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

Order rejected

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

    Order rejected

    Hi,
    I'm getting the error "Order rejected". And in another window it says: "Sell stop or sell stop limit orders can't be placed above the market".
    But the price is above the entry for my EnterShortStopMarket.


    These are the error windows and the Output. I've placed a Print to show the values, and the market price is above my entry.

    I get this error while in playback mode 1x. Calcuate onEactTick

    The EnterShortStopMarket runs on FirstTickOfBar

    Click image for larger version

Name:	1.png
Views:	38
Size:	190.1 KB
ID:	1301535


    Here is the chart screenshot. Clearly the bar opens above the stopPrice

    Click image for larger version

Name:	2024-04-30 14_12_01-Chart - NQ JUN24.png
Views:	28
Size:	10.7 KB
ID:	1301536

    This is the part of the code where I place the limit order:

    This is inside another IF statement --> IsFirstTickOfBar
    Code:
    if (Position.MarketPosition == MarketPosition.Flat)
                        {
                            if (BearSignal[1] == 1)
                            {
                                if (Open[0] > _shortEntry && Close[0] > _shortEntry)
                                {
                                    myEntryOrder = EnterShortStopMarket(0, false, 1, _shortEntry, "Short_Entry");
                                    Print(string.Format("EnterShortStopMarket {0}; {1}; {2}; {3}; {4}; {5}, Current: {6}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _shortEntry, Close[0]));
                                }
                                else
                                {
                                    myEntryOrder = EnterShortLimit(0, false, 1, _shortEntry, "Short_Entry");
                                    Print(string.Format("EnterShortLimit {0}; {1}; {2}; {3}; {4}; {5}, Current: {6}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _shortEntry, Close[0]));
                                }
                            }
                            if (BullSignal[1] == 1)
                            {
                                if (Open[0] < _longEntry && Close[0] < _longEntry)
                                {
                                    myEntryOrder = EnterLongStopMarket(0, false, 1, _longEntry, "Long_Entry");
                                    Print(string.Format("EnterLongStopMarket {0}; {1}; {2}; {3}; {4}; {5}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _longEntry));
                                }    
                                else
                                {
                                    myEntryOrder = EnterLongLimit(0, false, 1, _longEntry, "Long_Entry");
                                    Print(string.Format("EnterLongLimit {0}; {1}; {2}; {3}; {4}; {5}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _longEntry));
                                }
                            }
                        }​

    #2
    Hello NM_eFe,

    Two issues here.

    First, orders should not be assigned to variables directly from the order method call, but should be instead assigned from OnOrderUpdate().
    (Otherwise there will be unexpected behavior)

    From the help guide:
    "OnOrderUpdate() will run inside of order methods such as EnterLong() or SubmitOrderUnmanaged(), therefore attempting to assign an order object outside of OnOrderUpdate() may not return as soon as expected. If your strategy is dependent on tracking the order object from the very first update, you should try to match your order objects by the order.Name (signal name) from during the OnOrderUpdate() as the order is first updated."


    The help guide includes a code sample of assigning orders to variables from OnOrderUpdate().


    Second, when submitting a stop order, it is necessary to check the price of the order is a valid price.

    A buy stop order must have the stop price above the current ask (GetCurrentAsk()), a sell stop order must have the stop price below the current bid (GetCurrentBid()).

    The forum post below discusses this.
    Hi I have a sellshort StopLimit order that i change if unfilled. I tick below the last bar's low. I keep getting the stop price can't be changed above the market but the price value it quotes ( the one I want) is below the market. Currently I am on the simulated feed. I appreciate in real market situations this could happen

    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Thank you VERY MUCH, Chelsea !!

      It seems to be working without error now !

      Click image for larger version

Name:	2024-04-30 23_58_20-Chart - NQ JUN24.png
Views:	20
Size:	20.0 KB
ID:	1301607

      Code looks like this now:

      Code:
                          if (Position.MarketPosition == MarketPosition.Flat)
                          {
                              if (BearSignal[1] == 1)
                              {
                                 [B] if (_shortEntry < GetCurrentBid())[/B] //(Open[0] > _shortEntry && Close[0] > _shortEntry)
                                  {
                                      EnterShortStopMarket(0, false, 1, _shortEntry, "Short_Entry");
                                      Print(string.Format("EnterShortStopMarket {0}; {1}; {2}; {3}; {4}; {5}, Current: {6}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _shortEntry, Close[0]));
                                  }
                                  else
                                  {
                                      EnterShortLimit(0, false, 1, _shortEntry, "Short_Entry");
                                      Print(string.Format("EnterShortLimit {0}; {1}; {2}; {3}; {4}; {5}, Current: {6}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _shortEntry, Close[0]));
                                  }
                              }
                              if (BullSignal[1] == 1)
                              {
                                 [B] if (_longEntry > GetCurrentAsk())[/B] //(Open[0] < _longEntry && Close[0] < _longEntry)
                                  {
                                      EnterLongStopMarket(0, false, 1, _longEntry, "Long_Entry");
                                      Print(string.Format("EnterLongStopMarket {0}; {1}; {2}; {3}; {4}; {5}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _longEntry));
                                  }    
                                  else
                                  {
                                      EnterLongLimit(0, false, 1, _longEntry, "Long_Entry");
                                      Print(string.Format("EnterLongLimit {0}; {1}; {2}; {3}; {4}; {5}", Time[0], CurrentBar, BullSignal[1], BearSignal[1], Open[0], _longEntry));
                                  }
                              }
                          }​
      BTW: Is there a sample code to catch any of these errors, then cancel / close all orders but let the Strategy to continue and not disable it ?

      Thanks again !

      Comment


        #4
        OK. I might have celebrated to early.
        Now I have a similar issue with the exits.

        In a Buy i want to place a ExitLongLimit for TP and a ExitLongStopMarket for the SL, like this:

        Code:
                    if (Position.MarketPosition == MarketPosition.Long)
                    {
                        // Sell Limit Order for target profit
                        ExitLongLimit(1, _longTP, "Long_TP" + id, "Long_Entry");
                        // Sell Stop Order for stop loss
                        ExitLongStopMarket(1, _longSL, "Long_SL" + id, "Long_Entry");
                    }
        
                    if (Position.MarketPosition == MarketPosition.Short)
                    {
                        // Buy Limit Order for target profit
                        ExitShortLimit(1, _shortTP, "Short_TP", "Short_Entry");
                        // Buy Stop Order for stop loss
                        ExitShortStopMarket(1, _shortSL, "Short_SL", "Short_Entry");                    
                    }​
        First, I would like to make sure this is only called once after position is open. Otherwise its trying to update the exits on every tick.(not optimal)
        Second, I'm getting (once in a while) the same error with the entry "order rejected" after the SL is touched. In a Long the exit for SL would be a Sell Stop Market (ExitLongStopMarket)


        This is the code for OnOrderUpdate

        Code:
                protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
                {
                    // One time only, as we transition from historical
                    // Convert any old historical order object references to the live order submitted to the real-time account
                    if (myOrder != null && myOrder.IsBacktestOrder && State == State.Realtime)
                      myOrder = GetRealtimeOrder(myOrder);
                    
                    // check if the current order matches the orderName passed in "EnterLong"()
                    // Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
                    // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
                    if (order.Name == "Long_Entry" || order.Name == "Short_Entry")
                      myOrder = order;
                
                    // Null Entry order if filled or cancelled. We do not use the Order objects after the order is filled, so we can null it here
                    if (myOrder != null && myOrder == order)
                    {
                      if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                          myOrder = null;
                      if (order.OrderState == OrderState.Filled)
                          myOrder = null;
                    }        
                }​

        Comment


          #5
          Hello NM_eFe,

          When submitting a stop order, it is necessary to check the price of the order is a valid price.

          A buy stop order must have the stop price above the current ask (GetCurrentAsk()), a sell stop order must have the stop price below the current bid (GetCurrentBid()).​

          For the ExitLongStopMarket() call for the '"Long_SL" + id' order, ensure that the _longSL value is less than GetCurrentBid() one line above where the order method is called.
          For the ExitLongStopMarket() call for the '"Short_SL"' order, ensure that the _shortSL value is greater than GetCurrentAsk() one line above where the order method is called.


          "First, I would like to make sure this is only called once after position is open. Otherwise its trying to update the exits on every tick.(not optimal)"

          Then call this from OnPositionUpdate after the position is taken to the quantity you are wanting.


          "Second, I'm getting (once in a while) the same error with the entry "order rejected" after the SL is touched. In a Long the exit for SL would be a Sell Stop Market (ExitLongStopMarket)"

          See my comment at the start of this post.


          "This is the code for OnOrderUpdate​"

          You should have different variables for each order.

          You are assigning "Long_Entry" and "Short_Entry" both to myOrder. These should be separate variables holding separate orders.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #6
            Thank you, again ChelseaB!
            I had to do a huge rework on the code, but now I feel is much more robust.

            This is the new OnExecutionUpdate code, let me know if there is something OFF:
            Code:
                    protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
                    {
                        /* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate()
                        which ensures your strategy has received the execution which is used for internal signal tracking. */
                        if (myLongEntryOrder != null && myLongEntryOrder == 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
                                myLongSumFilled += execution.Quantity;
            
                                // Submit exit orders for partial fills
                                if (execution.Order.OrderState == OrderState.PartFilled)
                                {
                                    myLongStopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, _longSL, "MyLongStop", "myLongEntry");
                                    myLongTargetOrder = ExitLongLimit(0, true, execution.Order.Filled, _longTP, "MyLongTarget", "myLongEntry");
                                }
                                // 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 && myLongSumFilled == execution.Order.Filled)
                                {
                                    // Stop-Loss order for OrderState.Filled
                                    myLongStopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, _longSL, "MyLongStop", "myLongEntry");
                                    myLongTargetOrder = ExitLongLimit(0, true, execution.Order.Filled, _longTP, "MyLongTarget", "myLongEntry");
                                }
            
                                // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
                                if (execution.Order.OrderState != OrderState.PartFilled && myLongSumFilled == execution.Order.Filled)
                                {
                                    myLongEntryOrder = null;
                                    myLongSumFilled = 0;
                                }                    
                            }
                        }
                        
                        if (myShortEntryOrder != null && myShortEntryOrder == 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
                                myShortSumFilled += execution.Quantity;
            
                                // Submit exit orders for partial fills
                                if (execution.Order.OrderState == OrderState.PartFilled)
                                {
                                    myShortStopOrder = ExitShortStopMarket(0, true, execution.Order.Filled, _shortSL, "MyShortStop", "myShortEntry");
                                    myShortTargetOrder = ExitShortLimit(0, true, execution.Order.Filled, _shortTP, "MyShortTarget", "myShortEntry");
                                }
                                // 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 && myShortSumFilled == execution.Order.Filled)
                                {
                                    // Stop-Loss order for OrderState.Filled
                                    myShortStopOrder = ExitShortStopMarket(0, true, execution.Order.Filled, _shortSL, "MyShortStop", "myShortEntry");
                                    myShortTargetOrder = ExitShortLimit(0, true, execution.Order.Filled, _shortTP, "MyShortTarget", "myShortEntry");
                                }
            
                                // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
                                if (execution.Order.OrderState != OrderState.PartFilled && myShortSumFilled == execution.Order.Filled)
                                {
                                    myShortEntryOrder = null;
                                    myShortSumFilled = 0;
                                }                    
                            }
                        }            
                        
                    }​

            And here the OnOrderUpdate.
            I've commented out the if order state == Filled and assigning null to the entryorder var. I didn't feel this was ok in cases with partial fill. When should this be implemnted like that?

            Code:
                    protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
                    {
                        // One time only, as we transition from historical
                        // Convert any old historical order object references to the live order submitted to the real-time account
                        if (myLongEntryOrder != null && myLongEntryOrder.IsBacktestOrder && State == State.Realtime)
                          myLongEntryOrder = GetRealtimeOrder(myLongEntryOrder);
            
                        if (myShortEntryOrder != null && myShortEntryOrder.IsBacktestOrder && State == State.Realtime)
                          myShortEntryOrder = GetRealtimeOrder(myShortEntryOrder);
                                    
                        // check if the current order matches the orderName passed in "EnterLong"()
                        // Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
                        // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
                        if (order.Name == "myLongEntry")
                          myLongEntryOrder = order;
            
                        // Null Entry order if filled or cancelled. We do not use the Order objects after the order is filled, so we can null it here
                        if (myLongEntryOrder != null && myLongEntryOrder == order) // if long entry order exists
                        {
                            if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                            {
                                myLongEntryOrder = null;
                                myLongSumFilled = 0;
                            }
            //                  if (order.OrderState == OrderState.Filled)
            //                    myLongEntryOrder = null;
                        }    
            
                        if (order.Name == "myShortEntry")
                          myShortEntryOrder = order;            
                        
                        // Null Entry order if filled or cancelled. We do not use the Order objects after the order is filled, so we can null it here
                        if (myShortEntryOrder != null && myShortEntryOrder == order) // if short entry order exists
                        {
                            if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                            {
                                myShortEntryOrder = null;
                                myShortSumFilled = 0;
                            }
            //                if (order.OrderState == OrderState.Filled)
            //                    myShortEntryOrder = null;
                        }
                    }    ​

            Thanks again for all your help

            Comment


              #7
              Hello NM_eFe

              myLongStopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, _longSL, "MyLongStop", "myLongEntry");

              You are assigning order objects to variables from order method calls and not from the order object parameter provided from the OnOrderUpdate() override method.

              This will cause undesired and unexpected behavior.

              From the help guide:
              "OnOrderUpdate() will run inside of order methods such as EnterLong() or SubmitOrderUnmanaged(), therefore attempting to assign an order object outside of OnOrderUpdate() may not return as soon as expected. If your strategy is dependent on tracking the order object from the very first update, you should try to match your order objects by the order.Name (signal name) from during the OnOrderUpdate() as the order is first updated."


              Calling the order methods in OnExecutionUpdate() is fine. However, the variable assignment should be in the OnOrderUpdate() override method.

              Below is a link to the ProfitCasestopTrailExitOrdersExample which demonstrates properly assigning order objects to variables from OnOrderUpdate().



              Further, you are accumulating the part fills to a variable myLongSumFilled, but this is not being used for the quantity of the exit orders.
              With some brokerages like Rithmic and Interactive Brokers, the execution and order updates may not be in sequence. This means the execution.Order.Filled may not be up-to-date.
              I would recommend using myLongSumFilled as the exit order quantity instead.

              This thread discusses.
              Hello, I see in the documentation you have fixed: 15048 Added Adapter, Rithmic Updated Rithmic API to version 11.3.0.0 Can you elaborate on that please? Will OnOrderUpdate() OnExecutionUpdate() and OnPositionUpdate() be called in the expected order?
              Chelsea B.NinjaTrader Customer Service

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by sofortune, Today, 10:55 PM
              0 responses
              2 views
              0 likes
              Last Post sofortune  
              Started by sofortune, Today, 10:19 PM
              0 responses
              9 views
              0 likes
              Last Post sofortune  
              Started by sofortune, Today, 10:10 PM
              0 responses
              6 views
              0 likes
              Last Post sofortune  
              Started by sofortune, Today, 09:49 PM
              0 responses
              4 views
              0 likes
              Last Post sofortune  
              Started by trader_by_day, Today, 09:37 PM
              1 response
              12 views
              0 likes
              Last Post NinjaTrader_Manfred  
              Working...
              X