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

2 entry orders help!

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

    Hello bobperez,

    A few modifications would be necessary.

    Lines 138 to 145 where the entries are being submitted in OnMarketData(), this would need to be moved to OnBarUpdate().

    Then entry conditions (currently line 138) would need time conditions added.

    if (longStopEntry == null && shortStopEntry == null && ToTime(Time[0]) == 93800)

    Below is a link to an example of time conditions.
    Chelsea B.NinjaTrader Customer Service

    Comment


      Originally posted by NinjaTrader_ChelseaB View Post
      Hello bobperez,

      A few modifications would be necessary.

      Lines 138 to 145 where the entries are being submitted in OnMarketData(), this would need to be moved to OnBarUpdate().

      Then entry conditions (currently line 138) would need time conditions added.

      if (longStopEntry == null && shortStopEntry == null && ToTime(Time[0]) == 93800)

      Below is a link to an example of time conditions.
      https://ninjatrader.com/support/help...to_limit_t.htm
      Hi Chelsea,

      I followed your suggestion, and it fills the order on the next bar, instead of placing the oco order on the desired bar.

      Code:
      protected override void OnBarUpdate()
      {
      
      if ( (longStopEntry == null && shortStopEntry == null )
      && ((ToTime(Time[0]) == 82900 )
      || (ToTime(Time[0]) == 113000 )
      || (ToTime(Time[0]) == 113800 )
      || (ToTime(Time[0]) == 142000 )
      )
      )
      
      {
      ocoString = string.Format("unmanagedentryoco{0}", DateTime.Now.ToString("hhmmssffff"));
      longStopEntry = SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.Limit, 1, 0, (High[0] + 2 * TickSize), ocoString, "longStopEntry");
      shortStopEntry = SubmitOrderUnmanaged(0, OrderAction.SellShort, OrderType.Limit, 1, 0, (Low[0] - 2 * TickSize), ocoString, "shortStopEntry");
      
      
      }
      
      
      }
      Click image for larger version  Name:	Captura20240311.jpg Views:	0 Size:	22.3 KB ID:	1295241
      Last edited by bobperez; 03-11-2024, 12:59 PM.

      Comment


        Hello bobperez,

        When NinjaTrader is running with Calculate set to OnBarClose, orders are placed after the bar closes using logic calculated from that bar.

        Below is a link to the help guide on the Calculate property.


        This means that any orders that are triggered from that bar are submitted after the bar closes as the new bar opens. As the order is placed as the new bar opens and the timestamp of the order is within the time of the next bar, the order will show on the next bar.

        If the strategy were running with Calculate as OnPriceChange or OnEachTick, or if the script has intra-bar granularity and submitted orders on a smaller timeframe, this would cause the timestamp of the order to be within the bar it is triggered on as the order may be submitted intra-bar. This order would show on the same bar as the bar that triggered the order submission.

        In historical data, Calculate will always be OnBarClose unless TickReplay is enabled for the data series.

        Further, TickReplay cannot be used for intra-bar order fills. A 1 tick series must be added for 1-tick intra-bar granularity to increase the accuracy of order fills to the price and time of a specific tick.
        This is outlined in the help guide Discrepancies: Real-Time vs Backtest.


        Also, below is a link to a forum thread about intra-bar granularity.
        http://ninjatrader.com/support/forum...297#post491297
        Chelsea B.NinjaTrader Customer Service

        Comment


          Originally posted by NinjaTrader_ChelseaB View Post
          Hello bobperez,

          When NinjaTrader is running with Calculate set to OnBarClose, orders are placed after the bar closes using logic calculated from that bar.

          Below is a link to the help guide on the Calculate property.


          This means that any orders that are triggered from that bar are submitted after the bar closes as the new bar opens. As the order is placed as the new bar opens and the timestamp of the order is within the time of the next bar, the order will show on the next bar.

          If the strategy were running with Calculate as OnPriceChange or OnEachTick, or if the script has intra-bar granularity and submitted orders on a smaller timeframe, this would cause the timestamp of the order to be within the bar it is triggered on as the order may be submitted intra-bar. This order would show on the same bar as the bar that triggered the order submission.

          In historical data, Calculate will always be OnBarClose unless TickReplay is enabled for the data series.

          Further, TickReplay cannot be used for intra-bar order fills. A 1 tick series must be added for 1-tick intra-bar granularity to increase the accuracy of order fills to the price and time of a specific tick.
          This is outlined in the help guide Discrepancies: Real-Time vs Backtest.


          Also, below is a link to a forum thread about intra-bar granularity.
          http://ninjatrader.com/support/forum...297#post491297
          Thank you, Chelsea,

          I added the intrabar granularity as shown on the video link you sent. Still, I must be doing something wrong as the oco order does not appear and the fill is not where the script requires it to be.

          The attached file includes the time modifications and added data series.
          BobPerez
          Attached Files

          Comment


            Hello bobperez,

            Are you running the script with Calculate set to OnPriceChange / or OnEachTick in the strategy parameters window?
            Is TickReplay enabled?
            Chelsea B.NinjaTrader Customer Service

            Comment


              Originally posted by NinjaTrader_ChelseaB View Post
              Hello bobperez,

              Are you running the script with Calculate set to OnPriceChange / or OnEachTick in the strategy parameters window?
              Is TickReplay enabled?
              Yes. Both are set. I also modified the order submission and exit commands on the OnExecutionUpdate method to manage the order with the 1 tick bar:
              Code:
               SubmitOrderUnmanaged(1, OrderAction.Sell, OrderType.Limit, 1, (High[0] + 20 * TickSize), 0, ocoString, "longProfitTarget");
              ,
              Last edited by bobperez; 03-11-2024, 01:49 PM.

              Comment


                Hello bobperez,

                Can you print the bar time from inside of the entry condition in OnBarUpdate() and print the order.ToString() object in OnOrderUpdate(), then post the output text file?

                I just want to confirm we are seeing multiple updates for the bar on each price change in OnBarUpdate() and that the order is being submitted immediately.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  Originally posted by NinjaTrader_ChelseaB View Post
                  Hello bobperez,

                  Can you print the bar time from inside of the entry condition in OnBarUpdate() and print the order.ToString() object in OnOrderUpdate(), then post the output text file?

                  I just want to confirm we are seeing multiple updates for the bar on each price change in OnBarUpdate() and that the order is being submitted immediately.
                  Chelsea,

                  Code:
                          protected override void OnBarUpdate()
                          {
                              
                              if ( (longStopEntry == null && shortStopEntry == null )        
                                  && ((ToTime(Time[0]) == 82900 )
                                  ||    (ToTime(Time[0]) == 113000 )
                                  || (ToTime(Time[0]) == 113800 )
                                  ||    (ToTime(Time[0])  == 142000 )
                                  )
                                  )                
                                  
                              {
                                  ocoString        = string.Format("unmanagedentryoco{0}", DateTime.Now.ToString("hhmmssffff"));
                                  longStopEntry    = SubmitOrderUnmanaged(1, OrderAction.Buy, OrderType.Limit, 1, 0, (High[0] + 2 * TickSize), ocoString, "longStopEntry");
                                  shortStopEntry    = SubmitOrderUnmanaged(1, OrderAction.SellShort, OrderType.Limit, 1, 0, (Low[0] - 2 * TickSize), ocoString, "shortStopEntry");
                                  
                                  Print(Time[0]+ " From OnBarUpdate after order submission" );
                              }
                                  
                          
                          }
                  Attached Files

                  Comment


                    Hello bobperez,

                    I'm seeing that the first two orders were submitted at 8:29. These were limit orders, and not market orders, so may not fill immediately and may fill at a later time when the limit price is reached.

                    2024-03-01 8:29:00 AM order.ToString()orderId='NT-00000-1378' account='Sim101' name='longStopEntry' orderState=Submitted instrument='CL 04-24' orderAction=Buy orderType='Limit' limitPrice=0 stopPrice=79.79 quantity=1 tif=Gtc oco='unmanagedentryoco0639187450' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2024-03-01 08:28:59' gtd='2099-12-01' statementDate='2024-03-11'

                    2024-03-01 8:29:00 AM order.ToString()orderId='NT-00001-1378' account='Sim101' name='shortStopEntry' orderState=Submitted instrument='CL 04-24' orderAction=SellShort orderType='Limit' limitPrice=0 stopPrice=79.72 quantity=1 tif=Gtc oco='unmanagedentryoco0639187450' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2024-03-01 08:28:59' gtd='2099-12-01' statementDate='2024-03-11'​

                    Is the issue that the orders are being submitted at the correct time but are not filling until a later bar due to being limit orders and not market orders?


                    I should have had you put the print in a separate condition for the time, so we can see this print for each bar update at that time, and see if there are more bar updates after the order is submitted.

                    Code:
                    if  ((ToTime(Time[0]) == 82900 )
                    || (ToTime(Time[0]) == 113000 )
                    || (ToTime(Time[0]) == 113800 )
                    || (ToTime(Time[0]) == 142000 )
                    )
                    )
                    
                    {
                    Print(Time[0]+ " bar update" );
                    }​
                    
                    if ( (longStopEntry == null && shortStopEntry == null )
                    && ((ToTime(Time[0]) == 82900 )
                    || (ToTime(Time[0]) == 113000 )
                    || (ToTime(Time[0]) == 113800 )
                    || (ToTime(Time[0]) == 142000 )
                    )
                    )
                    
                    {
                    ocoString = string.Format("unmanagedentryoco{0}", DateTime.Now.ToString("hhmmssffff"));
                    longStopEntry = SubmitOrderUnmanaged(1, OrderAction.Buy, OrderType.Limit, 1, 0, (High[0] + 2 * TickSize), ocoString, "longStopEntry");
                    shortStopEntry = SubmitOrderUnmanaged(1, OrderAction.SellShort, OrderType.Limit, 1, 0, (Low[0] - 2 * TickSize), ocoString, "shortStopEntry");
                    
                    Print(Time[0]+ " From OnBarUpdate after order submission" );
                    }
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      Originally posted by NinjaTrader_ChelseaB View Post
                      Hello bobperez,

                      I'm seeing that the first two orders were submitted at 8:29. These were limit orders, and not market orders, so may not fill immediately and may fill at a later time when the limit price is reached.

                      2024-03-01 8:29:00 AM order.ToString()orderId='NT-00000-1378' account='Sim101' name='longStopEntry' orderState=Submitted instrument='CL 04-24' orderAction=Buy orderType='Limit' limitPrice=0 stopPrice=79.79 quantity=1 tif=Gtc oco='unmanagedentryoco0639187450' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2024-03-01 08:28:59' gtd='2099-12-01' statementDate='2024-03-11'

                      2024-03-01 8:29:00 AM order.ToString()orderId='NT-00001-1378' account='Sim101' name='shortStopEntry' orderState=Submitted instrument='CL 04-24' orderAction=SellShort orderType='Limit' limitPrice=0 stopPrice=79.72 quantity=1 tif=Gtc oco='unmanagedentryoco0639187450' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2024-03-01 08:28:59' gtd='2099-12-01' statementDate='2024-03-11'​

                      Is the issue that the orders are being submitted at the correct time but are not filling until a later bar due to being limit orders and not market orders?


                      I should have had you put the print in a separate condition for the time, so we can see this print for each bar update at that time, and see if there are more bar updates after the order is submitted.

                      Code:
                      if ((ToTime(Time[0]) == 82900 )
                      || (ToTime(Time[0]) == 113000 )
                      || (ToTime(Time[0]) == 113800 )
                      || (ToTime(Time[0]) == 142000 )
                      )
                      )
                      
                      {
                      Print(Time[0]+ " bar update" );
                      }​
                      
                      if ( (longStopEntry == null && shortStopEntry == null )
                      && ((ToTime(Time[0]) == 82900 )
                      || (ToTime(Time[0]) == 113000 )
                      || (ToTime(Time[0]) == 113800 )
                      || (ToTime(Time[0]) == 142000 )
                      )
                      )
                      
                      {
                      ocoString = string.Format("unmanagedentryoco{0}", DateTime.Now.ToString("hhmmssffff"));
                      longStopEntry = SubmitOrderUnmanaged(1, OrderAction.Buy, OrderType.Limit, 1, 0, (High[0] + 2 * TickSize), ocoString, "longStopEntry");
                      shortStopEntry = SubmitOrderUnmanaged(1, OrderAction.SellShort, OrderType.Limit, 1, 0, (Low[0] - 2 * TickSize), ocoString, "shortStopEntry");
                      
                      Print(Time[0]+ " From OnBarUpdate after order submission" );
                      }
                      Hello Chelsea,

                      I expect to place only one oco order per each time bar, at the High[0]+2 ticks and Low[0]-2 ticks. There should only be a total of 4 orders, one for each bar. So, on bar 8:29, the oco order should be placed immediately after the bar closes, when its final high and low are known.
                      Attached Files

                      Comment


                        Hello bobperez,

                        The orders are being submitted while the bar is still open, are you wanting to wait until after the bar has closed to submit the orders?

                        In this output what is the behavior you are seeing that is incorrect?
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          Originally posted by NinjaTrader_ChelseaB View Post
                          Hello bobperez,

                          The orders are being submitted while the bar is still open, are you wanting to wait until after the bar has closed to submit the orders?

                          In this output what is the behavior you are seeing that is incorrect?
                          Hi Chelsea,

                          I expect a behavior similar to your plain example. The orders should be placed about 2-3 ticks above/below the bars, instead of 15 ticks as you have in your example. They should be submitted when the timed bar closes to identify its final High/Low.

                          Comment


                            Hello bobperez,

                            If you want to wait until after the bar closes to submit the order using the high and low values of the previous fully closed bar while Calculate is OnPriceChange and TickReplay is enabled, do this when IsFirstTickOfBar is true and use 1 bar ago indexes.

                            Code:
                            if (IsFirstTickOfBar)
                            {
                            int barsAgoIndex = Calculate != Calculate.OnBarClose && (State == State.Realtime || (State == State.Historical && BarsArray[0].IsTickReplay)) ? 1 : 0;
                            Print(string.Format("{0} | barsAgoIndex selected: {1}, {2}, High[{1}]: {3}, Low[{1}]: {4}", Time[0], barsAgoIndex, Time[barsAgoIndex], High[barsAgoIndex], Low[barsAgoIndex]));
                            }
                            Chelsea B.NinjaTrader Customer Service

                            Comment


                              Originally posted by NinjaTrader_ChelseaB View Post
                              Hello bobperez,

                              If you want to wait until after the bar closes to submit the order using the high and low values of the previous fully closed bar while Calculate is OnPriceChange and TickReplay is enabled, do this when IsFirstTickOfBar is true and use 1 bar ago indexes.

                              Code:
                              if (IsFirstTickOfBar)
                              {
                              int barsAgoIndex = Calculate != Calculate.OnBarClose && (State == State.Realtime || (State == State.Historical && BarsArray[0].IsTickReplay)) ? 1 : 0;
                              Print(string.Format("{0} | barsAgoIndex selected: {1}, {2}, High[{1}]: {3}, Low[{1}]: {4}", Time[0], barsAgoIndex, Time[barsAgoIndex], High[barsAgoIndex], Low[barsAgoIndex]));
                              }
                              Hi Chelsea,

                              Great! Thank you!

                              Comment


                                Originally posted by NinjaTrader_ChelseaB View Post
                                Hello bobperez,

                                If you want to wait until after the bar closes to submit the order using the high and low values of the previous fully closed bar while Calculate is OnPriceChange and TickReplay is enabled, do this when IsFirstTickOfBar is true and use 1 bar ago indexes.

                                Code:
                                if (IsFirstTickOfBar)
                                {
                                int barsAgoIndex = Calculate != Calculate.OnBarClose && (State == State.Realtime || (State == State.Historical && BarsArray[0].IsTickReplay)) ? 1 : 0;
                                Print(string.Format("{0} | barsAgoIndex selected: {1}, {2}, High[{1}]: {3}, Low[{1}]: {4}", Time[0], barsAgoIndex, Time[barsAgoIndex], High[barsAgoIndex], Low[barsAgoIndex]));
                                }
                                Hi Chelsea,

                                Here's what I interpreted from your suggestion. With this code, the chart freezes, and I have to force Ninjja to shut down with Ctr+Alt+Del.




                                Code:
                                            if ( (longStopEntry == null && shortStopEntry == null && IsFirstTickOfBar )        
                                                && ((ToTime(Time[0]) == 82900   )
                                                ||    (ToTime(Time[0]) == 113000  )
                                                ||  (ToTime(Time[0]) == 113800  )
                                                ||    (ToTime(Time[0])  == 142000 )
                                                )
                                                )                
                                                
                                            {
                                                int barsAgoIndex = Calculate != Calculate.OnBarClose && (State == State.Realtime || (State == State.Historical && BarsArray[0].IsTickReplay)) ? 1 : 0;
                                                Print(string.Format("{0} | barsAgoIndex selected: {1}, {2}, High[{1}]: {3}, Low[{1}]: {4}", Time[0], barsAgoIndex, Time[barsAgoIndex], High[barsAgoIndex], Low[barsAgoIndex]));
                                                ocoString        = string.Format("unmanagedentryoco{0}", DateTime.Now.ToString("hhmmssffff"));
                                                longStopEntry    = SubmitOrderUnmanaged(1, OrderAction.Buy, OrderType.Limit, 1, 0, (High[barsAgoIndex] + 4 * TickSize), ocoString, "longStopEntry");
                                                shortStopEntry    = SubmitOrderUnmanaged(1, OrderAction.SellShort, OrderType.Limit, 1, 0, (Low[barsAgoIndex] - 4 * TickSize), ocoString, "shortStopEntry");
                                                
                                            }
                                                
                                ​
                                BobPerez
                                Last edited by bobperez; 03-12-2024, 02:15 PM.

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by llanqui, Today, 03:53 AM
                                0 responses
                                4 views
                                0 likes
                                Last Post llanqui
                                by llanqui
                                 
                                Started by burtoninlondon, Today, 12:38 AM
                                0 responses
                                10 views
                                0 likes
                                Last Post burtoninlondon  
                                Started by AaronKoRn, Yesterday, 09:49 PM
                                0 responses
                                14 views
                                0 likes
                                Last Post AaronKoRn  
                                Started by carnitron, Yesterday, 08:42 PM
                                0 responses
                                11 views
                                0 likes
                                Last Post carnitron  
                                Started by strategist007, Yesterday, 07:51 PM
                                0 responses
                                14 views
                                0 likes
                                Last Post strategist007  
                                Working...
                                X