Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Calculate OnBarClose when OnPriceChange selected.

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

    Calculate OnBarClose when OnPriceChange selected.

    Hello,

    I have a script (irrelevant is it indicator or strategy) that have a few lines of code in OnBarUpdate method:

    Code:
    if (IsFirstTickOfBar)
    {
    Print(string.Format("{0} {1} {2} {3} {4}",
    Time[0].ToString("yyyyMMdd HH:mm"),
    Open[0].ToString("0.##"),
    High[0].ToString("0.##"),
    Low[0].ToString("0.##"),
    Close[0].ToString("0.##")));
    
    return;
    }
    Suppose i have last one month data on a daily chart (2021.11.08 - 2021.12.09). And i add an script on a chart and...

    1. If I set calculate property to Calculate.OnBarClose Output window shows below data:
    20211108 19:00 ......
    20211109 19:00 ......
    20211110 19:00 ......
    .
    .
    .
    20211208 19:00 ......

    Because today/current day is 2021.12.09 and bar not closed yet if statement code block not working for the current day. This is nice and what i wanted/expected.

    2.If I set calculate property to Calculate.OnPriceChange Output window shows below data:
    20211108 19:00 ......
    20211109 19:00 ......
    20211110 19:00 ......
    .
    .
    .
    20211208 19:00 ......
    20211209 19:00 ......

    If statement is working also for current day bar which is not yet closed. Shortly i dont want to work if statement block for the current day even if i set calculate property to OnPriceChage. So how can i prevent that?

    Best Regards,
    AA

    #2
    Hello aytacasan,

    Thanks for writing in.

    This is the expected behavior when using OnPriceChange. If you run a script using OnPriceChange, you will get data points for the current day printed to the output window.

    You would need to add a condition to your If statement so that today's date is excluded. You may consider comparing Time[0] with the DateTime.Now properties (check for an equal day, month, year).

    See this help guide for more information about Time[0]: https://ninjatrader.com/support/help...eries_time.htm

    And this publicly available link about DateTime: http://msdn2.microsoft.com/en-us/lib....datetime.aspx

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

    Comment


      #3
      Originally posted by aytacasan View Post
      Shortly i dont want to work if statement block for the current day even if i set calculate property to OnPriceChage. So how can i prevent that?
      When using OnBarClose,
      Close[0] is close price of the most recently closed bar <-- you want this
      Close[1] is close price of the next recently closed bar


      When using OnEachTick/OnPriceChange,
      Close[0] is current close price of the active bar being built
      Close[1] is close price of the most recently closed bar <-- you want this
      Close[2] is close price of the next recently closed bar

      Woah woah woah ... did you See that?
      The meaning of Close[0] vs Close[1] has completely changed
      based upon the value of the Calculate setting.

      When using OnEachTick/OnPriceChange, all the BarsAgo
      index values get shifted by 1, so that [0] is freed up to store
      the current values of the active bar being built.

      This is a big deal.
      It bites people who are doing precisely what you're trying to do.
      [That is, access values from the most recently closed bar.]

      So, what can you do about that?
      [Many times, you won't care. For ex, take a look at @EMA.cs,
      or @CCI.cs, or any standard indicator -- most of them don't care
      about Calculate and just use Close[0], etc -- but yet they still work
      regardless of Calculate's setting. How is that? Because Close[0]
      is being used in calculations, and calculations need to be performant
      for bar close values as well as current close values. Well, it turns
      out just using Close[0] happens to be correct in (almost) all cases
      for all values of Calculate when doing calculations. Pretty cool
      design, eh?]

      But when you do care, you'll need to write your own logic to
      handle it. Let's look at that a bit more.

      -=o=-

      You might try doing something like this,

      if (IsFirstTickOfBar)
      {
      int B0 = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
      Print(string.Format("{0} {1} {2} {3} {4}",
      Time[B0].ToString("yyyyMMdd HH:mm"),
      Open[B0].ToString("0.##"),
      High[B0].ToString("0.##"),
      Low[B0].ToString("0.##"),
      Close[B0].ToString("0.##")));
      return;

      }

      Tip:
      Throughout my code, whenever I access values from the recently
      closed bars, I tend to specify the index through a global variable,
      like this, Close[B0] or Open[B1] or Low[B0], etc.

      private int B0 = 0;
      private int B1 = 1;

      // add more indexes, such as B2, B3, etc, as necessary
      // idea is very extensible, but I've never needed them


      which I adjust later based upon the Calculate setting,

      B0 = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
      B1 = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 1 : 2;


      If I design the rest of the code right, I am usually well insulated
      from whatever the Calculate setting happens to be.

      But, be careful ...
      B0 and B1 are only for accessing the most recently closed bars,
      so I still use Close[0] in most calculations, so that the correct value
      is being used in the formula regardless of Calculate.

      In other words, when you absolutely know you want the values of the
      most recently closed bars
      , the index variables B0 and B1 are always
      set to the correct BarsAgo values.

      Make sense?
      Last edited by bltdavid; 12-09-2021, 04:29 PM.

      Comment


        #4
        Hello,

        Don't think question is only related for daily bars.
        Same script must work all time frames, horly minute tick etc.
        So your solution is not make sense to me or not enough to me.
        First i think that Time[0] equel to session/current bar end time not start time.
        If so i can write this kind of code and i think it'll work all time frames.

        if (DateTime.Now.ConvertToTimeZone(NinjaTrader.Option s.SelectedTimeZone) >= Time[0]) { DoSomething(); }

        Am i right. What you think? Also see some codes like that;

        var barAgo = State == State.Historical ? 0 : 1;
        if (Close[barsAgo] > Open[BarsAgo]) { ... }

        Why some developers write this type of code? Is it related to my problem?

        Thanks,
        AA

        Comment


          #5
          Originally posted by bltdavid View Post

          When using OnBarClose,
          Close[0] is close price of the most recently closed bar <-- you want this
          Close[1] is close price of the next recently closed bar


          When using OnEachTick/OnPriceChange,
          Close[0] is current close price of the active bar being built
          Close[1] is close price of the most recently closed bar <-- you want this
          Close[2] is close price of the next recently closed bar

          Woah woah woah ... did you See that?
          The meaning of Close[0] vs Close[1] has completely changed
          based upon the value of the Calculate setting.

          When using OnEachTick/OnPriceChange, all the BarsAgo
          index values get shifted by 1, so that [0] is freed up to store
          the current values of the active bar being built.

          This is a big deal.
          It bites people who are doing precisely what you're trying to do.
          [That is, access values from the most recently closed bar.]

          So, what can you do about that?
          [Many times, you won't care. For ex, take a look at @EMA.cs,
          or @CCI.cs, or any standard indicator -- most of them don't care
          about Calculate and just use Close[0], etc -- but yet they still work
          regardless of Calculate's setting. How is that? Because Close[0]
          is being used in calculations, and calculations need to be performant
          for bar close values as well as current close values. Well, it turns
          out just using Close[0] happens to be correct in (almost) all cases
          for all values of Calculate when doing calculations. Pretty cool
          design, eh?]

          But when you do care, you'll need to write your own logic to
          handle it. Let's look at that a bit more.

          -=o=-

          You might try doing something like this,

          if (IsFirstTickOfBar)
          {
          int B0 = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
          Print(string.Format("{0} {1} {2} {3} {4}",
          Time[B0].ToString("yyyyMMdd HH:mm"),
          Open[B0].ToString("0.##"),
          High[B0].ToString("0.##"),
          Low[B0].ToString("0.##"),
          Close[B0].ToString("0.##")));
          return;
          }

          Tip:
          Throughout my code, whenever I access values from the recently
          closed bars, I tend to specify the index through a global variable,
          like this, Close[B0] or Open[B1] or Low[B0], etc.

          private int B0 = 0;
          private int B1 = 1;

          (never found a need for B2, B3, etc, or beyond)

          which I adjust later based upon the Calculate setting,

          B0 = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
          B1 = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 1 : 2;


          If I design the rest of the code right, I am usually well insulated
          from whatever the Calculate setting happens to be.

          But, be careful ...
          B0 and B1 are only for accessing the most recently closed bars,
          so I still use Close[0] in most calculations, so that the correct value
          is being used in the formula regardless of Calculate.

          In other words, when you absolutely know you want the values of the
          most recently closed bars
          , the index variables B0 and B1 are always
          set to the correct BarsAgo values.

          Make sense?
          Hi David,

          Wow, I'm impressed. Thank you so much for your effort. Please ignore my previous post which i wrote before I saw your post. I think your post will solve my problem. I'll read many times and try to code as you recommend. Thanks again.

          Comment


            #6
            Time[0] has nothing to do with the session.
            That is not how it is defined.

            Time is a Series that contains the 'end time' of each bar,
            and is defined that way for all time frames and all bar types.

            If the end time of the bar happens to be same time as the
            end time of the session, well, that's just coincidental.

            When using OnBarClose,
            Time[0] is close timestamp of the most recently closed bar
            Time[1] is close timestamp of the next recently closed bar


            When using OnEachTick/OnPriceChange,
            Time[0] is current(*) timestamp of the active bar being built
            Time[1] is close timestamp of the most recently closed bar
            Time[2] is close timestamp of the next recently closed bar

            The above statements are true & consistent and stay constant, regardless of
            the time frame or underlying bar type
            .

            EDIT:
            The "current" timestamp is a rather fuzzy definition. For time based bar series
            using OnEachTick/OnPriceChange, Time[0] is the active bar's projected end time.
            And, once set for a particular bar, Time[0] will keep the same projected end time
            for each call to OnBarUpdate -- that is, Time[0] stays constant and will not change
            until that bar closes, which occurs on the first tick of the next bar.

            (Naturally, after the bar closes, the new Time[0] value for the next bar is the projected
            end time of that next bar. Remember, for time-based bar series, the new 'projected
            end time' is calculated on the first tick of the new bar. That means Time[0] will always
            reflect the correct projected end time of the bar, starting on the bar's very first tick.)

            Non-time based bars, such as Renko and Range, aren't so fuzzy. The time value
            in these bars is very straight forward. The Time[0] value is the timestamp of the
            real-time incoming tick exactly as it was received from the data provider. So, for
            these bars, Time[0] is always (er, I mean, usually) a different value. I wanted to
            say 'always different', but in a highly volatile fast-moving market, many multiple
            ticks could easily have the same Time[0] value.

            To understand the 'constant' nature of the Time series, you need to understand the
            underlying base time period the bar series is built upon. That is, whether a bar series
            is time-based or tick-based is defined by the bar series itself. Start by studying the
            help page titled How Bars Are Built.

            After that, to really master the subject, study How Bars Data is Referenced.
            Last edited by bltdavid; 12-10-2021, 08:32 PM. Reason: Added edits to discuss 'current timestamp' for time-based vs tick-based bar series

            Comment


              #7
              Originally posted by bltdavid View Post
              Time[0] has nothing to do with the session.
              That is not how it is defined.

              Time is a Series that contains the 'end time' of each bar,
              and is defined that way for all time frames and all bar types.

              If the end time of the bar happens to be same time as the
              end time of the session, well, that's just coincidental.

              When using OnBarClose,
              Time[0] is close timestamp of the most recently closed bar
              Time[1] is close timestamp of the next recently closed bar


              When using OnEachTick/OnPriceChange,
              Time[0] is current timestamp of the active bar being built
              Time[1] is close timestamp of the most recently closed bar
              Time[2] is close timestamp of the next recently closed bar

              The above statements are true & consistent and stay constant, regardless of
              the time frame or underlying bar type
              .
              So David below code is the right solution? What do you think about it?

              Code:
              protected override void OnBarUpdate()
              {
              //Add your custom strategy logic here.
              if (IsFirstTickOfBar)
              {
              var barsAgo = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
              
              if (DateTime.Now < Time[barsAgo])
              return;
              
              Print(string.Format("{0} {1} {2} {3} {4} {5}",
              CurrentBar.ToString("0000"),
              Time[barsAgo].ToString("yyyyMMdd HH:mm"),
              Open[barsAgo].ToString("0.##"),
              High[barsAgo].ToString("0.##"),
              Low[barsAgo].ToString("0.##"),
              Close[barsAgo].ToString("0.##")));
              
              return;
              }
              }
              Also above code when my computer and ninja use different time zone settings, is it continue working?

              Thanks,
              AA
              Last edited by aytacasan; 12-09-2021, 12:51 PM.

              Comment


                #8
                Originally posted by bltdavid View Post
                Time[0] has nothing to do with the session.
                Maybe we can talk about a more specific sample.
                Let say we have an indicator that must calculate only on bar close.
                And we write a strategy that uses this indicator for entry/exit conditions.
                Also want to use trailing stop for open positions and need tick by tick data.
                First set strategy's calculate on each tick than in our OnBarUpdate;

                if (IsFirstTickOfBar)
                {
                if (this is not most recent and so not yet closed bar)
                {
                Do indicator calculations...
                if (We don't have a position and conditions are met for a new position)
                {
                Open new position...
                }
                }
                }

                if (We have a position)
                {
                Trail stop...
                }

                Comment


                  #9
                  Originally posted by aytacasan View Post

                  So David below code is the right solution? What do you think about it?

                  Code:
                  protected override void OnBarUpdate()
                  {
                      //Add your custom strategy logic here.
                      if (IsFirstTickOfBar)
                      {
                          var barsAgo = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
                  
                  [COLOR=#e74c3c]       if (DateTime.Now < Time[barsAgo])
                              return;[/COLOR]
                  
                          Print(string.Format("{0} {1} {2} {3} {4} {5}",
                              CurrentBar.ToString("0000"),
                              Time[barsAgo].ToString("yyyyMMdd HH:mm"),
                              Open[barsAgo].ToString("0.##"),
                              High[barsAgo].ToString("0.##"),
                              Low[barsAgo].ToString("0.##"),
                              Close[barsAgo].ToString("0.##")));
                  
                          return;
                      }
                  }
                  Also above code when my computer and ninja use different time zone settings, is it continue working?
                  Looks good, but why the code in red above?

                  As to your second question,
                  The timezone setting of your PC vs the exchange time zone
                  doesn't matter. So, yes, it will continue working.

                  Do you mean the NT8 setting in Options -> General where you
                  can tell NinjaTrader the time zone? Same thing, it doesn't
                  matter.

                  By default,
                  The timestamp values stored the Time series are always
                  adjusted and saved as local time -- meaning the time values
                  you see are end times of each bar automatically normalized
                  to the time zone of your local computer.

                  However, if you change the time zone in Options -> General,
                  the timestamp values stored in the Time series are normalized
                  to the time zone setting you specified.

                  [EDIT: I presume that the Time series is always normalized to
                  the time zone setting in General -> Options. It's just that this
                  setting defaults to your computer's time zone, and 99 out of
                  100 people probably never change it.]

                  NT Support can correct me if I'm wrong.

                  Comment


                    #10
                    Originally posted by aytacasan View Post
                    Maybe we can talk about a more specific sample.
                    Let say we have an indicator that must calculate only on bar close.
                    And we write a strategy that uses this indicator for entry/exit conditions.
                    Also want to use trailing stop for open positions and need tick by tick data.

                    First set strategy's calculate on each tick than in our OnBarUpdate;
                    Sounds like we're talking about the code for a strategy.
                    You're asking about a very common scenario.

                    Study this sample.
                    Last edited by bltdavid; 12-09-2021, 02:34 PM.

                    Comment


                      #11
                      Originally posted by bltdavid View Post

                      Looks good, but why the code in red above?
                      Please look at the attachments. One is with doing Time check other is not.

                      Without time check "HT 2523 20211210 03:00 50520.94 50844.86 47323.23 47884.41" output line working something historical but actually it's not historical in my logic because its current-day bar and isn't closed yet. Also, be careful about the recurrence of the 2523 bar number.

                      About time zone. Yes, I'm talking about NT's settings. This setting effecting all of your data related to time. For example time series on your chart, time series on your script, etc.

                      I'll study the sample code that you mentioned very next post.

                      Thanks,
                      AA

                      Attached Files

                      Comment


                        #12
                        Originally posted by aytacasan View Post
                        Please look at the attachments. One is with doing Time check other is not.

                        Without time check "HT 2523 20211210 03:00 50520.94 50844.86 47323.23 47884.41" output line working something historical but actually it's not historical in my logic because its current-day bar and isn't closed yet. Also, be careful about the recurrence of the 2523 bar number.

                        About time zone. Yes, I'm talking about NT's settings. This setting effecting all of your data related to time. For example time series on your chart, time series on your script, etc.

                        I'll study the sample code that you mentioned very next post.
                        Yeah, you've discovered something else, and that is the Historical -> RealTime transition
                        doesn't seem so clean. That is, in my experience with NT7, I found that sometimes the
                        CurrentBar for the very last Historical bar is 're-used' for the very first RealTime bar, but
                        this only happened with CalculateOnBarClose=False, which is equivalent to OnEachTick
                        in NT8. I think the term 'fake bar' was previously used to describe this phenomenon.

                        Also, see the edits in my post #6 to understand why Time[0] is a constant value for each
                        call to OnBarUpdate. I discuss why, even after the transition from Historical to RealTime,
                        each tick for CurrentBar=2523 shows the same Time[0] value. Did you notice that?

                        So why is that? Quick answer: Because your using OnEachTick/OnPriceChange, and
                        because the primary bar series is time-based.
                        Last edited by bltdavid; 12-10-2021, 08:35 PM.

                        Comment


                          #13
                          Originally posted by bltdavid View Post

                          Yeah, you've discovered something else, and that is the Historical -> RealTime transition
                          doesn't seem so clean.
                          Hi David,

                          Although the support team does not comment on this issue, I think the most correct approach should be as follows.
                          Below code, you can execute commands for only each closed bar or for only each tick, or for both situations.
                          Thanks for your helps.

                          Code:
                          if (IsFirstTickOfBar)
                          {
                          var barsAgo = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
                          
                          if (DateTime.Now >= Time[barsAgo])
                          {
                          var currentBar = CurrentBar - barsAgo;
                          
                          Print(string.Format("OnBarClose {0} {1} {2} {3} {4} {5}",
                          currentBar.ToString("0000"),
                          Time[barsAgo].ToString("yyyyMMdd HH:mm"),
                          Open[barsAgo].ToString("0.00"),
                          High[barsAgo].ToString("0.00"),
                          Low[barsAgo].ToString("0.00"),
                          Close[barsAgo].ToString("0.00")));
                          }
                          }
                          
                          Print(string.Format("OnEachTick {0} {1} {2} {3} {4} {5}",
                          CurrentBar.ToString("0000"),
                          Time[0].ToString("yyyyMMdd HH:mm"),
                          Open[0].ToString("0.00"),
                          High[0].ToString("0.00"),
                          Low[0].ToString("0.00"),
                          Close[0].ToString("0.00")));

                          Comment


                            #14
                            Originally posted by aytacasan View Post
                            Code:
                            if (IsFirstTickOfBar)
                            {
                                var barsAgo = (Calculate == Calculate.OnBarClose || State == State.Historical) ? 0 : 1;
                            
                                if (DateTime.Now >= Time[barsAgo])
                                {
                                    var currentBar = CurrentBar - barsAgo;
                            
                                    Print(string.Format("OnBarClose {0} {1} {2} {3} {4} {5}",
                                        currentBar.ToString("0000"),
                                        Time[barsAgo].ToString("yyyyMMdd HH:mm"),
                                        Open[barsAgo].ToString("0.00"),
                                        High[barsAgo].ToString("0.00"),
                                        Low[barsAgo].ToString("0.00"),
                                        Close[barsAgo].ToString("0.00")));
                                }
                                return;  // [COLOR=#e74c3c]<-- you're missing this, right?[/COLOR]
                            }
                            You're missing a return inside your IsFirstTickOfBar, right?

                            I mean, for that piece of code, without the return, you're gonna have
                            double prints on the first tick of every bar, right?

                            Mind if I make some more coding suggestions?
                            Let's make your code a bit easier to read, and easier to write.
                            [I know this is very subjective, but you may find some useful nuggets here.]

                            -=o=-

                            TIP #1

                            I like to make these three methods available for every Indicator and Strategy,

                            Code:
                            public double RoundToTickSize(double Price)
                            {
                                return Instrument.MasterInstrument.RoundToTickSize(Price) ;
                            }
                            
                            public string FormatPrice(double Price)
                            {
                                return Instrument.MasterInstrument.FormatPrice(RoundToTic kSize(Price));
                            }
                            
                            public int ComparePrice(double Price1, double Price2)
                            {
                                return Instrument.MasterInstrument.Compare(Price1, Price2);
                            }
                            The important one here is FormatPrice -- it will show the correct number
                            of decimals (or fractionals, in the case of Treasury bonds), so your code
                            becomes insulated form the TickSize of the instrument.

                            Now your first Print becomes,

                            Code:
                            Print(string.Format("OnBarClose {0} {1} {2} {3} {4} {5}",
                                currentBar.ToString("0000"),
                                Time[barsAgo].ToString("yyyyMMdd HH:mm"),
                                FormatPrice(Open[barsAgo]),
                                FormatPrice(High[barsAgo]),
                                FormatPrice(Low[barsAgo]),
                                FormatPrice(Close[barsAgo])));
                            -=o=-

                            TIP #2

                            I would suggest that typing currentBar.ToString("0000") is a bit
                            too much typing, I mean, my fingers get achy just looking at that ... lol ...

                            Try moving that format specification inside the string.Format itself, like this,

                            Code:
                            Print(string.Format("OnBarClose [B][COLOR=#e74c3c]{0:0000}[/COLOR][/B] {1} {2} {3} {4} {5}",
                                currentBar,
                                Time[barsAgo].ToString("yyyyMMdd HH:mm"),
                                FormatPrice(Open[barsAgo]),
                                FormatPrice(High[barsAgo]),
                                FormatPrice(Low[barsAgo]),
                                FormatPrice(Close[barsAgo])));
                            That helps to make the code a little bit cleaner and easier to read.

                            -=o=-

                            TIP #3

                            I predict that you use Print(string.Format(....)) a lot, which is
                            a very good thing. This next tip helps to make that a little bit easier.

                            I like to make this method available to every Indicator and Strategy,

                            Code:
                            public void PrintString(string format, params object[] args)
                            {
                                Print(string.Format(format, args));
                            }
                            Your Print easily becomes a PrintString, like this,

                            Code:
                            PrintString("OnBarClose [B][COLOR=#e74c3c]{0:0000}[/COLOR][/B] {1} {2} {3} {4} {5}",
                                currentBar,
                                Time[barsAgo].ToString("yyyyMMdd HH:mm"),
                                FormatPrice(Open[barsAgo]),
                                FormatPrice(High[barsAgo]),
                                FormatPrice(Low[barsAgo]),
                                FormatPrice(Close[barsAgo]));
                            Big deal, you say, small savings in typing, who cares, it's just a personal
                            matter of taste and style. Sure, but there are benefits to this approach.

                            What are those benefits?

                            1. What if you want to turn off all your debugging output?

                            PrintString allows you to setup a single global variable, which can
                            later become your primary knob to disable that debugging output quickly
                            and easily, like this,

                            Code:
                            public void PrintString(string format, params object[] args)
                            {
                                if (IsDebugging)
                                    Print(string.Format(format, args));
                            }
                            2. What if you want to use PrintString everywhere?

                            Well, you can wrap that other long output method easily, like this,

                            Code:
                            public void PrintString(string format, params object[] args)
                            {
                                NinjaTrader.Code.Output.Process(string.Format(format, args), PrintTo.OutputTab1);
                            }
                            I've found PrintString to be a nice little method that encapsulates all my
                            printing to the output window.

                            -=o=-

                            TIP #4

                            FormatPrice can be used with FormatPriceMarker to make all your
                            Treasury bond charts more consistent and a little easier to use.

                            Study the technique here.

                            Comment


                              #15
                              Originally posted by bltdavid View Post

                              You're missing a return inside your IsFirstTickOfBar, right?
                              No, my friend, I'm not missing the return. Yes, you're right this means double print. According to different scenarios you want to add again.
                              For example, if you have a custom series inside your strategy and you want to calculate the current value only on bar close and all other trading logic will be processed tick by tick.
                              So you don't want to use return. Something like this;

                              if (IsFirstTickOfBar)
                              {
                              Do some calculations because the current bar closed right now...
                              Below we'll use updated values until the next bar close so don't use return
                              }

                              if (Position.MarketPosition == MarketPosition.Flat)
                              {
                              Use updated values for trade logic...
                              }

                              Also thank you so much for your tips. They are very valuable and useful.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                              0 responses
                              577 views
                              0 likes
                              Last Post Geovanny Suaza  
                              Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                              0 responses
                              334 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by Mindset, 02-09-2026, 11:44 AM
                              0 responses
                              101 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                              0 responses
                              553 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by RFrosty, 01-28-2026, 06:49 PM
                              0 responses
                              551 views
                              1 like
                              Last Post RFrosty
                              by RFrosty
                               
                              Working...
                              X