Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

StopLoss ignored

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

    #16
    Hello tgn55,

    May I have you take the same steps as cls71 and point out the bar where the order is ignored and show the order is above or below the close of the submission bar.

    I would prefer this in a saved output file from prints and TraceOrders so I can report, otherwise I will have to design my own script to test.
    https://ninjatrader.com/support/foru...121#post791121

    An order will be ignored if the current close is on the other side of the order as it is submitted. So we will need what cls71 showed, in that the order was below the close for a sell or above the close for a buy.

    I need the close of the bar, if the order is a buy or sell, and the price the set method is submitted to.
    Last edited by NinjaTrader_ChelseaB; 06-17-2020, 02:28 PM.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #17
      Chelsea... I have a result. You can test it with the attached script... but note, it is critical that this be run on THE SAME CHART as I have set up... as it kicks in based on a specific CurrentBar number.

      So.. the setup is:
      1. NQ 09-20 5 minute chart
      2. Custom Start date: 6/11/2020 ( I hope our TZ difference does not screw this up .. it is critical ;-) What matters is getting the bar on 6/10, 20 minutes after the NYSE opens... ie at 9:50 EST, being bar number 189. Vital to have this.. or my script will probably be useless!
      3. End date... not important, a day or 2 should be fine... only interested in what happens in the first day...
      I have tweaked cls71's fine script... and added in stuff that can replicate my strategy... and its all selectable as parameters, so I can create the issue or not at will...

      Turns out, the issue of ignored stoploss values... EXCEPT if they are like 50 ticks below entry, is dependent on... use of OCO to create a bracket entry !!
      I have made cls71's verbose printouts optional... as you can see the behaviour without them... But, if you want to see every instance of OnOrderUpdate... go ahead ;-)
      [Suggestion: set output window to a fixed-width font... Courier New... I made the output easy to read if you do...]

      First, explanation of my parameters.. and strategy
      OCO_Entry_Bracket... pretty obvious. If OFF, I just create a Long entry. If ON, I create a bracketed pair on bar 189. Which will trigger Long on bar 190.
      StaggeredStops:..... If OFF, all stops get set at the same price level... 10 ticks below the entry
      .................................if ON, I set stops staggered at 10 tick intervals... the same as my profit targets
      Profit targets and stops are OCO-linked, but...
      I DO NOT create a Profit target on the 5th position... it is meant to be a runner, ie, with a stoploss... but no target. (Of course , in my real strategy, I manage this with an ATM-style trailing stop)

      OK... sorry for the novel, but it's probably best you understand what I'm doing...

      Try running this with these combinations:
      OCO_Entry_Bracket StaggeredStops Looks Like Result
      OFF OFF 4 x targets, 5 identical stops Works as expected
      OFF ON 4 x targets, 5 progressively lower stops Works as expected
      ON OFF 4 x targets, 5 identical stops Breaks, NO stops created as the first instance invokes the error
      ON ON 4 x targets, 5 progressively lower stops Sort of works... first 3 stops ignored, the 4th stop (40 ticks) was NOT ignored, nor the 5th


      So.. there you have it. My strategy, putting all stops at the same level (10 ticks below entry) broke... leaving the 5th position to run wild.
      I trust this can be recorded as a bug...

      I hope this helps others who might hit the same weird issue...

      Update: I have included screenshots of my chart for all four combinations... Its On-Off that is the important one...

      Final note: WHY THIS MATTERS!!!
      The above behaviour renders my strategy un-backtestable/optimizable, as the rogue unprotected position runs to end of session... creating unrealistic huge profits or losses...
      So... even if the platform behaves in realtime, this nonsense of ignoring (some) stops on historical bars is just... dumb.
      I can maybe see why it might be implemented on live trades... but surely it should NOT trigger on a strategy in State.Historical

      Regards,
      T.
      Attached Files
      Last edited by tgn55; 06-18-2020, 12:15 PM. Reason: Correction

      Comment


        #18
        One further observation... from studying the full debug printout... it seems to me that I cannot even catch this ignored order, and do something (like submit a revised order at a different price)... as it never appears in OnOrderUpdate etc... Seems it is just silently killed off behind the users back... with no hope of strategy code handling the error.

        Did I miss something? Because if I am right... then the ONLY remedy seems to be Ninja fix this... I don't think I can add in something to trap it.
        If there is a way to trap it... please advise.

        Chelsea ??

        Update: I edited the previous post... realised that the 4th stoploss (at 40 ticks) was in fact accepted, so the comment Chelsea made that the order is ignored IF it is above the close of the bar is evidently verified. The question is... Why ??

        This issue arose (for me) testing a breakout strategy... which, in the case in point, worked nicely, my entry and stoploss placements all seem entirely legitimate. In a live trade situation, the policy makes no sense... since we don't know what the close of the bar will be when the orders are submitted.

        In a backtest... what possible purpose does this serve? It renders the strategy un-testable. Bad. Very bad. Can anybody enlighten me as to the advantage of this policy? I fail to see any...

        Well... until I went to bed (at 4:30 AM) and had a think about it ;-( So... I guess the intent is to avoid placing a stoploss at a level that would either a) have already triggered, or b) being above the market would be invalid... In the first case, it really depends in what happened intrabar.. which I guess the NT backtest engine doesn't know or use. Fair enough. In my breakout case, this is exactly what happened. Most of the action takes place within the one bar. ..I can only plead brain fade at crazy O'clock in the morning!

        So...the remaining mystery is... Why does the entry being an OCO pair impact this????

        Regards
        Last edited by tgn55; 06-18-2020, 01:35 PM.

        Comment


          #19
          Hello tgn55,

          Chelsea is currently out of the office.

          Time zone will be critical here since the bars on the chart would be based on the time zone configured in the platform and where the bars start on the chart. Checking for a certain day, and then checking for specific prices can help to reproduce on multiple PC's using different time zones.

          I responded to a related ticket recently and provided instruction for what debugging steps that need to be taken to see why the order is ignored. I also gave some detail on how Standard fill resolution will encounter these errors more frequently (there is no intra movement when backtesting.) Could you have a look at this post and let us know if the steps and information here resolve the matter? If it does not, could you update the test script so it identifies a specific date and looks for certain prices?

          I am coding a strategy and am receiving numerous instances of the following error message: A Buy order placed at '[time]' has been ignored since the stop price is less than or equal to the close price of the current bar. I have searched the NinjaTrader forums and have read many posts related to this error message, but none


          I look forward to assisting.

          Comment


            #20
            Originally posted by tgn55 View Post
            One further observation... from studying the full debug printout... it seems to me that I cannot even catch this ignored order, and do something (like submit a revised order at a different price)... as it never appears in OnOrderUpdate etc... Seems it is just silently killed off behind the users back... with no hope of strategy code handling the error.

            Did I miss something? Because if I am right... then the ONLY remedy seems to be Ninja fix this... I don't think I can add in something to trap it.
            If there is a way to trap it... please advise.

            Chelsea ??

            Update: I edited the previous post... realised that the 4th stoploss (at 40 ticks) was in fact accepted, so the comment Chelsea made that the order is ignored IF it is above the close of the bar is evidently verified. The question is... Why ??

            This issue arose (for me) testing a breakout strategy... which, in the case in point, worked nicely, my entry and stoploss placements all seem entirely legitimate. In a live trade situation, the policy makes no sense... since we don't know what the close of the bar will be when the orders are submitted.

            In a backtest... what possible purpose does this serve? It renders the strategy un-testable. Bad. Very bad. Can anybody enlighten me as to the advantage of this policy? I fail to see any...

            Well... until I went to bed (at 4:30 AM) and had a think about it ;-( So... I guess the intent is to avoid placing a stoploss at a level that would either a) have already triggered, or b) being above the market would be invalid... In the first case, it really depends in what happened intrabar.. which I guess the NT backtest engine doesn't know or use. Fair enough. In my breakout case, this is exactly what happened. Most of the action takes place within the one bar. ..I can only plead brain fade at crazy O'clock in the morning!

            So...the remaining mystery is... Why does the entry being an OCO pair impact this????

            Regards
            OCO making a difference sounds strange. Let me ask what may be a silly question. Are you saying that, on a single all-in/all-out order, if you placed the exact same stop loss order only, with no target order, you do not get the error?

            Comment


              #21
              Koganam: No... if you look at the attached test script it will I hope be clear... but here's the quick summary: (The script is there under the four screenshot pics above..maybe a bit hidden...)
              when I enter the position, I ALWAYS submit the same profit target and stop loss positions. The ONLY difference is... how I enter: this is the essence of OnBarUpdate :
              Code:
              SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, 5, 0, 10031.25, OCO_string, "Entry x 5");
              if (OCO_Entry_Bracket)
                 SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.StopMarket, 5, 0, 10013.0, OCO_string, "Entry x 5");
              This to go long at the high of the opening range, or... if OCO-bracketed, also to also place a sell at the low.

              I have played with High Precision fill flag as Jim suggests... but this behaviour is, well..."interesting".
              Clearly what triggers this whole thing is a lot of stuff happens intrabar.. I get it. And ultimately I might just need to go to tick data series... I was trying to avoid that. [Edit: just confirmed using tick fill resolution did indeed create the stop-loss order...]

              Jim: the test script was thrown together in a hurry, leveraging a script provided by the OP....I thought I provided sufficient detail in the earlier post to ensure you could make it trigger on the "correct" bar... 20 minutes after the open, It is messy to code for the time... given our different timezones... it should be trivial to tweak the CurrentBar number in OBU to make it line up, if required (but I don;t think it will be...). In any case... AFAIK, if you run on a chart (or in Strategy Analyser) if you get the same start date June 11)... the first bar will be beginning of the session.. regardless of timezone. That will only impact the time of day displayed on each bar... right? In my timezone, the opening bell happens at 11:00 PM... but it should be bar 185 for us both)

              Anyway... two issues still seem to require addressing:
              1. why the OCO thing should make a difference in behaviour, and
              2. the fact(?) that it seem to be impossible to write a handler for this error
              Hopefully this marked-up pic makes it even clearer...
              Click image for larger version  Name:	StopLoss markup.png Views:	0 Size:	50.3 KB ID:	1105897

              OK... given the above edit, noting that the issue kinda goes away if I use tick-based fills... I guess that will be the answer...
              I still think it worth noting the weird dependence on OCO entries... right?
              Attached Files
              Last edited by tgn55; 06-20-2020, 12:40 AM.

              Comment


                #22
                Originally posted by tgn55 View Post
                Koganam: No... if you look at the attached test script it will I hope be clear... but here's the quick summary: (The script is there under the four screenshot pics above..maybe a bit hidden...)
                when I enter the position, I ALWAYS submit the same profit target and stop loss positions. The ONLY difference is... how I enter: this is the essence of OnBarUpdate :
                Code:
                SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, 5, 0, 10031.25, OCO_string, "Entry x 5");
                if (OCO_Entry_Bracket)
                SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.StopMarket, 5, 0, 10013.0, OCO_string, "Entry x 5");
                This to go long at the high of the opening range, or... if OCO-bracketed, also to also place a sell at the low.
                Actually, I was asking what happens if there is no OCO at all; just the stop loss only with no target.

                Anyway... two issues still seem to require addressing:[LIST=1][*]why the OCO thing should make a difference in behaviour, and[*]the fact(?) that it seem to be impossible to write a handler for this error

                OK... given the above edit, noting that the issue kinda goes away if I use tick-based fills... I guess that will be the answer...
                I still think it worth noting the weird dependence on OCO entries... right?
                Tick Resolution may be the answer in this case, but in terms of actual error handling, you would be better of always knowing if your order is rejected, so that you can take necessary action. Regardless what happens in OnExecutionUpdate(), one should always use OnOrderUpdate() to check the order to make sure whether or not it is in OrderState.Rejected, then act as necessary. It is not a trapping mechanism: it is a necessary part of full and proper order-handling.

                Comment


                  #23
                  I use two different OCOs...the first, which i can turn on/off via a parameter, (really, just for the purpose of demo to CHelsea the error ;-) is for the entries. If OFF... I do NOT use OCO to bracket the entry.

                  Once I enter, I use OCO to pair up profit targets with stop losses, pretty standard arrangement.

                  As for error handling...I think you miss the point. When I have OCO bracket entries... the error occurs... but there is NOTHING recorded as an event in OnOrderUpdate (or anywhere else)... hence... my comment that it cannot be trapped. It simply does not invoke OnOrderUpdate...at all. If you run the script with Debug Trace turned on... you will see it all.

                  Why it happens with an OCO short entry ... which gets cancelled... but NOT if there is only a buy stop... that's the mystery!

                  All said... I have been able to backtest the strategy now buy specifying High Order Fill resolution...using 1 tick. Heaps slower backtest... but at least it does not generate the errors.

                  Comment


                    #24
                    I haven't read all the information here but in my managed approach I'm using this code in order to detect rogue orders without stop loss/or profit taker limit order.

                    Code:
                        public abstract class AbstractStrategy : Strategy {
                            protected class StrategyPositionStatus {
                                public StrategyPositionStatus() {
                                    IsLong = false;
                                    IsShort = false;
                                    HasStop = false;
                                    HasTarget = false;
                                }
                                public bool HasPosition {get {return IsLong || IsShort;}}
                                public bool IsLong {get; set;}
                                public bool IsShort {get; set;}
                                public bool HasStop {get; set;}
                                public bool HasTarget {get; set;}
                                public bool HasBracket {get{return HasStop && HasTarget;}}
                                public string EntrySignalName {get; set;}
                            }
                    
                            protected StrategyPositionStatus positionStatus = new StrategyPositionStatus();
                    Code:
                            protected void CheckPositionStatus() {
                                if(positionStatus.HasPosition && !positionStatus.HasBracket) {
                                    if(positionStatus.IsLong) {
                                        this.ExitLong(priceSeriesIndex, 1, "emergency exit", positionStatus.EntrySignalName);
                                    } else {
                                        this.ExitShort(priceSeriesIndex, 1, "emergency exit", positionStatus.EntrySignalName);
                                    }
                                    Print("exited position " + Time[0]);
                                }
                            }
                    
                            protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity
                                , int filled, double avgFillPrc, OrderState state, DateTime time, ErrorCode errorCode, string commment) {
                                if(order.OrderType == OrderType.Limit) {
                                    if(state == OrderState.Cancelled || state == OrderState.Filled) {
                                        positionStatus.HasTarget = false;
                                    } else if(state == OrderState.Accepted) {
                                        positionStatus.HasTarget = true;
                                    }
                                } else if(order.OrderType == OrderType.StopMarket) {
                                    if(state == OrderState.Cancelled || state == OrderState.Filled) {
                                        positionStatus.HasStop = false;
                                    } else if(state == OrderState.Accepted) {
                                        positionStatus.HasStop = true;
                                    }
                                }
                            }
                    
                            protected override void OnExecutionUpdate(Execution execution, string executionId, double price
                                    , int quantity, MarketPosition marketPosition, string orderId, DateTime time) {
                                if(execution.IsEntryStrategy) {
                                    positionStatus.IsLong = marketPosition == MarketPosition.Long;
                                    positionStatus.IsShort = marketPosition == MarketPosition.Short;
                                } else if(execution.IsExitStrategy) {
                                    positionStatus.IsLong = false;
                                    positionStatus.IsShort = false;
                                }            
                            }
                    Before EnterLong/EnterShort etc.

                    Code:
                                    positionStatus.EntrySignalName = signalName;
                    Maybe something similar can be done in an unmanaged approach.
                    Of course I'm not taking any responsibility and I'm not liable for actions/results caused by my code if someone is foolish enough to copy it .

                    Comment


                      #25
                      Originally posted by tgn55 View Post
                      I use two different OCOs...the first, which i can turn on/off via a parameter, (really, just for the purpose of demo to CHelsea the error ;-) is for the entries. If OFF... I do NOT use OCO to bracket the entry.

                      Once I enter, I use OCO to pair up profit targets with stop losses, pretty standard arrangement.

                      As for error handling...I think you miss the point. When I have OCO bracket entries... the error occurs... but there is NOTHING recorded as an event in OnOrderUpdate (or anywhere else)... hence... my comment that it cannot be trapped. It simply does not invoke OnOrderUpdate...at all. If you run the script with Debug Trace turned on... you will see it all.

                      Why it happens with an OCO short entry ... which gets cancelled... but NOT if there is only a buy stop... that's the mystery!

                      All said... I have been able to backtest the strategy now buy specifying High Order Fill resolution...using 1 tick. Heaps slower backtest... but at least it does not generate the errors.
                      The key takeaway then is that it only happens in the presence of OCO. Got that.

                      However, you might look again. I have always been able to trap rejected orders simply by grabbing the information from OnOrderUpdate().

                      The other option of course, is to iterate though all the orders, and see if your stop order exists.
                      Last edited by koganam; 06-20-2020, 06:02 PM.

                      Comment


                        #26
                        Koganam... no point in looking again... I have looked, many times.

                        I have put a screenshot of the debug output here (in its raw format, it is pretty ugly.... I just used the OP's format... including Spanish (?) comments... sorry))
                        The test script prints EVERY entry to OnOrderUpdate, OnExecutionUpdate, OnPositionUpdate etc... you can see a bunch of such prints...

                        The ignored order simply IS NOT there! (I mean... the error message is printed out, but... NO corresponding OnOrderUpdate print.) If you would run the script, you would see.
                        It is evidently reported via Ninja's internal process... but NEVER sees the light of day as an actual order

                        MojoJojo: thanks, but this doesn't really address the point I am making... if the ignored order NEVER invokes one of the above methods... you are NEVER going to be able to respond to it from within those methods! Surely this is obvious......
                        Attached Files
                        Last edited by tgn55; 06-21-2020, 12:13 AM.

                        Comment


                          #27
                          Originally posted by tgn55 View Post
                          Koganam... no point in looking again... I have looked, many times.

                          [B]if the ignored order NEVER invokes one of the above methods... you are NEVER going to be able to respond to it from within those methods! Surely this is obvious......
                          Right, it's so obvious that my code is built around it. I'm checking on the next bar, for the impatient start a timer on entry and check after a few seconds during live trading, for backtesting I don't believe it's possible to find out earlier.
                          Last edited by MojoJojo; 06-21-2020, 01:42 AM.

                          Comment


                            #28
                            Ah, OK... next bar...Makes sense now... thanks for that. Nice...

                            For backtesting, next bar would be OK... what makes the original strategy useless for backtesting is having these rogue trades run through until end of session. If I could detect/manage them next bar... that would not happen. The P/L results would only be slightly skewed, except in cases where there is a significant move within the bar (which is exactly what happens in my test case)

                            So... seems the options are
                            a) do the tick-based fill resolution thing... ultimate accuracy, but at the expense of MUCH slower backtesting, or
                            b) implement your "check on next (each?) bar... small risk of incorrect P/L... but should backtest heaps faster....

                            That said... I still think there is a latent issue. You code still depends on setting your class member state in the On* methods... right? So... if a an order was actually placed... great. But if it is never placed... but *should* have been... don't we still have a problem? So maybe an additional layer of logic is needed to check that? Or am I missing something?

                            Thanks!

                            Comment


                              #29
                              That's a good summary, I prefer to choose faster backtesting with small errors, usually only one or two failed trades occurs for me during an iteration.

                              I'm having the same problem that either the stop loss or limit order is missing of the bracket I'm placing. Maybe it could be completely avoided by some checks before entry but apart from targets/stop losses below 0, I haven't been able to come up with anything better,

                              The strategy will invoke the OnOrderUpdate for the bracket orders and if it does not it will be noticed on the next bar. HasBracket return false with HasPosition true in such cases. The status is checked on every bar, it's inexpensive.

                              So far every time during my testing when NT fires an error message also the exit position by the code occurs.

                              But some modifications might be necessary for your trade management.

                              Edit:
                              Something to explore: maybe for backtesting checking target/stop prices against bid/ask of the next bar before entry could help.
                              BarsArray[x].GetAsk(CurrentBar + 1)
                              Last edited by MojoJojo; 06-21-2020, 04:04 AM.

                              Comment


                                #30
                                Well, clearly what is really desired is some code that works for live/realtime trades as well as backtesting. Anyway, thanks for your input. I got pulled away this evening on another matter.. I'll experiment with your approach when I get some time next week...

                                Cheers,

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by NullPointStrategies, Yesterday, 05:17 AM
                                0 responses
                                54 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
                                72 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
                                49 views
                                0 likes
                                Last Post TheRealMorford  
                                Working...
                                X