Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Catching errors closing position, continuing to run strat

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

    Catching errors closing position, continuing to run strat


    Hi folks,

    While I was running my strategy today on my sim account to test it I got these errors a few times. I'm using OnEachTick and pasted my entry and sl/tp code below. From reading the error message and previous posts on this forum I understand that the price has moved in the time it takes for the stop loss or tp to get submitted, and that it's no longer valid given current price. My question is how should I go about catching this, closing the open position (if this happens then I'd want to exit to be on the safe side), and then continuing to run the strategy? Do you by chance have any example/sample code that does the above that I can reference? Thank you!

    Click image for larger version

Name:	image.png
Views:	95
Size:	23.4 KB
ID:	1317044


    //Buy
    if (buySignalPrice > 0 && Close[0] > buySignalPrice && Position.MarketPosition == MarketPosition.Flat && orderBar != CurrentBar)
    {
    EnterLong(Convert.ToInt32(DefaultQuantity), @"Long");

    SetStopLoss(CalculationMode.Price, buySignalPrice);

    //calculate stop loss diff between st and close
    double risked = Close[0] - buySignalPrice;
    double target = (Close[0] + risked) * ProfitTargetRatio;

    SetProfitTarget(CalculationMode.Price, target);

    Print(string.Format( "{0} | Buy signal: {1} Close: {2} Open: {3}, Target: {4}", Time[0], buySignalPrice, Close[0], Open[0], target));

    orderBar = CurrentBar;
    }

    //Sell
    if (sellSignalPrice > 0 && Close[0] < sellSignalPrice && Position.MarketPosition == MarketPosition.Flat && orderBar != CurrentBar)
    {
    EnterShort(Convert.ToInt32(DefaultQuantity), @"Short");

    SetStopLoss(CalculationMode.Price, sellSignalPrice);
    //calculate stop loss diff between st and close
    double risked = sellSignalPrice - Close[0];
    double target = (Close[0] - risked) * ProfitTargetRatio;


    SetProfitTarget(CalculationMode.Price, target);

    Print(string.Format( "{0} | Buy signal: {1} Close: {2} Open: {3}, Target: {4}", Time[0], sellSignalPrice, Close[0], Open[0], target));

    orderBar = CurrentBar;

    }​


    #2
    Hello shorty,

    That type of error can happen if one of the targets is rejected for any reason, the OCO message is just a side effect of the order being rejected. If one part of an OCO pair is rejected the second order to submit will get an OCO error because the first order using that oco was rejected. The main problem here as that the price being used was too close to the market and ended up being submitted on the wrong side of the market. In fast moving markets this is common when using an offset that is too close to the market.

    The easiest way to avoid this is to not update the stop as frequently, for example add an amount of profit required before submitting changes to the order. If you are submitting the order on each tick you are very likely going to hit this type of rejection frequently if the target is at all close to the current market.

    You can also ignore rejections but that opens the script up to having problems with any error at all. If any rejection occurs the script will keep running and if you had not previously planned for that rejection and added logic to handle it the strategy could start trading incorrectly.




    Comment


      #3
      Thank you Jesse! Although I will also mention that I don't update my stop or tp, I'm submitting them in the same code block as the entry, and they stay fixed, but I suppose it moved so fast that in those milliseconds between lines the order was invalid? I will go ahead and experiment with adding a few ticks buffer, thanks!

      Comment


        #4
        Hello shorty,

        If you are not updating them later that may be due to the targets using an old price. You need to price the targets before submitting the entry so your code should look like this:



        Code:
        SetStopLoss(CalculationMode.Price, buySignalPrice);
        SetProfitTarget(CalculationMode.Price, target);
        EnterLong(Convert.ToInt32(DefaultQuantity), @"Long");
        If you call them after the entry while using Price mode that could end up using the last price that was set. ​

        Comment


          #5
          Fantastic - thank you!

          Comment


            #6
            Hi Jesse! Sry about this but I wanted to circle back and check something with you, since I got another error last night: "buy order stop price must be above trade price"

            I had thought that my updated logic would prevent that...here's what I'm doing, in plain English, as well as the code.
            • Checking the trade signal, time of day, PnL etc. before entering
            • Calculating initial risk and adding additional ticks to the PT --> for NQ the strategy is set to 8 additional ticks currently
            • If initial risk is lower than the max SL, if not, use the max SL
            • Set SL and PT using CalculationMode.Ticks
            • Enter trade
            Do you spot anything that needs to be updated to prevent the error? Instead, Should I instead monitor the trade's drawdown in ticks in real time and use ExitLong(); or ExitShort() to avoid this?

            Code:
             //Buy
                        if (buySignalPrice > 0
                            && Close[0] > buySignalPrice
                            && Position.MarketPosition == MarketPosition.Flat
                            && orderBar != CurrentBar
                            && currentDaysPnL >= -DailyLossLimit
                            && (Times[0][0].TimeOfDay > StrategyStartTime.TimeOfDay)
                            && (Times[0][0].TimeOfDay < StrategyEndTime.TimeOfDay))
                        {          
                          
                            //Points risked
                            double pointsRisked = Close[0] - buySignalPrice;
                          
                            //Convert points to ticks
                            double ticksRisked = pointsRisked / TickSize;
                            //Add any additional target
                            double updatedRisk = ticksRisked + AdditionalTickTarget;
                            Print(string.Format( "{0} | Buy signal price: {1}, Current Price: {2}, Initial Risk in Points: {3}, Initial Risk in Ticks: {4}", Time[0], buySignalPrice, Close[0], pointsRisked, ticksRisked));
                            Print(string.Format( "{0} | Additional Tick Target from User: {1}, New Risk in Ticks: {2}", Time[0], AdditionalTickTarget, updatedRisk));
                      
                            double stopLossValue = ticksRisked > MaxTickStopLoss ? MaxTickStopLoss : ticksRisked;
                            Print(string.Format( "{0} | Initial Stop in Ticks: {1}, Max from User: {2}, Updated Stop in Ticks: {3}", Time[0], ticksRisked, MaxTickStopLoss, stopLossValue));
                          
                            SetStopLoss(CalculationMode.Ticks, stopLossValue);
                            SetProfitTarget(CalculationMode.Ticks, updatedRisk);
                          
                            EnterLong(Convert.ToInt32(DefaultQuantity), @"Long");
                          
                            Print(string.Format( "{0} | Buy signal: {1} Entry: {2}, Target: {3}, Stop Loss: {4}", Time[0], buySignalPrice, Close[0], updatedRisk, stopLossValue));
                            Print(string.Format( "{0} | Days PnL: {1}", Time[0], currentDaysPnL));
                            orderBar = CurrentBar;
                        }
                      
                         //Sell
                        if (sellSignalPrice > 0
                            && Close[0] < sellSignalPrice
                            && Position.MarketPosition == MarketPosition.Flat
                            && orderBar != CurrentBar
                            && currentDaysPnL >= -DailyLossLimit
                            && (Times[0][0].TimeOfDay > StrategyStartTime.TimeOfDay)
                            && (Times[0][0].TimeOfDay < StrategyEndTime.TimeOfDay))
                        {
                          
                            //Get how many points are risked
                            double pointsRisked = sellSignalPrice - Close[0];
                            //Convert points to ticks
                            double ticksRisked = pointsRisked / TickSize;
                            //Add any additional target
                            double updatedRisk = ticksRisked + AdditionalTickTarget;
                            Print(string.Format( "{0} | Sell Signal: {1}, Current Price: {2}, Initial Risk in Points: {3}, Initial Risk in Ticks: {4}", Time[0], sellSignalPrice, Close[0], pointsRisked, ticksRisked));
                            Print(string.Format( "{0} | Additional Tick Target from User: {1}, New Risk in Ticks: {2}", Time[0], AdditionalTickTarget, updatedRisk));
            
                            double stopLossValue = ticksRisked > MaxTickStopLoss ? MaxTickStopLoss : ticksRisked;
                            Print(string.Format( "{0} | Initial Stop in Ticks: {1}, Max from User: {2}, Updated Stop in Ticks: {3}", Time[0], ticksRisked, MaxTickStopLoss, stopLossValue));
                          
                            SetStopLoss(CalculationMode.Ticks, stopLossValue);
                            SetProfitTarget(CalculationMode.Ticks, updatedRisk);
                          
                            EnterShort(Convert.ToInt32(DefaultQuantity), @"Short");
                          
                            Print(string.Format( "{0} | Sell signal: {1} Entry: {2}, Target: {3}, Stop Loss: {4}", Time[0], sellSignalPrice, Close[0], updatedRisk, stopLossValue));
                            Print(string.Format( "{0} | Days PnL: {1}", Time[0], currentDaysPnL));
                            orderBar = CurrentBar;
                        }          
                      
                        if (Position.MarketPosition != MarketPosition.Flat && ((Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0]) + currentDaysPnL) <= (-DailyLossLimit)))
                        {
                                Print(string.Format("{0} | Combined loss & unrealized loss: {1}",  Time[0].ToString(), (Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0]) + currentDaysPnL)));                  
                                Print(string.Format("{0} | Hit Daily Loss Limit of {1}, Realized PnL: {2} UnrealizedProfitLoss PnL: {3}",  Time[0].ToString(), DailyLossLimit, currentDaysPnL, Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0])));                  
                                if (Position.MarketPosition == MarketPosition.Long)
                                    ExitLong();
                                if (Position.MarketPosition == MarketPosition.Short)
                                    ExitShort();            
                        }​

            Comment


              #7
              Hi, after looking in more detail at the trades, it does look like it was the last code block that triggered the order, since the max daily loss limit was reached. Should I instead set a param to have those be submitted as market orders? Or what do you recommend?

              Comment


                #8
                Hello shorty,

                The error that you are seeing specifically relates to the stop price of the order so using market exit orders would also be a way to avoid that from happening. In regard to the last code block, that appears to already be using market exits. the ExitLong and ExitShort methods submit market orders. You would have to remove SetStopLoss to completely prevent that error from happening, the offset being used can also be increased to help avoid that however that will depend on the market being traded.

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by NullPointStrategies, Yesterday, 05:17 AM
                0 responses
                72 views
                0 likes
                Last Post NullPointStrategies  
                Started by argusthome, 03-08-2026, 10:06 AM
                0 responses
                143 views
                0 likes
                Last Post argusthome  
                Started by NabilKhattabi, 03-06-2026, 11:18 AM
                0 responses
                76 views
                0 likes
                Last Post NabilKhattabi  
                Started by Deep42, 03-06-2026, 12:28 AM
                0 responses
                47 views
                0 likes
                Last Post Deep42
                by Deep42
                 
                Started by TheRealMorford, 03-05-2026, 06:15 PM
                0 responses
                51 views
                0 likes
                Last Post TheRealMorford  
                Working...
                X