Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Backtest entry ignores conditions, enters out of range

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Backtest entry ignores conditions, enters out of range

    Hey guys, I'm really confused by this one and hoping someone can help me out! I've got two problems: A line of code is not executing the way I expect it to, and an entry is being made outside of the range of the candle it's supposedly being made on in backtesting.

    Here's the problematic line of code: isBreakingHigh = (High[1] >= MAX(High, 55)[0]);
    I expect this condition to mean that a trade will only be placed if the high of the penultimate bar is the biggest bar of the last 55 candles. As you can see from the first attached screenshot, this is clearly not the case. ​I chose 55 because the trade does not enter at 56 for some reason.

    In addition, I included different print statements that should trigger based on whether or not the entry conditions were triggered. As you can see in the second screenshot, the print statement associated with entry conditions being met was not printed.

    I also noticed that the entry was not made on the candle or wick (see third screenshot. Is this due to the slippage of 1 that I added?




    Here's the relevant portion of code:


    for (int i = table.Rows.Count - 1; i >= 0; i--)
    {
    Print($"Checking row {i}: Supply/Demand = {table.Rows[i]["Supply/Demand"]}, RangeHigh = {table.Rows[i]["RangeHigh"]}, RangeLow = {table.Rows[i]["RangeLow"]}, timeAdded = {table.Rows[i]["timeAdded"]}, barIndex = {table.Rows[i]["barIndex"]}, Current Time = {Time[0]}");


    region Short Trades
    bool isSupply = table.Rows[i]["Supply/Demand"] == "Supply";
    bool isAboveRangeLow = (High[0] > Convert.ToDouble(table.Rows[i]["rangeLow"]) || High[1] > Convert.ToDouble(table.Rows[i]["rangeLow"]));
    bool isCloseValid = Close[0] < Low[1];
    bool isBreakingHigh = (High[1] >= MAX(High, 55)[0]);


    if (isSupply && isAboveRangeLow && isCloseValid && isBreakingHigh)
    {

    Print("All conditions met, trade should enter here");

    double stopLossPriceShort = MAX(High, 5)[0] + ATR(14)[0] + StopLossMultiplier * (Math.Abs(Close[0] - MAX(High, 5)[0]));
    double riskAmountShort = Math.Abs(Close[0] - stopLossPriceShort);
    double takeProfitAmountShort = TakeProfitMultiplier * riskAmountShort;
    double takeProfitPriceShort = Close[0] - takeProfitAmountShort;

    Print("stopLossPriceShort = " + stopLossPriceShort);
    Print("Math.Abs(Close[0] - MAX(High, 5)[0] = " + Math.Abs(Close[0] - MAX(High, 5)[0]));
    Print("Close[0] = " + Close[0]);
    Print("MAX(High, 55)[0] = " + MAX(High, 55)[0]);
    Print("Low[1] = " + Low[1]);
    Print("High[1] = " + High[1]);
    Print("riskAmountShort = " + riskAmountShort);


    //Set SL and TP
    SetStopLoss(CalculationMode.Price, stopLossPriceShort);
    SetProfitTarget(CalculationMode.Price, takeProfitPriceShort);

    //Want to risk 200 / trade
    int entryAmountShort = Convert.ToInt32(Math.Round((200/2)/riskAmountShort));

    //Enter Trade
    EnterShort(entryAmountShort, "FVG Short " + entryAmountShort);
    Print("TradeEntered");


    }
    else
    {
    Print("Not all conditions met, trade should not enter");
    }​
    Attached Files

    #2
    Hello Ferdinand_the_Cyber_Duck,

    Be sure to implement 1-tick intra-bar granularity for accurate order fills in backtest.


    Also, keep in mind if the order is being submitted after the bar closes, it will fill on a bar after the condition bar.

    The screenshot of the output isn't showing any orders have been submitted at all.

    In the output, be sure you have enabled TraceOrders and print the order.ToString() in OnOrderUpdate() so that we can see what orders are being submitted, ignored, rejected, cancelled or filled when the condition is true.
    With the output for the condition, this should have the time of the bar, all values used in the condition, with labels for all values and comparison operators so we can see how the values are being compared. The print for the condition should appear just like the condition but with labels added for each value.

    Below is a link to a support article on adding informative debugging prints.


    To save the output from the output window, right-click the output window and select Save as, then you can attach the text file to your post.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Thanks for the quick response!!

      I enabled TraceOrders. It's showing an ignored entry at 7:40, but nothing at 7:45. I tried to attach the output, but I got this error: "Error: PHP Max Post Size has been exceeded.​"

      This is what it says at 7:40:

      8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Entered internal SetStopTarget() method: Type=Stop FromEntrySignal='' Mode=Price Value=18999.6176405609 IsSimulatedStop=False IsMarketIfTouched=False
      8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Entered internal SetStopTarget() method: Type=Target FromEntrySignal='' Mode=Price Value=18069.8823594391 IsSimulatedStop=False IsMarketIfTouched=False
      8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Entered internal SubmitOrderManaged() method at 8/2/2024 7:40:00 AM: BarsInProgress=1 Action=SellShort OrderType=Market Quantity=1 LimitPrice=0 StopPrice=0 SignalName='FVG Short 0' FromEntrySignal=''
      8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Ignored SubmitOrderManaged() method at 8/2/2024 7:40:00 AM: BarsInProgress=1 Action=SellShort OrderType=Market Quantity=1 LimitPrice=0 StopPrice=0 SignalName='FVG Short 0' FromEntrySignal='' Reason='Order already has this stop price/limit price/quantity'
      TradeEntered​

      Comment


        #4
        Hello Ferdinand_the_Cyber_Duck,

        So at 7:45 AM on August 2nd you are expecting an order and no order was submitted, this would imply the condition did not evaluate as true.
        The 'All conditions met, trade should enter here' output did not appear, correct?

        One line above the condition that submits the order, print the time of the bar and all values in the condition. Include labels for each value and comparison operator to show how the values are being compared.

        Re-run and provide the new output. If the output file is large, please use a webtransfer service such as wetransfer.com and provide a link in your post.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          I would like to not enter the trade at 07:45; the condition should not evaluate as true. The "All conditions met, trade should enter here" output did not print, neither did the TraceOrder show an entry. However, the trade is showing up in the StrategyAnalyzer.

          Here's a link to the output: https://we.tl/t-55OGs4uY8u

          Comment


            #6
            Hello ,

            8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Entered internal SubmitOrderManaged() method at 8/2/2024 7:40:00 AM: BarsInProgress=1 Action=SellShort OrderType=Market Quantity=1 LimitPrice=0 StopPrice=0 SignalName='FVG Short 0' FromEntrySignal=''

            The 'FVG Short 0 ' should not have been submitted on the 7:40 bar is this correct? (You are not looking for an order that should have been submitted at 7:45? What are you expecting at 7:45?)

            If so the order method got called.

            From the output in the file I see:

            Time = 8/2/2024 7:40:00 AM
            isSupply = True
            isAboveRangeLow = True
            isCloseValid = True
            isBreakingHigh = True
            High[1] = 18748
            MAX(High, 55)[0] = 18748
            All conditions met, trade should enter here
            8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Entered internal SetStopTarget() method: Type=Stop FromEntrySignal='' Mode=Price Value=18999.6176405609 IsSimulatedStop=False IsMarketIfTouched=False
            8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Entered internal SetStopTarget() method: Type=Target FromEntrySignal='' Mode=Price Value=18069.8823594391 IsSimulatedStop=False IsMarketIfTouched=False
            8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Entered internal SubmitOrderManaged() method at 8/2/2024 7:40:00 AM: BarsInProgress=1 Action=SellShort OrderType=Market Quantity=1 LimitPrice=0 StopPrice=0 SignalName='FVG Short 0' FromEntrySignal=''
            8/2/2024 7:40:00 AM Strategy 'SupplyAndDemand/-1': Ignored SubmitOrderManaged() method at 8/2/2024 7:40:00 AM: BarsInProgress=1 Action=SellShort OrderType=Market Quantity=1 LimitPrice=0 StopPrice=0 SignalName='FVG Short 0' FromEntrySignal='' Reason='Order already has this stop price/limit price/quantity'

            It does appear on the 'All conditions met, trade should enter here' is in the output just above the order submission.
            This would imply the condition evaluated as true and called the order method.

            isSupply, isAboveRangeLow, isCloseValid, isBreakingHigh were all true. Which of the values are you expecting to be false at 7:40 and why?
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Okay, I've located the issue: High[1] in the following line is referring to the high of the 5m dataseries I added, not the 1m dataseries I'm running the analyzer on.

              bool isBreakingHigh = (High[1] >= MAX(High, 55)[0]);

              Although this satisfies my curiosity on how the condition could be satisfied as true, I'm still a little confused as to how this could be...I thought I would need to phrase it as Highs[1][1] for it to take the high of the penultimate bar according to the 1st added dataseries?

              Comment


                #8
                Hello Ferdinand_the_Cyber_Duck,

                That depends on the logic in OnBarUpdate().

                High refers to the bars object currently updating OnBarUpdate().

                Do you have a condition to require BarsInProgress to be 0?
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  I do not have such a condition. What does that do?

                  How do I set the bars object currently updating OnBarUpdate()? Isn't that by default set by the dataseries used in the strategy analyzer?

                  Comment


                    #10
                    Hello Ferdinand_the_Cyber_Duck,

                    All price series added with AddDataSeries() update OnBarUpdate() when they have a bar updating.

                    BarsInProgress is a property that specifies which series is the one updating.


                    You cannot set this, as all series will update OnBarUpdate(). You can only choose to perform logic when a specific series is updating OnBarUpdate().
                    Chelsea B.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by NullPointStrategies, Today, 05:17 AM
                    0 responses
                    52 views
                    0 likes
                    Last Post NullPointStrategies  
                    Started by argusthome, 03-08-2026, 10:06 AM
                    0 responses
                    130 views
                    0 likes
                    Last Post argusthome  
                    Started by NabilKhattabi, 03-06-2026, 11:18 AM
                    0 responses
                    70 views
                    0 likes
                    Last Post NabilKhattabi  
                    Started by Deep42, 03-06-2026, 12:28 AM
                    0 responses
                    44 views
                    0 likes
                    Last Post Deep42
                    by Deep42
                     
                    Started by TheRealMorford, 03-05-2026, 06:15 PM
                    0 responses
                    48 views
                    0 likes
                    Last Post TheRealMorford  
                    Working...
                    X