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

formulating a "barsAgo" index that works for both Calculate OnBarClose and OnEachTick

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

    formulating a "barsAgo" index that works for both Calculate OnBarClose and OnEachTick

    I'm trying to figure out how to use the NT API to provide the correct bar index to reference the last closing bar such that the script will automatically use index 0 or index 1 depending on Calculate mode chosen by the user.

    Code:
                int barsAgo = Calculate == Calculate.OnBarClose || State == State.Historical ? 0 : 1;
    
    
                if (IsFirstTickOfBar)
                {
                    if (Close[barsAgo] > High[barsAgo + 1])
                        ExitLong();
    
                    if (Time[0].Date == new DateTime(2020,04,15).Date)
                        EnterLong();
                }

    In the above example the script tries to get the right bar index to use based on how the script is being run. It runs as expected for Calculate == OnBarClose but for Calculate == OnPriceChange, barsAgo == 0 when I expect barsAgo == 1.
    When running on Calculate == OnPriceChange and starting the strategy the backfll logic processes and when the OnBarUpdate is called for the last bar on the chart the State == Historical and IsFirstTickOfBar is true. But I'm starting the strategy in the middle of the formation of this last bar. I expected that IsFirstTickOfBar should be false.

    THE TEST SCRIPT ATTACHED:
    AtsSampleStrategy.zip

    I run the script on the ES 06-20 1440 minute bars, CME US Index Futures ETH.
    Set MarketReplay to 4/17/2020 midnight.

    This simple script enters long on 4/15/2020 then looks for a close higher than the prior day high. The bar time stamped 4/17/2020 meets this criteria.

    With Calculate == OnBarClose the exit order is submitted at the close of the 4/17 bar as expected.
    With Calculate == OnPriceChange the exit order is submitted before the 4/17 bar closes. Because of the afformentioned problem the script calls ExitLong. I would have expected that the result of this unwanted call would take the strategy to flat but it does not. An order is submitted however and the a short position in the sim account while the strategy remains in the long position. This is a secondary issue .

    I test with Market Replay and set the time to 4/17/2020 which begins at midnight and the 4/17 bar has already started to form.

    I expect that there's some way to write a formula to create a barsAgo value that will be correct for both OnBarClose and OnEachTick/OnPriceChange. I just don't know how. Is there a way?


    AtsSampleStrategy.zip


    #2
    Hello Brillo,

    IsFirstTickOfBar is true on the first tick received after a bar is open. If the first tick received is halfway after the bar is built then it will still be true halfway after the bar is built.

    With TickReplay, however, this would add in that tick data needed to process the historical ticks, such as the ones at the beginning of the bar before the script was enabled and processing real-time ticks.

    Do you have TickReplay enabled?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hi Chelsea, No I don't have tick replay enabled.

      Comment


        #4
        Hello Brillo,

        Without TickReplay enabled, the first tick of the bar will be the first tick received after the script is enabled or data is loaded even if this is mid bar.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Here's a link to a video that demonstrates the issue. Thought it might help:

          Comment


            #6
            Originally posted by NinjaTrader_ChelseaB View Post
            Hello Brillo,

            Without TickReplay enabled, the first tick of the bar will be the first tick received after the script is enabled or data is loaded even if this is mid bar.
            Okay. I tried using TickReplay to see if I could get it to work but I can't. Anyway, I can not use TickReplay for most of my work. I'm loading a lot of historical bars.

            Is there anyway to achieve calculating an index that works properly for both OnBarClose and OnEachTick/OnPriceChange?

            The need for this that a strategy that uses a realtime indicator on a chart so that the user can see when a signal is coming that the strategy might act on. This means the strategy must run OnPriceChange/OnEachTick to drive the indicator to update while bars are forming and do it's "before the end of bar thing". If running OnBarClose the strategy will run fine but the user won't see the indication until the next bar opens right when the strategy is already submitting an order.

            The only way around is for the strategy to NOT add the indicator to the chart and the user has to add the indicator CONFIGURED THE SAME EXACT WAY to the chart. Run the indicator OnEachTick/OnPriceChange and run the strategy OnBarClose, But keepting the settings synchronized gets confusing and consequently I want to provide a strategy that adds all the real time indicators itself using the parameters given to the strategy so they're sure to be matching.

            Comment


              #7
              Originally posted by NinjaTrader_ChelseaB View Post
              Hello Brillo,

              Without TickReplay enabled, the first tick of the bar will be the first tick received after the script is enabled or data is loaded even if this is mid bar.
              By the way, State == State.Historical even when the 1st tick comes in for the last bar mid bar. So we have IsFirstTickOfBar == true and State == State.Historical in the middle of the last bar. The script thinks it's historical and uses bars index 0. Is there any property that tells us if the in coming tick is the last expected bar ( for now )?

              Comment


                #8
                Hello Brillo,

                IsFirstTickOfBar is always true in historical data unless TickReplay is enabled.

                Simularly, Calculate.OnEachTick or .OnPriceChange do not work in historical data unless TickReplay is enabled.

                If you are only concerned with real-time, you can ensure the State is State.Real-time before using IsFirstTickOfBar.
                You could also wait for the second real-time bar if you want to get in when the bar opens.

                If you want the most recently closed bar while the current bar is building this would be an index of [1] when in real-time and Calculate is .OnEachTick or .OnPriceChange.
                Without TickReplay IsFirstTickOfBar, Calculate.OnEachTick, and Calculate.OnPriceChange will not function. Use a [0] when in historical data for the most recently closed bar.,
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Originally posted by NinjaTrader_ChelseaB View Post
                  IsFirstTickOfBar is always true in historical data unless TickReplay is enabled.
                  Simularly, Calculate.OnEachTick or .OnPriceChange do not work in historical data unless TickReplay is enabled.




                  Yes, understood while trying to achieve this.




                  Originally posted by NinjaTrader_ChelseaB View Post
                  If you are only concerned with real-time, you can ensure the State is State.Real-time before using IsFirstTickOfBar.
                  You could also wait for the second real-time bar if you want to get in when the bar opens.
                  I'm not only concerned with realtime. We need the historical bars to process as they normally do: OnBarClose oriented behavior is fine for the historical backfill. But when the system transitions to real time then we want the indicators driven by the strategy to run in real time. Simply stated this way it's working. The problem is that we have to use bar index 0 or bar index 1 depending on whether we're receiving ticks for last bar (regardless of whether those ticks are part of historical backfill or not) of the chart but there is no way to know this.

                  Originally posted by NinjaTrader_ChelseaB View Post
                  If you want the most recently closed bar while the current bar is building this would be an index of [1] when in real-time and Calculate is .OnEachTick or .OnPriceChange.
                  ... Use a [0] when in historical data for the most recently closed bar.,


                  The problem with this is that State is NOT State == State.Realtime while the last bar is building until after historical back filling is complete. So when starting a strategy in the middle of this LAST bar historical backfill is occurring and we're in State == State.Historical.

                  Restating the problem briefly:
                  Running a realtime strategy what bar index to use for hosted indicators for which we want the last complete bar: 0 or 1? Guidance from NT is to use 0 for the historical bars and 1 for the last real time bar. ( ie, For the historical bars use 0 and for ANY tick in the last, realtime bar, use 1 ). The problem is that NT has not provided a way to determine if we are receiving ticks on the last bar so that we can make the index to be 1. Can not use TickReplay so that can't be part of the solution.

                  I have tried this:

                  int barsAgo = Calculate == Calculate.OnBarClose || State == State.Historical ? 0 : 1;

                  This says if Calculate == State.Historical OR State == State.Historical set barsAgo to 0 otherwise set it to 1;

                  Then barsAgo could drive the indicators hosted by the strategy like this: myIndicator.MySignal[barsAgo]

                  But the problem is that the first ticks coming in for the last bar are also State == State.Historical and so barsAgo is getting set to be 0 when guidance from NT is to set it to 1 for a real time bar.

                  If there's a way to know if the ticks are for the last bar then the formula could be written:
                  int barsAgo = Calculate == Calculate.OnBarClose || "NOT LAST BAR" ? 0 : 1;

                  Any way to know if the historical ticks are for the last bar would suffice.

                  Last edited by Brillo; 04-22-2020, 08:43 AM.

                  Comment


                    #10
                    Hello Brillo,

                    If this is needed for historical bars, the tool to achieve this would be TickReplay. This would allow the historical ticks to process and would allow IsFirstTickOfBar to work historically.

                    In historical data you can find the last fully closed bar with if (State == State.Historical && CurrentBar == Count - 2). (The count will continuously increase in real-time so this only works for historical)
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Chelsea, This is exactly what's needed to fix the problem. It takes a little doing but I've been able to get this to work.

                      Code:
                      // this is a field in the class ( a member of the Strategy object ):
                      [LEFT][COLOR=#4D4D4D][FONT=Helvetica][SIZE=13px]        int LastHistoricalBar = int.MaxValue;
                      
                      // In OnBarUpdate[/SIZE][/FONT][/COLOR][/LEFT]
                      
                                  if (State == State.Historical && CurrentBar == Count - 2)
                                      LastHistoricalBar = CurrentBar;
                      
                                  int barsAgo = Calculate == Calculate.OnBarClose || CurrentBar <= LastHistoricalBar ? 0 : 1;
                      
                                  if (CurrentBar <= LastHistoricalBar || (IsFirstTickOfBar && CurrentBar >= LastHistoricalBar))
                                  {
                      // some entry logic: barsAgo is either 0 or 1 as needed.
                                      if (Close[[B]barsAgo[/B]] > High[[B]barsAgo[/B] + 1])
                                          ExitLong("LX", "LE");
                      // some exit logic. barsAgo is either 0 or 1 as needed
                                      if (Time[[B]barsAgo[/B]].Date == new DateTime(2020, 04, 15).Date)
                                          EnterLong(1, "LE");
                                  }
                      With this a strategy can run with Calculate == Calculate.OnPriceChange ( or Calculate.OnEachTick ), without TickReplay, drive it's hosted indicators in real time so they update on the screen for the user, while the strategy itself will only execute it's logic on the close of each bar and execute properly on all of it's historical bars with bar index 0 and then transition to realtime and use bar index 1 for the realtime to properly reference only closed bars.

                      I have attached the sample as well as a video.
                      AtsSampleStrategy.2020-04-22.zip

                      There is a side effect that's maybe a small bug in NT. When restarting the strategy while it's still forming the bar who's first tick caused the order to be placed, the strategy properly shows the historical order in the Strategy tab in Control Center but it does not show in the chart. If you then wait until this bar completes and restart the strategy then the chart marker is there. You'll see in the video.

                      Thanks so much for this. I think NT should formally create something built into the scriptbase so that the user community can use this easily.

                      Comment


                        #12
                        Hello Brillo,

                        This request is being tracked with ID# SFT-4806.

                        As with all feature requests, interest is tracked before implementation is considered, so we cannot offer an ETA or promise of fulfillment. If implemented, it will be noted in the Release Notes page of the Help Guide.

                        Release Notes — https://ninjatrader.com/support/help...ease_notes.htm
                        Chelsea B.NinjaTrader Customer Service

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by pechtri, 06-22-2023, 02:31 AM
                        9 responses
                        122 views
                        0 likes
                        Last Post NinjaTrader_ChelseaB  
                        Started by frankthearm, 04-18-2024, 09:08 AM
                        16 responses
                        65 views
                        0 likes
                        Last Post NinjaTrader_Clayton  
                        Started by habeebft, Today, 01:18 PM
                        1 response
                        5 views
                        0 likes
                        Last Post NinjaTrader_ChelseaB  
                        Started by benmarkal, Today, 12:52 PM
                        2 responses
                        13 views
                        0 likes
                        Last Post benmarkal  
                        Started by f.saeidi, Today, 01:38 PM
                        1 response
                        7 views
                        0 likes
                        Last Post NinjaTrader_BrandonH  
                        Working...
                        X