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

Print Close[0] prints the close price of the 2nd last bar instead of the last

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

    Print Close[0] prints the close price of the 2nd last bar instead of the last

    Hi,

    Please see the following example and help me understand why is this happening?

    The last 2 bars on the daily AAPL Chart show the last 2 day's Close prices as follows:
    1/12/2021 164.77
    2/12/2021 163.76

    If I was to have a simple script that just says...

    Print(Close[0]);

    It prints 164.77 as the last closing price in the output window instead of 163.76
    Why is this so? Am I able to get it to print the actual last date/bar's closing price 163.76?

    I have added a screenshot and circled what price I should be getting.


    Thank you
    Attached Files

    #2
    Hello ShayeAus,

    Thanks for your post.

    If you create a NinjaScript that calls Print(Cose[0]); and run the script with a Calculate mode of Calculate.OnBarClose, the script will calculate values only at the close of a bar. This means that when one bar closes and a new bar begins to form, the print will display for the recently closed bar and not the current bar Close price.

    If you would like to have the current bar Close price print out, you would need to run the script with a Calculate mod of Calculate.OnPriceChange or Calculate.OnEachTick. See the help guide page below for more information about Calculate.

    Calculate: https://ninjatrader.com/support/help.../calculate.htm

    Let us know if we may assist further.

    Brandon H.NinjaTrader Customer Service

    Comment


      #3
      Hi Brandon,

      Thank you for your reply.

      I've tried OnPriceChange but I'm guessing that it's not working as I'm running a Backtest using historical end of day data.

      So what you're saying is that even though the Close for 2/12/21 has already passed and can be clearly seen on the chart, I'm not able to get this value to print out?
      When running strategies using Strategy Builder does it not use the current bar Close price (which is the last bar? which would be dated 2/12/21?)



      Cheers,
      ShayeAus

      Comment


        #4
        Hello ShayeAus,

        Thanks for your post.

        If you are backtesting the script then the script will only calculate with Calculate.OnBarClose.

        When in historical data, only the Open, High, Low, and Close will be available and there will be no intra-bar data. This means actions cannot happen intra-bar, fills cannot happen intra-bar. All prices and actions come from and occur when the bar closes as this is all the information that is known.

        Because of this, OnBarUpdate will only update 'On bar close' as it does not have the intra-bar information necessary for 'On price change' or 'On each tick' and the script will not have the intra-bar information to accurately fill an order at the exact price and time.

        If the current bar on the chart is for 2/12/21 and you are running Calculate.OnBarClose, the strategy will not process this bar until it has closed and a new bar begins forming. To have the script print out a Close value for the current bar, Calculate.OnPriceChange or Calculate.OnEachTick would need to be used.

        Please review the help guide document on the differences on real-time vs backtest (historical).
        http://ninjatrader.com/support/helpG...ime_vs_bac.htm

        Let us know if we may assist further.
        Brandon H.NinjaTrader Customer Service

        Comment


          #5
          Originally posted by ShayeAus View Post
          Why is this so? Am I able to get it to print the actual last date/bar's closing price 163.76?
          You can't get the closing price of the bar until the bar actually closes, silly.

          Oh, you want to see this closing price as the bar is built, before it closes?

          [EDIT: The Strategy Analyzer won't support this directly, historical bars don't
          have the extra data to show 'real-time' changes -- so it always runs your
          Strategy using Calculate.OnBarClose. The Calculate setting only really
          shines when used with real-time data.]

          Well, as Brandon says, don't use Calculate.OnBarClose.

          [EDIT: Since you're dealing with daily bars, you have some additional choices,
          such as GetDayBar and CurrentDayOHL -- but the Close price of the current daily
          bar is a real-time thing, and won't be finalized until end of day. You can get the
          current real-time last price of the bar as the bar is being built -- the easiest way
          to do that is via a trick of the Calculate property.]

          What does Calculate do?

          The Calculate property controls the sense of what Close[0] means. It also
          dictates how often your OnBarUpdate() is called.

          There are 3 settings,
          • Calculate.OnBarClose <-- this is the default
          • Calculate.OnEachTick
          • Calculate.OnPriceChange
          OnBarClose means every Close[0] reflects the price of the most recently
          closed bar -- so, if you want the current close price of the active bar currently
          being built
          , you'll have to get that by other means (or don't use OnBarClose).

          OnEachTick means every Close[0] reflects every tick price movement for the
          active bar currently being built
          . If you want the close price of the most recently
          closed bar, it's available -- the indexes have all been shifted back by one --
          at Close[1].

          OnPriceChange is the same as OnEachTick, except if the tick price coming
          in from the data feed is same price as the last tick, OnPriceChange does nothing.

          See that?
          It's subtle -- but the sense of what Close[0] means depends upon the Calculate
          setting.

          People also get confused by OnEachTick vs OnPriceChange. OnPriceChange
          means you don't care about 26 ticks in a row coming in at the same price, you
          only care about when the tick price has changed. OnEachTick means you get to
          see each and every tick, even if the price hasn't changed.

          In your case, either OnEachTick and OnPriceChange should give you what you
          want -- which is the current real-time close price of the daily bar under construction.

          Ok, but why is that same price distinction important?
          One word: volume.

          Because ticks have volume. Even if the price is the same, each tick will contain
          volume information -- if knowing this volume on a tick by tick basis for the active bar
          currently being built
          is important, well then, OnEachTick is your man, and your
          OnBarUpdate() is called for each and every tick.

          [EDIT: This may be important to you, if say, you're writing a volume based indicator,
          such as a volume profile.]

          If volume is not a big deal, but you still want to see the tick price as it changes for
          the active bar currently being built, then use OnPriceChange. Your OnBarUpdate()
          only gets called if the tick price is different.

          [EDIT: Most indicators are associated with price, not volume. These are indicators
          where OnEachTick vs OnPriceChange doesn't change the plotting.]

          If the real-time prices associated with the active bar currently being built is not
          a big deal, because you only wish to deal with bars that have closed, then use the
          default setting OnBarClose. This means your OnBarUpdate() will be called less
          often (a lot less often), because it only gets called on the first tick of the new bar.

          Huh? Wait a minute ... what?
          Why does OnBarClose mean OnBarUpdate() is called on first tick of the new bar?
          How come it's not called on the last tick of the current bar?

          Good question.
          Because NinjaTrader supports many different bar types, that's why. If your mind
          says 'last tick of the current bar', you're thinking about time-based bars -- and yes,
          this would be possible to do.

          But what about Renko, or Range, or Volume bars?
          How do you know when the last tick has arrived for those bars?

          You don't necessarily know you're on the last tick while you're on it. These bar
          types are defined by knowing when the next tick must start a new bar.

          Well, it turns out that if you define each new bar by the arrival of its first tick,
          you've solved that problem for each and every bar type, for all time. That's
          why the bar close event actually takes place on the first tick of the new bar,
          to make the code easier and more consistent for all bar types, for all charts.

          Once you learn about the silly things, like what the Calculate setting is really
          doing, like shifting the meaning of Close[0] vs Close[1] -- it's a piece of cake.

          Oh, now don't get me started on historical data. The Strategy Analyzer only
          deals with historical data, which only supports OnBarClose, which means the
          Strategy Analyzer is not able to call your OnBarUpdate for every tick or price
          change. [EDIT: It's probably more appropriate to say the Strategy Analyzer
          ignores your Calculate setting, since it always uses OnBarClose internally.]

          In other words, the Strategy Analyzer will only call your OnBarUpdate (this is
          for BarsInProgress set to 0, which is your primary data series) at the close of
          each bar -- and, naturally, each of those bars is (by definition) a historical bar.

          If you need to see the 'realtime' tick data of each historical bar, you have to dig
          deep into the NinjaScript foot locker of tips & tricks and use a 1-Tick secondary
          data series
          .

          Fortunately, with the advent of NinjaTrader 8, that 1-Tick secondary data series
          trick is really only needed by strategies. The analogous solution for indicators
          (that is, how to get the 'realtime' tick data of each historical bar, as the historical
          bar is being built) is called TickReplay.

          Yup, clear as mud.

          Last edited by bltdavid; 12-05-2021, 04:28 AM. Reason: Improve closing comments -- better buildup to TickReplay.

          Comment


            #6
            Very loud and clear. Thanks for the wonderful write-up about the Calculate OnBarClose.

            Originally posted by bltdavid View Post

            You can't get the closing price of the bar until the bar actually closes, silly.

            Oh, you want to see this closing price as the bar is built, before it closes?

            [EDIT: The Strategy Analyzer won't support this directly, historical bars don't
            have the extra data to show 'real-time' changes -- so it always runs your
            Strategy using Calculate.OnBarClose. The Calculate setting only really
            shines when used with real-time data.]

            Well, as Brandon says, don't use Calculate.OnBarClose.

            [EDIT: Since you're dealing with daily bars, you have some additional choices,
            such as GetDayBar and CurrentDayOHL -- but the Close price of the current daily
            bar is a real-time thing, and won't be finalized until end of day. You can get the
            current real-time last price of the bar as the bar is being built -- the easiest way
            to do that is via a trick of the Calculate property.]

            What does Calculate do?

            The Calculate property controls the sense of what Close[0] means. It also
            dictates how often your OnBarUpdate() is called.

            There are 3 settings,
            • Calculate.OnBarClose <-- this is the default
            • Calculate.OnEachTick
            • Calculate.OnPriceChange
            OnBarClose means every Close[0] reflects the price of the most recently
            closed bar -- so, if you want the current close price of the active bar as it
            is being built, you'll have to get that by other means (or don't use OnBarClose).

            OnEachTick means every Close[0] reflects every tick price movement for
            the active bar being built. If you want the close price of the most recently
            closed bar, it's available -- the indexes have all been shifted back by one --
            at Close[1].

            OnPriceChange is the same as OnEachTick, except if the tick price coming
            in from the data feed is same price as the last tick, OnPriceChange does nothing.

            See that?
            It's subtle -- but the sense of what Close[0] means depends upon the Calculate
            setting.

            People also get confused by OnEachTick vs OnPriceChange. OnPriceChange
            means you don't care about 26 ticks in a row coming in at the same price, you
            only care about when the tick price has changed. OnEachTick means you get to
            see each and every tick, even if the price hasn't changed.

            In your case, either OnEachTick and OnPriceChange should give you what you
            want -- which is the current real-time close price of the daily bar under construction.

            Ok, but why is that same price distinction important?
            One word: volume.

            Because ticks have volume. Even if the price is the same, each tick will contain
            volume information -- if knowing this volume on a tick by tick basis for the bar
            currently being built
            is important, well then, OnEachTick is your man, and
            your OnBarUpdate() is called for each and every tick.

            [EDIT: This may be important to you, if say, you're writing a volume based indicator,
            such as a volume profile.]

            If volume is no big deal, but you still want to see the tick price as it changes for
            the bar currently being built, then use OnPriceChange. Your OnBarUpdate()
            only gets called if the tick price is different.

            [EDIT: Most indicators are associated with price, not volume. These are indicators
            where OnEachTick vs OnPriceChange doesn't change the plotting.]

            If the prices associated with the bar currently being built is not a big deal,
            because you only wish to deal with bars that have closed, then use OnBarClose.
            This means your OnBarUpdate() will being called less often (a lot less often),
            because it only gets called on the first tick of the new bar.

            Huh? Wait a minute ...
            Why does OnBarClose mean OnBarUpdate() is called on first tick of the new bar?
            How come it's not called on the last tick of the current bar?

            Good question.
            Because NinjaTrader supports many different bar types, that's why. If your mind
            says 'last tick of the current bar', you're thinking about time-based bars -- and yes,
            this would be possible to do.

            But what about Renko, or Range, or Volume bars?
            How do you know when the last tick has arrived for those bars?

            You don't necessarily know you're on the last tick while you're on it. These bar
            types are defined by knowing when the next tick must start a new bar.

            Well, it turns out that if you define each new bar by the arrival of it's first tick,
            you've solved that problem for each and every bar type, for all time. That's
            why the bar close event actually takes place on the first tick of the new bar,
            to make the code easier and more consistent for all bar types, for all charts.

            Once you learn about the silly things, like what the Calculate setting is really
            doing, like shifting the meaning of Close[0] vs Close[1] -- it's a piece of cake.

            Oh, and don't get me started on historical data. The Strategy Analyzer only
            deals with historical data, which only supports OnBarClose, which means your
            OnBarUpdate does not get called for every tick or every price change, which
            means you have to resort to a 1-Tick secondary data series. But that's for
            strategies.

            Most of what I just said about historical data doesn't apply for indicators
            designed to use TickReplay.

            Yup, clear as mud.

            Comment


              #7
              David, do you have any indicators or strategies for sale?

              Comment


                #8
                Originally posted by ezrollin View Post
                David, do you have any indicators or strategies for sale?
                Interesting that you ask.
                But, unfortunately, no ... not at this time.

                However, never say never.
                Things may/will change next year.

                Some tools of interest ...

                1. I have a network aware TradeCopier.
                [Wanna run Apex and Leeloo at the same time, on the same PC, with a Single Broker license?
                Run my TradeCopier server on NT8, have it replicate the main 'leader' account to the 'follower'
                account(s) running on NT7 using my TradeCopier client -- all running on the same PC.]

                2. I have an Advanced Pivots indicator.
                [Would you like to see the current Daily, Weekly, and Monthly pivots, as well as the prior DWM
                pivots -- all while loading only 1 day of data to your chart? NO more loading 60+ days on your
                chart to see Monthly pivots.]

                3. I have a Chart Trader enhancement w/buttons Buy/SellOnClose, BE+1, 1-click OCO order entry.
                [Ctrl+Click 'REV' and it becomes an 'OCO' order entry button. There are 5 customizable 'preset
                quantity' buttons. It has +/- nudge buttons to move the stop/target orders by 1 tick, or use
                Ctrl+Click and it nudges the orders by 2 ticks. I invented a 'BX+1' button which does what I
                call 'Bracket Exit' -- it's my GTFO Now button -- BX+1 does two things: move stop to 1 tick
                below last price, and move target to 1 tick above last price.]

                All the above, plus much more, is available now for NT7 ... next year for NT8.

                Attached Files
                Last edited by bltdavid; 12-05-2021, 04:14 AM.

                Comment


                  #9
                  Hi David,

                  Thank you for the detailed write-up.
                  Just to clarify, I'm using the Strategy Analyzer to run Backtesting on the End of Day closing prices. So I'm not interested in the intraday real time as the bar is being built. I'm waiting for the day to be over and getting the end of day closing price. At the moment, the Strategy Analyzer is not doing this. It's using the previous days closing price instead of today's (after the market has closed) closing price.

                  I understand that I can't get the Close Price until the bar closes (which it clearly has closed as the trading day is over and I've downloaded the closing prices from Kinetick.)
                  The closed price is then downloaded and stored in the Historical Data. This same closed price that is now stored is pulled up and displayed on the chart.

                  Q> If this Closed Price definitely exists as I can clearly see on the bar chart and in the Historical Data, then why can't I access it to use it eg. Print it out?
                  I think this is a limitation of the Strategy Analyzer and they should fix it. Bar[0] should call up the last recorded close price of the last bar not the 2nd last bar/price
                  What do you think?

                  Comment


                    #10
                    This is kinda a real-time discussion. A lot of what happens in
                    real-time is simply not possible to be reflected in the Strategy
                    Analyzer -- it only deals with historical prices, or more accurately,
                    with OHLCV of closed bars. A Daily bar won't be "closed" in
                    NinjaScript until the first tick arrives at the next session open.

                    Close[0] won't contain the actual Close price of the daily bar
                    until the first tick of the next day's daily bar arrives. When
                    using OnBarClose, by definition the value of Close[0] always
                    reflects the close of the previous day.

                    Waiting for the day to be over doesn't mean anything. The
                    fact that the end of day closing prices are known and
                    available around the world doesn't mean anything.

                    What the real world knows and what NinjaScript knows is
                    not always the same thing. This happens to be one of those
                    things.

                    Close[0] will change its value only when the first tick arrives
                    at the start of the new session -- since it is that tick that is
                    the first tick of the next daily bar -- but the new session
                    (for a Futures instrument) won't start for 1 hour.

                    In other words, NT won't reflect Close[0] as the end of the
                    current day -- why? because OnBarClose (I'll say it again)
                    always means Close[0] is the close price of the most recently
                    closed bar -- and a bar is closed only when NT detects the
                    first tick of the next bar.

                    But -- here's the rub -- the first tick of the new daily bar for a
                    Futures instrument arrives 1 hour later -- at the next session
                    open. If that's got you confused or upset, it really shouldn't.

                    -=o=-

                    Q> If this Closed Price definitely exists as I can clearly see on the bar chart and in the Historical Data, then why can't I access it to use it eg. Print it out?
                    I think this is a limitation of the Strategy Analyzer and they should fix it. Bar[0] should call up the last recorded close price of the last bar not the 2nd last bar/price
                    What do you think?

                    I think you need to fix your thinking.
                    Sure, the close price exists, as you say, and can be downloaded, as you say.
                    But it won't exist in NinjaScript with OnBarClose until the first tick arrives for
                    the next bar -- that's just the way NT builds its bars. The fact that the close
                    price is 'known' for 1 hour until the first tick arrives when the exchange re-opens
                    also doesn't mean anything -- the OnBarUpdate for the bar close of the daily
                    bar actually happens on the first tick of the new session, which, for most
                    Futures instruments, occurs 1 hour after the close. That's just part of the
                    design, my friend.

                    And, btw, I think the current NT design is fine.
                    Why would you want the close price right at the moment the session closes?
                    The session is closed, what good does it do you at that instant?
                    Ok, say you know it, what can you do with it?
                    The session is closed, there is no more data, the auction is over, so
                    there are no more orders.

                    Ok, so you know the close price, as supplied to you by the real world, for
                    an hour -- but in NinjaScript you can't do anything with it anyways, because
                    the exchange is closed.

                    And, as expected, there are no more OnBarUpdates, because there is
                    no more data. The next OnBarUpdate is at the first tick of the new session,
                    and it will be at that moment that Close[0] reflects the close price that the
                    real world has already known about for an hour -- but, hey, this the first
                    tick of the new session, data is available, the auction is open, and you
                    can immediately enter orders using the Close[0] for the previous day
                    close.-- thus, actually, everything in your code should work fine.

                    Comment


                      #11
                      bltdavid is correct.

                      In additional, it depends on the instrument (futures, stocks, forex, cryptos).

                      If it's cryptos, it's the settings that you need to change to Default 24/7, disable EOD, and turn off Sessions. Strategy Analyzer will see that data will be treated as 24 hours/day and will run all the way between the start and end dates without closing the sessions/EOD.



                      Comment


                        #12
                        Hello ShayeAus,

                        Thanks for your note.

                        bltdavid is correct. "Close[0] won't contain the actual Close price of the daily bar until the first tick of the next day's daily bar arrives. When using OnBarClose, by definition the value of Close[0] always reflects the close of the previous day."

                        Please let us know if we may assist further.
                        Brandon H.NinjaTrader Customer Service

                        Comment


                          #13
                          Thanks David for another excellent write up.

                          Waiting for the start of the next tick will still lag a day behind so this won't work for me. I wish NT8 had an option to click and manually set it.

                          I'm trying to think of a workaround. Since it won't give me yesterday's close and only the day before, this is what I've done (and has sort of worked)...

                          I've selected one stock and created a dummy entry in the historical data for today. Now when I re-run the Strategy Analyzer, it has today's (dummy) prices which trick it and now I get yesterday's closing price. (manually triggering the next Tick I guess) Make sense?
                          Then when I re-download the actual closing prices tomorrow it will overwrite today's dummy data, so that fixes that.
                          But then I have to repeat the process the next day etc. which I don't mind doing as it takes less than a minute

                          The real problem now is, I will have to do this for all stock! Imagine I'm testing an instrument list of 000's. Not very practical.

                          Another thought....
                          Can I upload one file of multiple instruments with dummy entries for one day? I only know of uploading one file per instrument.

                          Brandon, can you confirm if this is possible to import/update stock last price data for multiple instruments at once (one file)?
                          Last edited by ShayeAus; 12-06-2021, 10:47 PM.

                          Comment


                            #14
                            Originally posted by ShayeAus View Post
                            Thanks David for another excellent write up.

                            Waiting for the start of the next tick will still lag a day behind so this won't work for me. I wish NT8 had an option to click and manually set it.

                            I'm trying to think of a workaround. Since it won't give me yesterday's close and only the day before, this is what I've done (and has sort of worked)...

                            I've selected one stock and created a dummy entry in the historical data for today. Now when I re-run the Strategy Analyzer, it has today's (dummy) prices which trick it and now I get yesterday's closing price. (manually triggering the next Tick I guess) Make sense?
                            Then when I re-download the actual closing prices tomorrow it will overwrite today's dummy data, so that fixes that.
                            But then I have to repeat the process the next day etc. which I don't mind doing as it takes less than a minute

                            The real problem now is, I will have to do this for all stock! Imagine I'm testing an instrument list of 000's. Not very practical.

                            Another thought....
                            Can I upload one file of multiple instruments with dummy entries for one day? I only know of uploading one file per instrument.

                            Brandon, can you confirm if this is possible to import/update stock last price data for multiple instruments at once (one file)?
                            The parts in red have me confused.

                            What do you mean -- it won't give you yesterday's close?

                            If you're working with daily bars, and using OnBarClose,
                            (Strategy Analyzer is always OnBarClose), then the value
                            in Close[0] is precisely that -- it is yesterday's close.

                            If Close[0] is the last close price of the most recently
                            closed bar, then when using daily bars, by definition,
                            the value in Close[0] represents yesterday's closing
                            price.

                            Is this not what you're seeing?

                            Who is your data provider?
                            Last edited by bltdavid; 12-07-2021, 12:35 AM.

                            Comment


                              #15
                              Hello ShayeAus,

                              Another thought....
                              Can I upload one file of multiple instruments with dummy entries for one day? I only know of uploading one file per instrument.

                              Brandon, can you confirm if this is possible to import/update stock last price data for multiple instruments at once (one file)?
                              It is possible to manually import data by file into the platform, but this would not change how BarsAgo indexing works, and we wouldn't recommend taking that path.

                              As bltdavid mentions, Close[0] on a daily bar represents yesterday's close, until we start processing the next daily bar. (Bar closures are signaled by the first tick of a new bar, and this is for consistent event based bar development between all bar types)

                              I like to think of BarsAgo 0 references with OnBarClose as processing the bar that has just closed. OnEachTick/OnPriceChnage have BarsAgo 0 references point to the developing bar that has not yet closed.

                              JimNinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by pkefal, 04-11-2024, 07:39 AM
                              11 responses
                              36 views
                              0 likes
                              Last Post jeronymite  
                              Started by bill2023, Yesterday, 08:51 AM
                              8 responses
                              43 views
                              0 likes
                              Last Post bill2023  
                              Started by yertle, Today, 08:38 AM
                              6 responses
                              25 views
                              0 likes
                              Last Post ryjoga
                              by ryjoga
                               
                              Started by algospoke, Yesterday, 06:40 PM
                              2 responses
                              24 views
                              0 likes
                              Last Post algospoke  
                              Started by ghoul, Today, 06:02 PM
                              3 responses
                              16 views
                              0 likes
                              Last Post NinjaTrader_Manfred  
                              Working...
                              X