Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

An Enter() method to submit an entry order has been ignored

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

    #16
    Hello wzgy0920,

    Thanks for your notes.

    The error message 'Cancellation rejected by the Order Management System - Order is complete.' means that you tried to cancel an order that was already complete.

    Order objects should be tracked in OnOrderUpdate() and OnExecutionUpdate() and before calling CancelOrder() you should check if the Order object is not null as seen in the SampleCancelOrder reference sample.

    SampleCancelOrder: https://ninjatrader.com/support/help...thod_to_ca.htm

    Note from the SetStopLoss() and SetProfitTarget() help guide documentation:

    SetStopLoss(): The signal name generated internally by this method is "Stop loss" which can be used with various methods such as BarsSinceExitExecution(), or other order concepts which rely on identifying a signal name

    SetProfitTarget(): ​The signal name generated internally by this method is "Profit target" which can be used with various methods such as BarsSinceExitExecution(), or other order concepts which rely on identifying a signal name

    You could consider using Exit methods for your stop loss and profit target orders instead of Set methods. An example of using Exit methods can be seen in the SampleCancelOrder reference sample.​

    As stated in my previous post, SetStopLoss() and SetProfitTarget() should be reset when your strategy is flat otherwise, the last price/offset value set will be used to generate your stop loss order on your next open position. This is noted on the SetStopLoss() and SetProfitTarget() help guide documentation.

    NinjaScript strategies cannot see manually placed orders so it is not suggested to place manual orders on the same account/instrument that the NinjaScript strategy is running on. A NinjaScript strategy is only able to see orders that the specific strategy instance places.

    Use prints to understand how the logic is the strategy is behaving.
    https://ninjatrader.com/support/foru...121#post791121
    Last edited by NinjaTrader_BrandonH; 09-27-2023, 09:50 AM.
    <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

    Comment


      #17
      Also, regarding my previous question. When I non-programmatically cancel a pending order (i.e. manually in chart trader), it gets canceled. My strategy also reports that myEntryOrder == null. However, any subsequent calls to the EnterLongLimit/EnterShortLimit does not result in a new order being placed. I can't figure out why this is happening.​

      Another issue I noticed was that sometimes my strategy stops updating the orders to Enter(). For example, if trade signal 1 appears, it puts in an Enter order. Then signal 2 appears, making the signal 1 invalid. Therefore the orignal order for signal 1 should be canceled since it never got filled, and a new order for signal 2 should be submitted. But I noticed "sometimes", despite the new signal, the order new orders are not being submitted and older orders are not being canceled.

      Comment


        #18
        Hello wzgy0920,

        Thanks for your notes.

        " When I non-programmatically cancel a pending order (i.e. manually in chart trader), it gets canceled"

        NinjaScript strategies cannot see manually placed orders so it is not suggested to place manual orders on the same account/instrument that the NinjaScript strategy is running on. A NinjaScript strategy is only able to see orders that the specific strategy instance places.

        "But I noticed "sometimes", despite the new signal, the order new orders are not being submitted and older orders are not being canceled."

        Prints would need to be added throughout the strategy to understand exactly how your logic in your strategy is evaluating.

        TraceOrders could also be enabled to see more information about the orders when debugging the strategy. With the use of this property, you can track orders placed, amended, and canceled

        Below is a link to a forum post that demonstrates how to use prints and TraceOrders to understand a script's behavior.
        https://ninjatrader.com/support/foru...121#post791121
        <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

        Comment


          #19
          Brandon,
          Thank you for the helpful responses. I hope this is not too much to ask, but can you please help me by providing pseudo code or boilerplate code for the order management. I just can't get my order management to work properly. I already looked at all the sample code in documentations. Those example codes are for different situations. So when I try to adapt those example codes, I can't seem to get it right with my strategy. I already tried troubleshooting with print statements and such. But I can't figure out what I am doing wrong. Below is my general criteria for order management in my strategy.
          1. A function outputs a trade signal. The output include entry price, stop price, target price and a unique string ID that is unique to the trade signal. The function can output the same trade signal until a new signal arrives
          2. We decide if we should take the trade signal based on criteria (e.g. time of day)
          3. If we want to take the signal, a Limit order is placed in hope that the order will be filled. Along with the limit order, the SetStopLoss/SetProfitTarget is also placed if the order gets filled.
          4. If the order gets filled, all new trade signals are ignored until we are flat again
          5. If the order does not get filled and a new trade signal arrives that is different from the previous one, we should cancel the original order and place an order with the new trade signal

          Comment


            #20
            Hello wzgy0920,

            Thanks for your notes.

            I do not have any sample code available for your specific situation and I have not seen the entirety of your strategy so I am unsure exactly how you are defining your order management in the script.

            When working with any issue, it is important to take steps to isolate the issue so that the exact line causing the behavior can be found. This is a process of elimination and a process of debugging by adding prints.

            First, its great to create a copy of the script so that the original work is kept safe.

            Below is a link to a video that demonstrates making a copy of script.
            https://www.youtube.com/watch?v=BA0W...utu.be&t=8m15s

            Once the copy is created, the copy can be modified in any way without losing the original work.​

            The next step is to start reducing/commenting out code. I suggest that you reduce the code of your script by commenting out sections of code in the script. Program one section of code in your script at a time and test to see if the behavior is working as expected. Once you have one section of code working correctly, you could move on to the next section of code and test to see if it is working as expected.

            When you find that something is not working as expected, debugging prints would need to be used to print out every value being used for your logic so that you can understand exactly how the logic is behaving.

            That said, I recommend using Exit methods instead of Set methods so that you have more control over how orders are handled.

            The reference samples below demonstrates using OnOrderUpdate() and OnExecutionUpdate(), using Exit methods for stops/targets, as well as how CancelOrder() could be used in a script.

            SampleOnOrderUpdate: https://ninjatrader.com/support/help...and_onexec.htm
            SampleCancelOrder: https://ninjatrader.com/support/help...thod_to_ca.htm

            OnOrderUpdate: https://ninjatrader.com/support/help...rderupdate.htm
            OnExecutionUpdate: https://ninjatrader.com/support/help...tionupdate.htm
            CancelOrder: https://ninjatrader.com/support/help...ancelorder.htm

            Note that it is against our policy to create or debug your custom logic on your behalf in the Support Department at NinjaTrader. It would be up to your to create and debug your logic to understand exactly how your custom logic is evaluating.

            If you need assistance with creating prints or analyzing output in the Output window, please let me know and I will be happy to assist.
            <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

            Comment


              #21
              Brandon,

              Per your suggestion, I have fully adapted the sample code from SampleOnOrderUpdate along with using Exit methods instead of using SetStop/SetProfit methods. During my testing I came across a corner case where my stop turns out to be 1 tick away from entry price. For example, entry price is $4321.25 and stop price is $4321.00. I get filled to open a long position at $4321.25 and then market price drops and hits my expected stop price of $4321.00.This results in a situations where my stop order gets rejected because of market volatility. This also prevents cancellation of my ExitLongLimit order. See screenshot and output messages below. I referred to this post, for sample code on how to handle rejection. However this doesn't work for me. Inside my OnOrderUpdate(), I put a print statement for when order.OrderState == OrderState.Rejected. However, this print statement never occurs. Therefore, I don't understand how to trap this rejection.

              Code:
              Strategy 'MyCustomStrategy/300201363' submitted an order that generated the following error 'Order rejected'. Strategy has sent cancel requests, attempted to close the position and terminated itself.
              Disabling NinjaScript strategy 'MyCustomStrategy/300201363'
              Strategy 'MyCustomStrategy/300201363' submitted a cancellation request for Order ID 'orderId='2d7925ba4cbb46f8996d40f979d4b793' account='Playback101' name='MyProfitTarget' orderState=Working instrument='ES 12-23' orderAction=Sell orderType='Limit' limitPrice=4334.5 stopPrice=0 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=12500 time='2023-09-27 10:01:44' gtd='2099-12-01' statementDate='2023-09-27'' which has not been confirmed cancelled. Please check your account orders and positions.
              ​
              Click image for larger version

Name:	image.png
Views:	246
Size:	19.4 KB
ID:	1270698


              Also, I have one more question related to the sample code provided in SampleOnOrderUpdate​. Within the OnExecutionUpdate() there is portion of the code s shown below. In this code, why does stopOrder and targetOrder assigned a null value if the execution is partially filled? Don't we have to wait until it is completely filled before we assign a null value to the stopOrder and targetOrder?

              HTML Code:
              // Reset our stop order and target orders' Order objects after our position is closed. (1st Entry)
              if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
              {
              if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
              {
              stopOrder = null;
              targetOrder = null;
              }
              }
              ​​

              Comment


                #22
                Hello wzgy0920,

                Thanks for your notes.

                The error message indicates that you submitted a price to the wrong side of the market. As Chelsea noted in post # 8 on this forum thread, Buy stop orders must be above the ask, sell stop orders must be below the bid.

                See this forum thread: https://forum.ninjatrader.com/forum/...ed#post1199001

                If this is due to market volatility then there isn't really a way to 100% avoid this occurring, as in volatile markets the market could move so far and fast that this would occur.

                ​You could place your stop loss further from the current price.

                You could also consider using RealtimeErrorHandling.IgnoreAllErrors to trap order errors in OnOrderUpdate by checking error == ErrorCode.OrderRejected.

                Please note that setting this property value to IgnoreAllErrors can have serious adverse affects on a running strategy unless you have programmed your own order rejection handling in the OnOrderUpdate() method. To do this you could trap the rejected order by checking if the OrderState is Rejected within OnOrderUpdate() followed by defining your own order rejection handling behavior for the rejected order.

                Please see the example in the help guide link below that demonstrates using RealtimeErrorHandling and trapping a rejected order in OnOrderUpdate().

                RealtimeErrorHandling — https://ninjatrader.com/es/support/h...orhandling.htm

                This section of code in the SampleOnOrderUpdate script resets our stop order and target orders' Order objects after our position is closed for the first entry. This could be seen in the code's documentation. The execution of the stopOrder or targetOrder Order object could be OrderState.Filled or OrderState.PartFilled.

                <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                Comment


                  #23
                  Thank you Barndon. I have another issue now. I have pretty much adapted the sample code from SampleOnOrderUpdate​. One issue I noticed in live real-time trading is with partial fill. Let me give you an example I saw. I entered long position on ES at $4323.25 with 2x quantity which got filled in full. Then ExitLongLimit and ExitStopMarket orders were submitted with 2x quantity. Then my ExitLongLimit was filled at 4325.50, however it was in partials of 1x quantity. Although my open positions were flat, I saw I still had the stop order pending at 4316.25 but only with 1x quantity. It seems in the example code from SampleOnOrderUpdate​​, it is not properly canceling the orders after all positions are exited with partial fills. I am unsure how to troubleshoot this BECUASE during market replay, I cannot force a partial fill to investigate this further. Do you know what portion of the example code from SampleOnOrderUpdate​ can be causing the issue?

                  Comment


                    #24
                    Hello wzgy0920,

                    Thanks for your notes.

                    In your strategy are you using execution.Order.Filled for the quantity argument of your Exit orders in OnExecutionUpdate() when the execution.Order.OrderState == OrderState.PartFilled?

                    Are you also using execution.Order.Filled for the quantity argument of your Exit orders in OnExecutionUpdate() when the execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled?

                    Do you reset the entryOrder object and the sumFilled counter to null/0 after the order has been filled?​

                    From the SampleOnOrderUpdate reference sample:

                    Code:
                    // Submit exit orders for partial fills
                    if (execution.Order.OrderState == OrderState.PartFilled)
                    {
                        stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                        targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                    }
                    // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
                    else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
                    {
                        // Stop-Loss order for OrderState.Filled
                        stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                        targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                    }
                    
                    // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
                     if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
                    {
                        entryOrder = null;
                        sumFilled = 0;
                    }
                    ​
                    Have you added debugging prints to understand exactly how the orders are behaving in your script?

                    If not, this would be necessary to understand exactly how your order are behaving.

                    It is also helpful to enable TraceOrders and print the order object in OnOrderUpdate.

                    TraceOrders - https://ninjatrader.com/support/help...raceorders.htm
                    OnOrderUpdate() - https://ninjatrader.com/support/help...rderupdate.htm

                    I'm also including a link to a forum post with further suggestions on debugging a script.
                    https://ninjatrader.com/support/foru...956#post671956

                    Further, you could have the script submit a large number of orders when testing in Playback to try and make the strategy submit partial orders.

                    Also, if you are using the Sim101 account that comes with NinjaTrader for testing, you could enable to 'Enforce partial fills' option in the Tools > Options > Trading tab to try which sets if partial fills will be forced on simulation orders.
                    Last edited by NinjaTrader_BrandonH; 09-28-2023, 09:52 AM.
                    <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                    Comment


                      #25
                      Brandon, below is my OnExecutionUpdate() adapted from the sample code in SampleOnOrderUpdate​​,​


                      Code:
                      protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
                      {
                      bool submit_exit_orders = false;
                      
                      if (myEntryOrder != null && myEntryOrder == execution.Order)
                      {
                      if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
                      {
                      // We sum the quantities of each execution making up the entry order
                      sumFilled += execution.Quantity;
                      
                      // Submit exit orders for partial fills
                      if (execution.Order.OrderState == OrderState.PartFilled)
                      {
                      submit_exit_orders = true;
                      
                      }
                      // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
                      else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
                      {
                      // Stop-Loss order for OrderState.Filled
                      submit_exit_orders = true;
                      }
                      
                      // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
                      if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
                      {
                      myEntryOrder = null;
                      sumFilled = 0;
                      }
                      
                      if (submit_exit_orders) {
                      
                      if (current_TradeDirection == true){
                      
                      myStopOrder = ExitLongStopMarket(barsInProgressIndex: 0, isLiveUntilCancelled: true, quantity: execution.Order.Filled, stopPrice: current_StopPrice, fromEntrySignal: execution.Order.Name, signalName: "MyStopLoss");
                      myTargetOrder = ExitLongLimit(barsInProgressIndex: 0, isLiveUntilCancelled: true, quantity: execution.Order.Filled, limitPrice: current_TargetPrice, fromEntrySignal: execution.Order.Name, signalName: "MyProfitTarget");
                      }
                      else {
                      myStopOrder = ExitShortStopMarket(barsInProgressIndex: 0, isLiveUntilCancelled: true, quantity: execution.Order.Filled, stopPrice: current_StopPrice, fromEntrySignal: execution.Order.Name, signalName: "MyStopLoss");
                      myTargetOrder = ExitShortLimit(barsInProgressIndex: 0, isLiveUntilCancelled: true, quantity: execution.Order.Filled, limitPrice: current_TargetPrice, fromEntrySignal: execution.Order.Name, signalName: "MyProfitTarget");
                      }
                      
                      }
                      }
                      
                      }
                      
                      // Reset our stop order and target orders' Order objects after our position is closed. (1st Entry)
                      if ((myStopOrder != null && myStopOrder == execution.Order) || (myTargetOrder != null && myTargetOrder == execution.Order))
                      {
                      if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
                      {
                      myStopOrder = null;
                      myTargetOrder = null;
                      }
                      }
                      
                      }

                      Comment


                        #26
                        Hello wgzy0920,

                        Thanks for your notes.

                        You should call your Exit methods inside the condition that checks if (execution.Order.OrderState == OrderState.PartFilled) and inside the condition that checks if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled) as seen in the SampleOnOrderUpdate code.

                        For example, the code should look something like this:

                        Code:
                        // Submit exit orders for partial fills
                        if (execution.Order.OrderState == OrderState.PartFilled)
                        {
                            stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                            targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                        }
                        // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
                        else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
                        {
                            // Stop-Loss order for OrderState.Filled
                            stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                            targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                        }​


                        SampleOnOrderUpdate: https://ninjatrader.com/support/help...and_onexec.htm
                        <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                        Comment


                          #27
                          Originally posted by NinjaTrader_BrandonH View Post
                          Hello wgzy0920,

                          Thanks for your notes.

                          You should call your Exit methods inside the condition that checks if (execution.Order.OrderState == OrderState.PartFilled) and inside the condition that checks if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled) as seen in the SampleOnOrderUpdate code.
                          I put my Exit methods outside the if and else if statements because in both cases the exit orders are same. So I am improve code reusability by setting submit_exit_orders = true inside the if and else if statement. And then later I call the Exit methods. Programmatically am I coding something wrong??? I did this to reduce verbosity of my code and make it more concise.

                          Comment


                            #28
                            Hello wzgy0920,

                            Thanks for your notes.

                            The Exit order methods should be called within the conditions as mentioned in the previous post because when the execution.Order.OrderState == OrderState.PartFilled, we submit Exit orders for the partial fills.

                            Then, when the execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled we update our exit order quantities once OrderState turns to filled and we have seen execution quantities match order quantities. This is a different condition than the condition noted above where we check if the OrderState is PartFilled.

                            Please modify your code so that the Exit order methods are called within the two separate conditions the same way it is seen in the SampleOnOrderUpdate reference sample.​
                            <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                            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