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

Unmanaged Strategy Submitting Excessive Orders

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

    Unmanaged Strategy Submitting Excessive Orders

    Hello staff,

    I've switched from Managed to Unmanaged to have more flexibility and the change to Unmanaged has resolved a lot of the issues I had before. Now, some new issues have appeared as well.
    I've been testing my script on a Simulated Data Feed today and everything was functioning as supposed to, however, when I deployed my script on a real-time chart with a Live account the script has been submitting far too many orders than it should. See the attached image.

    The only place where I reset my orders to null is in OnOrderUpdate() when Cancelled and in OnExecutionUpdate() when Filled.
    Any ideas what could be going wrong here?

    I'm looking forward to your reply.

    Edit: I've been using this method in OnOrderUpdate() for a while now, could it be wrong to have the same "order" name for each one?

    if (order.Name == "AL1")
    AL1 = order;
    if (order.Name == "AL2")
    AL2 = order;
    if (order.Name == "AL3")
    AL3 = order;
    if (order.Name == "AL4")
    AL4 = order;
    Attached Files
    Last edited by GLFX005; 07-14-2020, 11:26 AM.

    #2
    Hello GLFX005,

    Use Print() and TraceOrders to understand what is happening.

    Below is a link to a forum post that demonstrates using prints to understand behavior.
    https://ninjatrader.com/support/foru...121#post791121

    I do have a few unmanaged examples you may find helpful.
    https://ninjatrader.com/support/foru...269#post802269
    https://ninjatrader.com/support/foru...579#post770579


    Using prints, does this condition get evaluated before or after the variables that are null are being assigned?

    OnOrderUpdate() will run for every order state change. Is this code running during all order states or a specific order state?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hello Chelsea, thank you for your reply.

      The two Unmanaged examples you have provided are quite interesting, yes. I found this in particular interesting:

      "This is definitely an issue with NinjaTrader 8. With NinjaTrader 8, the order object returned isn't updated when OnOrderUpdate() runs and will definitely cause issues if the Order object is assigned from OnOrderUpdate()."

      The way I have been assigning order .. names, is what I would call them I guess? Has been happening as you can see in the attached image.
      But in your sample codes for Unmanaged I can see something completely different that is placed at the very top of the script.

      private void AssignOrderToVariable(ref Order order)

      And I can assume that having OnOrderUpdate() below the OnBarUpdate() will cause some issues in that scenario if the order name assignment isn't happening quick enough, or at all.
      Another thing I noticed is the difference in the OnOrderUpdate() itself.

      What you have: 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 comment)

      What I have: protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)

      I can see similar differences with OnExecutionUpdate(). Should I copy/paste your versions into my script? What are some other crucial changes I should be aware of when changing to Unmanaged Approach?

      I'm looking forward to your reply.

      Edit: This video I made shows the multiple order submissions I am having, this video is recorded after having placed my order assignment above OnBarUpdate() in the same way that you have in your examples.

      Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
      Attached Files
      Last edited by GLFX005; 07-14-2020, 12:59 PM.

      Comment


        #4
        Hello GLFX005,

        C# methods are not run from top to bottom. They are event based and run when specific events happen.

        I'm asking if the order object from OnOrderUpdate is being assigned to the variable (from the OnOrderUpdate() event) previously in time to when this condition is checking that variable is null.

        If OnBarUpdate declaration is below OnOrderUpdate or above OnOrderUpdate or even above OnStateChange wont matter. It only matters which events have happened first, in time (not from top to bottom in the script)

        As an example, AssignToOrder is called from OnOrderUpdate() when the order is changing states (the change of the order state is the event). I'm assigning the order object to the variable that holds the order.

        If you would like to use the example as your starting point you may save a lot of time.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Hello Chelsea, thank you for your reply.

          I have added some Prints to the order name assignment and to the order submission. These are my results. I manually Cancelled the order a few times on the chart to produce more results.

          Enabling NinjaScript strategy 'Kyori34/206046869' : On starting a real-time strategy - StartBehavior=WaitUntilFlat EntryHandling=All entries EntriesPerDirection=2 StopTargetHandling=By strategy position ErrorHandling=Ignore all errors ExitOnSessionClose=False SetOrderQuantityBy=Strategy ConnectionLossHandling=Keep running DisconnectDelaySeconds=10 CancelEntriesOnStrategyDisable=True CancelExitsOnStrategyDisable=False Calculate=On price change IsUnmanaged=True MaxRestarts=4 in 5 minutes
          14/07/2020 21:15:00 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:00: BarsInProgress=0 Action=Buy OrderType=MIT Quantity=2 LimitPrice=0 StopPrice=10457.25 SignalName='ATP2'
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been submitted after checking for null
          14/07/2020 21:15:00 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:00: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been submitted after checking for null
          14/07/2020 21:15:00 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:00: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been submitted after checking for null
          14/07/2020 21:15:28 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:28: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been submitted after checking for null
          14/07/2020 21:15:28 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:28: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been submitted after checking for null
          14/07/2020 21:15:28 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:28: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been submitted after checking for null
          14/07/2020 21:15:28 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:28: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been submitted after checking for null
          14/07/2020 21:15:28 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:28: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          14/07/2020 21:15:34 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:34: BarsInProgress=0 Action=Buy OrderType=MIT Quantity=2 LimitPrice=0 StopPrice=10457.25 SignalName='ATP2'
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been submitted after checking for null
          14/07/2020 21:15:34 Strategy 'Kyori34/206046869': Entered internal SubmitOrderUnmanaged() method at 14/07/2020 21:15:34: BarsInProgress=0 Action=Buy OrderType=StopMarket Quantity=2 LimitPrice=0 StopPrice=10577.25 SignalName='AL1'
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          AL1 has been assigned in AssignOrderToVariable
          Disabling NinjaScript strategy 'Kyori34/206046869'
          14/07/2020 21:15:40 CancelAllOrders: BarsInProgress=0


          EDIT:

          Print 1:
          private void AssignOrderToVariable(ref Order order)
          {
          //Assignment
          if (order.Name == "AL1" && AL1 != order)
          AL1 = order;
          Print("AL1 has been assigned in AssignOrderToVariable");
          }


          Print 2:

          if (AL1 == null
          && AL2 == null
          && AL3 == null
          && Position.MarketPosition == MarketPosition.Flat
          && Low[0] <= KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0]
          && Close[0] <= KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] - 1 * TickSize
          && Close[0] > KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] - 7 * TickSize
          && C1 < 2)
          {
          Print("AL1 has been submitted after checking for null");
          SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, Contracts, 0, KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low1[0], "", "AL1");
          }
          Last edited by GLFX005; 07-14-2020, 01:21 PM.

          Comment


            #6
            Hello Chelsea, just a quick additional response.

            I see that you are doing something different at the very top of your example compared to what I'm doing. You set orders like this.

            private Order entryOrder, exitFlat, exitSession;

            And I set orders like this:

            private Order AL1 = null;

            Could this be the cause of the issue?

            Edit: here's another video example of the issue still happening even after setting the "private Order" with your method.
            Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
            Last edited by GLFX005; 07-14-2020, 01:58 PM.

            Comment


              #7
              Hello GLFX005,

              No, that will not have any difference.

              I were to declare:
              private Order entryOrder = null;
              private Order exitFlat = null;
              private Order exitSession = null;

              This would be exactly the same as:
              private Order entryOrder, exitFlat, exitSession;

              The variables are already null since they are not assigned a value.

              Where is AssignOrderToVariable() being called?
              If your variable is being assigned, it would not be null.
              Trying checking that the order variable is null immediately after it is assigned.

              What in what order states are you checking your condition?
              Last edited by NinjaTrader_ChelseaB; 07-14-2020, 02:07 PM.
              Chelsea B.NinjaTrader Customer Service

              Comment


                #8
                Hello Chelsea,

                I have found the solution to my problem. I will show you what I changed.

                From:

                if (AL1 == null
                && AL2 == null
                && AL3 == null
                && Position.MarketPosition == MarketPosition.Flat
                && Low[0] <= KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0]
                && Close[0] <= KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] - 1 * TickSize
                && Close[0] > KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] - 7 * TickSize
                && C1 < 2)
                {
                Print("AL1 has been submitted after checking for null");
                SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, Contracts, 0, KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low1[0], "", "AL1");
                }

                To:

                if (AL1 == null
                && AL2 == null
                && AL3 == null
                && Position.MarketPosition == MarketPosition.Flat
                && Low[0] <= KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0]
                && Close[0] <= KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] - 1 * TickSize
                && Close[0] > KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] - 7 * TickSize
                && C1 < 2)
                {
                Print("AL1 has been submitted after checking for null");
                AL1 = SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, Contracts, 0, KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low1[0], "", "AL1");
                }

                Now, however many times I click to Cancel the order, it always resubmits the order only once.

                Thank you for your time and effort to help me find the solution.

                Comment


                  #9
                  Hello GLFX005,

                  Orders should only be assigned to variables from the order object in OnOrderUpdate or you will run into issues later.

                  In my example scripts I assign an empty placeHolderOrder so these aren't null, but I always assign from OnOrderUpdate() as I know this will cause issues.
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #10
                    Hello Chelsea,

                    I will show you the life cycle of a single order:

                    private Order AS1;

                    (I used to have private void AssignOrderToVariable(ref Order order) here)

                    protected override void OnBarUpdate()

                    if (AS1 == null
                    && Position.MarketPosition == MarketPosition.Flat
                    && Close[0] > KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] + 7 * TickSize
                    && Low[0] > KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0])
                    {
                    SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.StopMarket, Contracts, 0, KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0], "", "AS1");
                    }

                    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 comment)


                    if (order.Name == "AS1" && AS1 != order)
                    AS1 = order;

                    if (AS1 != null && AS1 == order)
                    {
                    if (AS1.OrderState == OrderState.Cancelled)
                    {
                    AS1 = null;
                    }
                    }

                    protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity,
                    Cbi.MarketPosition marketPosition, string orderId, DateTime time)


                    if (AS1 != null && AS1 == execution.Order)
                    {
                    if (execution.Order.OrderState == OrderState.Filled)
                    {
                    AS1 = null;
                    }
                    }

                    Comment


                      #11
                      Hello GLFX005,

                      It does not look like you are directly assigning an order from an order method to a variable in this code, so this looks good.

                      Just a tip, that empty placeHolderOrder is very useful in the example I script I linked. It just lets the script know that the order has been submitted, but doesn't yet exist.
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #12
                        Hello Chelsea,

                        It may look good, but actually causes the error to still happen. However, when I am assigning the order like "AS1 = Submit..." then the error does not happen anymore.
                        So I am at loss as to what to do when apparently the wrong method of assigning the order to a variable is what resolves the issue.

                        Comment


                          #13
                          Hello GLFX005,

                          If an order is assigned to a variable it wont be null.

                          I'm using the placeHolderOrder to assign an empty order while waiting for the order to be constructed behind the scenes.

                          If you are seeing the variable is null, then it's null and nothing has been assigned to it yet. So you would need to wait until the order is actually constructed and becomes a real order in OnOrderUpdate, then assign it to the variable.

                          This is demonstrated in the example I have provided you.

                          If you are seeing a variable is null, then it hasn't been assigned an object yet.

                          Are you expecting an order variable to not be null immediately after an order method is called (because it won't be yet, as it takes a moment to create the order and submit it).

                          Are you seeing any issues with the example I provided?
                          Chelsea B.NinjaTrader Customer Service

                          Comment


                            #14
                            Hello Chelsea, thank you kindly for your reply.

                            I assumed that my script was reading parts too fast while other things are happening at a slower rate in the background, such as an order being created and submitted.
                            I don't see any problem with your example, no. You are using a variable to make sure that the script thinks an order is there while the actual order is still being created.
                            Applying that logic to my own order life cycle, I would get something like this.

                            private Order AS1;
                            private Order placeHolderOrder;

                            (I used to have private void AssignOrderToVariable(ref Order order) here)

                            protected override void OnBarUpdate()

                            if (AS1 == null
                            && Position.MarketPosition == MarketPosition.Flat
                            && Close[0] > KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0] + 7 * TickSize
                            && Low[0] > KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0])
                            {
                            AS1 = placeHolderOrder;
                            SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.StopMarket, Contracts, 0, KyoriBands2(TwentyFive, Fifty, SeventyFive, Hundred).Low2[0], "", "AS1");
                            }

                            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 comment)


                            if (order.Name == "AS1" && AS1 != order)
                            AS1 = order;

                            if (AS1 != null && AS1 == order)
                            {
                            if (AS1.OrderState == OrderState.Cancelled)
                            {
                            AS1 = null;
                            Do I set placeHolderOrder to null here?
                            }
                            }

                            protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity,
                            Cbi.MarketPosition marketPosition, string orderId, DateTime time)


                            if (AS1 != null && AS1 == execution.Order)
                            {
                            if (execution.Order.OrderState == OrderState.Filled)
                            {
                            AS1 = null;
                            Do I set placeHolderOrder to null here?
                            }
                            }

                            I will test this tomorrow when the markets are open again.

                            Comment


                              #15
                              Hello GLFX005,

                              The place holder would be when you are submitting an order. As that order doesn't exist immediately, it has to be constructed.

                              You could also choose to use bools instead of relying on an order variable to be null.
                              Chelsea B.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Christopher_R, Today, 12:29 AM
                              0 responses
                              6 views
                              0 likes
                              Last Post Christopher_R  
                              Started by sidlercom80, 10-28-2023, 08:49 AM
                              166 responses
                              2,235 views
                              0 likes
                              Last Post sidlercom80  
                              Started by thread, Yesterday, 11:58 PM
                              0 responses
                              3 views
                              0 likes
                              Last Post thread
                              by thread
                               
                              Started by jclose, Yesterday, 09:37 PM
                              0 responses
                              7 views
                              0 likes
                              Last Post jclose
                              by jclose
                               
                              Started by WeyldFalcon, 08-07-2020, 06:13 AM
                              10 responses
                              1,415 views
                              0 likes
                              Last Post Traderontheroad  
                              Working...
                              X