Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Managed Stop not updating

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

    #16
    I am using the Managed approach. When I added the 1 second Fill Resolution the "Time Traveling" stopped and it appears to work (still verifying):

    if (State == State.SetDefaults)
    {
    OrderFillResolution = OrderFillResolution.High;
    OrderFillResolutionType = BarsPeriodType.Second;
    OrderFillResolutionValue = 1;
    }

    Would there be any reason not to just keep the code I posted in Post # 14? To my unskilled eye.....it is waiting for a complete Fill....

    Otherwise in OnPositionUpdate() how would I identify the "last Stop fill"? Would this work to enter on the Same bar (Reverse on Stop)?

    protected override void OnPositionUpdate(Position position, double averagePrice, int quantity, Marke tPosition marketPosition)
    {
    if (position.MarketPosition == MarketPosition.Flat )
    {
    if ((BarsSinceExitExecution(ShortStops5) == 0))
    {
    EnterLong(QuantitySize, "Long7ReverseOnShortStop");
    }
    }
    }

    Comment


      #17
      Hello BigT4X,

      You can write your script how you would like. I've given you warning that the position object is what NinjaTrader is using to manage the position. If it hasn't updated yet, NinjaTrader may send Close position orders when your entry in the opposite direction is submitted causing the position to double as it reverses (or an overfill will happen). It takes time for the position to update after the order has updated. (Also, there is no guarantee of the sequence the order update, will be received. The position update will always be after the execution update.)

      See this forum thread that discusses what happens with different brokerages.


      The position will be flat when the exit orders have finished filling.
      if (marketPostion == MarketPosition.Flat)
      Last edited by NinjaTrader_ChelseaB; 08-04-2022, 11:05 AM.
      Chelsea B.NinjaTrader Customer Service

      Comment


        #18
        I added it and I think it works.....BUT unfortunately it causes my backtest to hang even with 'OrderFillResolution = OrderFillResolution.Standard;' and 'TraceOrders = false;'. This is probably because I am running 215 days of data on chart (back to January 1st, 2022) rather than say 1-2 months. I may go the other way (OnOrderUpdate with High Fill resolution) for now just to evaluate the trades for the last 7 months and refine the logic before adding it back.

        Please let me know if you see anything wrong in this below that would cause the backtest to hang? Note: I have Cbi on OnPositionUpdate but did not apply that to my OnOrderUpdate or OnExecutionUpdate code.

        protected override void OnPositionUpdate(Cbi.Position position, double averagePrice, int quantity, Cbi.MarketPosition marketPosition)
        {
        if (marketPosition == MarketPosition.Flat)
        {
        if ((BarsSinceExitExecution("LongStops1") == 0))
        {
        EnterShort(QuantitySize, "Short7ReverseOnLongStop");
        }
        if ((BarsSinceExitExecution("LongStops2") == 0))
        {
        EnterShort(QuantitySize, "Short7ReverseOnLongStop");
        }
        // repeats for some of the next 5

        if ((BarsSinceExitExecution("ShortStops1") == 0))
        {
        EnterLong(QuantitySize, "Long7ReverseOnShortStop");
        }
        if ((BarsSinceExitExecution("ShortStops2") == 0))
        {
        EnterLong(QuantitySize, "Long7ReverseOnShortStop");
        }
        // repeats for some of the next 5
        }
        Last edited by BigT4X; 08-04-2022, 01:34 PM.

        Comment


          #19
          Hello BigT4X,

          Add prints to understand behavior.

          Below is a link to a forum post that demonstrates using print to understand behavior.


          Is this code causing an endless loop where an order is submitted, the position updates, a new order is submitted, the position updates, a new order is submitted, forever?

          Can you reproduce the behavior on a single day range of data in the backtest?

          Please include output from prints saved to a text file. This may show us the position is forever being changed.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #20
            NinjaTrader_ChelseaB Me again (sorry!). Or Anyone else.....any help as always is very much appreciated.....

            I have everything working the way I want and now been working to try and resolve PositionUpdate to avoid Overtrading. BUT I am kind of stuck......so I thought I at least try to ask this. Below is my OnOrderUpdate code for LongStop1 only (the remaining Reverse on Stops code is similar so I am not displaying all the stops to reduce the post). Can I please have suggestions how to convert this to OnPositionUpdate?

            I know the Green text stays in OnOrderUpdate and the rest of the black text has to move to PositionUpdate in some sort of form. But the blue text below is not right in OnPositionUpdate - I get "order does not exist in current context" and "averageFillPrice does not exist in current context" errors in PositionUpdate.

            Here is the CODE Before my PositionUpdate change (note: there is correct close brackets but I may have missed one in copy and paste - so assume I have them)
            protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
            {
            //Assign Stop Orders
            if (order.Name == "LongStops1" && order != StopLongOrder1)
            {
            StopLongOrder1 = order;
            }


            //Reset Stop Orders on Fills and Cancels
            if (StopLongOrder1 != null && StopLongOrder1 == order)
            {
            Print(order.ToString());
            if (order.OrderState == OrderState.Filled)
            {
            StopLongOrder1 = null;
            if (!(ToTime(Time[0]) >= 160000 && ToTime(Time[0]) < 170000) && averageFillPrice < BigT_Auto_LinearRegressionBands1.UPLB[0] * 1.0012 && averageFillPrice <= Open[0])
            {
            EnterShort(QuantitySize, "Short7ReverseOnLongStop");
            }
            }

            if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
            {
            StopLongOrder1 = null;
            }
            }


            This code above works great if I ignore Overtrading possible issue. But to try and fix that.....

            My CODE Attempt for PositionUpdate - NOTE: I had tried before "if ((BarsSinceExitExecution("LongStops1") == 0))" but I believe that caused a loop and so I abandoned that. To even try that again...I need to get over the "averageFillPrice" error. Any way to get the Last Fill price to be found in PositionUpdate?

            protected override void OnPositionUpdate(Position position, double averagePrice, int quantity, MarketPosition marketPosition)
            {
            if (marketPosition == MarketPosition.Flat)
            {
            if (StopLongOrder1 != null && StopLongOrder1 == order) //
            Perhaps this should be "if ((BarsSinceExitExecution("LongStops1") == 0))" + some other criteria?? Any suggestions for this part?
            {
            Print(order.ToString());
            if (order.OrderState == OrderState.Filled)
            {
            StopLongOrder1 = null;
            if (!(ToTime(Time[0]) >= 160000 && ToTime(Time[0]) < 170000) && averageFillPrice < BigT_Auto_LinearRegressionBands1.UPLB[0] * 1.0012 && averageFillPrice <= Open[0])
            {
            EnterShort(QuantitySize, "Short7ReverseOnLongStop");
            }
            }
            }
            }
            }
            Last edited by BigT4X; 09-05-2022, 09:17 PM.

            Comment


              #21
              Hello BigT4X,

              With
              if (StopLongOrder1 != null && StopLongOrder1 == order)
              The first condition in the branching command is to see if StopLongOrder1 is null. If you want to use StopLongOrder1 for something, you would want to make sure it is not null, and check that the .OrderState is OrderState.Working or OrderState.Accepted.

              The second condition in the branching command is to see if StopLongOrder1 is equal to order.
              There is no variable named 'order' declared here.
              Possibly you are thinking you can use the order variable from OnOrderUpdate(), but that is not a parameter of OnPositionUpdate.


              The OnPositionUpdate method has a position variable with a Position object.



              order in OnOrderUpdate is a parameter that is defined in the method override signature.
              Code:
              protected override void OnOrderUpdate([B]Order order[/B],  double limitPrice, double stopPrice, int quantity , int filled, double averageFillPrice, OrderState  orderState, DateTime time, ErrorCode error, string  comment)
              {
              }
              
              protected override void OnPositionUpdate([B]Posit position[/B], double averagePrice, int quantity, Marke tPosition marketPosition)
              {
              
              }
              With
              Print(order.ToString());
              There is no order variable declared here. What are you trying to do with this print?
              Are you trying to check StopLongOrder1 for something?

              With
              if (order.OrderState == OrderState.Filled)
              Again there there is no variable order declared here.

              With
              Code:
              StopLongOrder1 = null;
              Why is this being set to null here?
              Chelsea B.NinjaTrader Customer Service

              Comment


                #22
                I thought I was clear on Post # 20 but I guess it was confusing. The Green/Black/Green code in Post # 20 is currently all in OnOrderUpdate. It works exactly as expected for the Strategy. Nothing wrong with it....EXCEPT.....

                All I am trying to do now is move/transfer the appropriate code from OnOrderUpdate to OnPositionUpdate as per your recommendation to avoid any Overtrading/double fills when I do a Reverse on Stop trade - really not trying to do anything more here. I believe the Green text stays in OnOrderUpdate and the revised black text moves to PositionUpdate with some changes as you mentioned. My blue text was my sad attempt at doing this in PositionUpdate - you could ignore the Blue text in the post completely.

                I will look at your notes/suggestions and try to adjust what I need to adjust in OnPositionUpdate. My guess is I need to make a variable to store the averageFillPrice value so that I can use it in PositionUpdate. And then I need to identify the order that just stopped out and filled in PositionUpdate and apply the opposite trade if the additional criteria applies. I cannot make my StopLongOrder1 = null until I know it is filled and I worry that if I update that in OrderUpdate....I have no way of identifying my order in PositionUpdate if all orders are now null before the new reverse trade is in.

                Thanks for your help

                Comment


                  #23
                  Hello BigT4X,

                  Code for working with order updates should be in OnOrderUpdate(). Code for working with the position should be in OnPositionUpdate().

                  If you want to reverse when the stop fills, you can check the marketPosition has become flat in OnPositionUpdate() and send a new order to reverse the position.

                  When using the managed approach, most developers will just call the entry in the opposite direction to reverse the position instead of using a stop if the intended outcome is to reverse the position. But you want to use the stop, you can, and wait until the position is flat and then send a new entry.

                  My guess is I need to make a variable to store the averageFillPrice value so that I can use it in PositionUpdate.
                  The averagePrice is already provided with the OnPositionUpdate() method when the position is long or short.
                  Last edited by NinjaTrader_ChelseaB; 09-06-2022, 09:47 AM.
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #24
                    Thanks for this. I will see what I can do.

                    I am looking for the averagePrice of the Stop....not the initial Entry. So I am not sure averagePrice will work for that.

                    Comment


                      #25
                      Hello BigT4X,

                      You can assign the order object to variable in OnOrderUpdate(). Then you can check that variable is not null, check the <order>.OrderState is OrderState.Filled, and check the <order>.AverageFillPrice.
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #26
                        I believe I coded it correctly as I am getting the exact same results as my Non-PositionUpdate code.

                        Please let me know if you see any concerns with this? Should I add something for Rejected orders or any other order status? Anything to handle manual intervention/exits? etc (sharing a link to another post is fine)

                        To keep the post as short as possible.......just showing LongStop1 and not all the Long and Short Stops (small snippet):

                        public class BigTAutoTrader_V2 : Strategy
                        {
                        private Order StopLongOrder1 = null;
                        private double StopAverageFillPrice = 0;
                        private bool StopFill = false;
                        }
                        ......
                        protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string nativeError)
                        {
                        //Assign Stop Orders
                        if (order.Name == "LongStops1" && order != StopLongOrder1)
                        {
                        StopLongOrder1 = order;
                        }
                        .....
                        //Set Stop price on Fills and Reset on Cancels
                        if (StopLongOrder1 != null && StopLongOrder1 == order)
                        {
                        Print(order.ToString());
                        if (order.OrderState == OrderState.Filled)
                        {
                        StopAverageFillPrice = averageFillPrice;
                        StopFill = true;
                        }
                        if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                        {
                        StopLongOrder1 = null;
                        StopAverageFillPrice = 0;
                        StopFill = false;
                        }
                        }
                        .....
                        protected override void OnPositionUpdate(Cbi.Position position, double averagePrice, int quantity, Cbi.MarketPosition marketPosition)
                        {
                        if (marketPosition == MarketPosition.Flat)
                        {
                        if (StopLongOrder1 != null && StopFill == true)
                        {
                        if (!(ToTime(Time[0]) >= 160000 && ToTime(Time[0]) < 170000) && StopAverageFillPrice < BigT_Auto_LinearRegressionBands1.UPLB[0] * 1.0012 && StopAverageFillPrice <= Open[0])
                        {
                        EnterShort(QuantitySize, "Short7ReverseOnLongStop");
                        }
                        StopLongOrder1 = null;
                        StopAverageFillPrice = 0;
                        StopFill = false;
                        }
                        }
                        }
                        Last edited by BigT4X; 09-06-2022, 08:09 PM.

                        Comment


                          #27
                          Hello BigT4X,

                          I think you are wanting if (StopLongOrder1 != null && StopLongOrder1.OrderState == OrderState.Filled)
                          As well as StopLongOrder1.AverageFillPrice < BigT_Auto_LinearRegressionBands1.UPLB[0], etc.
                          Last edited by NinjaTrader_ChelseaB; 09-07-2022, 07:08 AM.
                          Chelsea B.NinjaTrader Customer Service

                          Comment

                          Latest Posts

                          Collapse

                          Topics Statistics Last Post
                          Started by ETFVoyageur, Today, 07:55 PM
                          0 responses
                          4 views
                          0 likes
                          Last Post ETFVoyageur  
                          Started by janio973, Today, 07:24 PM
                          1 response
                          7 views
                          0 likes
                          Last Post NinjaTrader_Manfred  
                          Started by aligator, 01-06-2022, 12:14 PM
                          4 responses
                          242 views
                          0 likes
                          Last Post john_44573  
                          Started by reynoldsn, Today, 05:56 PM
                          0 responses
                          12 views
                          0 likes
                          Last Post reynoldsn  
                          Started by bortz, 11-06-2023, 08:04 AM
                          51 responses
                          1,996 views
                          0 likes
                          Last Post aligator  
                          Working...
                          X