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

about CurrentBar

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

    about CurrentBar

    Hello,

    I would like to know the difference between ChartBars.ToIndex and CurrentBar.

    I dont understand why doing:

    Code:
    for(int barIndex = (mybar - Period); barIndex <= CurrentBar; barIndex++)
    and doing:

    Code:
    for(int barIndex = (mybar - Period); barIndex <= [LEFT][COLOR=#4D4D4D][FONT=Helvetica][SIZE=13px]ChartBars.ToIndex [/SIZE][/FONT][/COLOR][/LEFT]; barIndex++)
    wont return the same answer. There is a 2 pts difference in my cumulative moving average and the one using
    ChartBars.ToIndex
    is the right answer.
    So why replacing by CurrentBar has a different impact?

    Ty

    #2
    Hello frankduc,

    Thank you for your post.

    ChartBars.ToIndex will return the index of the very last bar VISIBLE on the right side of the chart. From the help guide:

    Note: This value is NOT the last value that exists on the ChartBars, but rather the last bar index that is within the viewable range of the chart canvas area. This value changes as the user interacts with the ChartControl time-scale (x-axis).
    Whereas using CurrentBar will always give you the bar index of the bar that is currently forming. So, for example, if I am scrolled all the way to the currently forming bar, CurrentBar and ChartBars.ToIndex should give the same result. However, if I scroll back to the previous day, ChartBars.ToIndex will be the index for last visible bar on the right, not the most recent bar.

    Here's a link to the help guide with further information:

    https://ninjatrader.com/support/help...rs_toindex.htm

    Please let us know if we may be of further assistance to you.
    Last edited by NinjaTrader_Kate; 10-15-2019, 09:07 AM.
    Kate W.NinjaTrader Customer Service

    Comment


      #3
      Kate,

      Is it normal that Print(cma) outside the brackets of the for loop in OBU like this:

      Code:
      [LEFT][COLOR=#4D4D4D][FONT=Helvetica][SIZE=13px]protected override void OnBarUpdate()
        {
      
         for (int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
          {
          mybar = barIndex;
          }
      
      
          for(int barIndex = (mybar - Period); barIndex <= CurrentBar; barIndex++)
          {
          double closePrice = Bars.GetClose(barIndex);
          double volumes = Bars.GetVolume(barIndex); 
      
          clovol = closePrice * volumes; 
      
      
          sum1 += clovol++;
          sum2 += volumes++;
      
          cma = sum1 / sum2;
      
      
      
          Value[0] = cma;
      
        }  
      Print(Value[0]);
        }
      
      [/SIZE][/FONT][/COLOR][/LEFT]
      [LEFT][COLOR=#4D4D4D][FONT=Helvetica][/FONT][/COLOR][/LEFT]


      Print(Value or cma) will return a bunch of zeros for every bars on the chart prior to Period.

      If i set a Period = 160 and there is 500 bars there will be 340 zeros before the cma. See on attachment.
      Could it be link to addplot?

      Ty
      Attached Files

      Comment


        #4
        Hello frankduc,

        Thank you for your reply.

        A large chunk of your issue is that you're trying to do the final dividing of the sums and assigning to the plot within the loop that you're using the loop through the bars in the set period. You need to do this outside of the loop, because otherwise you're assigning something to Value[0] on each loop iteration.

        Also, this loop is redundant and can be removed:

        Code:
        for (int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
        {
        mybar = barIndex;
        }
        mybar will be equal to ChartBars.ToIndex at the end of the loop. Since we know that, we don't need to bother.

        That being said, I wouldn't use ChartBars.ToIndex as the calculations will vary depending on what bar the user is scrolled to. Use CurrentBar to make sure it's always calculating from the most recent.

        Also, make sure you're not trying to calculate the indicator before you have enough bars. You need as least as many bars as the Period, so I set my example below to account for that.

        Here's a quick revision that plots your CMA:

        Code:
            public class SampleCMA : Indicator
            {
        
                private double clovol;
                private double sum1;
                private double sum2;
                private double cma;
                private double closePrice;
                private double volumes;
        
                protected override void OnStateChange()
                {
                    if (State == State.SetDefaults)
                    {
                        Description                                    = @"Enter the description for your new custom Indicator here.";
                        Name                                        = "SampleCMA";
                        Calculate                                    = Calculate.OnBarClose;
                        IsOverlay                                    = false;
                        DisplayInDataBox                            = true;
                        DrawOnPricePanel                            = true;
                        DrawHorizontalGridLines                        = true;
                        DrawVerticalGridLines                        = true;
                        PaintPriceMarkers                            = true;
                        ScaleJustification                            = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                        //Disable this property if your indicator requires custom values that cumulate with each new market data event. 
                        //See Help Guide for additional information.
                        IsSuspendedWhileInactive                    = true;
                        Period = 160;
        
        
                        AddPlot(Brushes.Goldenrod, "CMA1");
                    }
                    else if (State == State.Configure)
                    {
                    }
                }
        
                protected override void OnBarUpdate()
                {
                    if (CurrentBar < Period)
                        return;
        
                    for(int barIndex = CurrentBar - Period; barIndex <= CurrentBar; barIndex++)
                    {
                        closePrice = Bars.GetClose(barIndex);
                        volumes = Bars.GetVolume(barIndex);
        
                        clovol = closePrice * volumes; 
        
                        sum1 += clovol;
                        sum2 += volumes;
                    }
        
                    cma = sum1 / sum2;
        
                    Value[0] = cma;
                }
        
                #region Properties
                [Range(1, int.MaxValue), NinjaScriptProperty]
                [Display(ResourceType = typeof(Custom.Resource), Name = "Period", GroupName = "NinjaScriptParameters", Order = 0)]
                public int Period
                { get; set; }
                #endregion
            }
        Please let us know if we may be of further assistance to you.
        Kate W.NinjaTrader Customer Service

        Comment


          #5
          Kate,

          The
          Code:
            [LEFT][COLOR=#252C2F][FONT=Courier]if (CurrentBar < Period)
                          return;[/FONT][/COLOR][/LEFT]
          seems to help get rid of those 2 errors i have been dealing with for a while:

          "CMAtest" flag: error on the application of the "OnBarUpdate" method on bar 0: The reference of the object is not passed to an instance of an object.

          "CMAtest" indicator: error on the application of the "OnBarUpdate" method on bar 0: The index is outside the limits of the table.

          But as you can see in attachment we are not there yet. Your result dont return the right answer, neither mine. The VWMA return the right answer but is not cumulative, the last result 2961.2 is the result i have been seeking. From my result there is a 10 pts difference. Actually i have been coding the cma with the exact same code in OnRender on another indicator i started and it return the right answer. I dont know what is wrong with OBU.

          My goal is to reproduce the effect of the RMMA. Create many cma's starting for each bars.

          I understand that you cant iterate directly a for loop like this:

          Code:
          int LowPeriod = 2;
                int HighPeriod = 160;
             int StepAverage = 3;
             int count = 0;
             for (int i = LowPeriod; i <= HighPeriod; i += StepAverage)
             {
          
          
             }  
          
          
          for(int barIndex = i; barIndex <= CurrentBar; barIndex++)
              {
          
          // and create more than one cma in the chart .//
          You need to this in the Value[]

          Code:
          int LowPeriod = 2;
                int HighPeriod = 160;
             int StepAverage = 3;
             int count = 0;
             for (int i = LowPeriod; i <= HighPeriod; i += StepAverage)
             {
          
          
              Values[count][0] = CMA(i)[0];
          
          
          
              count++;
          
             }
          By the way i dont see how replacing mybar by Currentbar help. If i set a Period = 160 like i would do for any other ma like sma it wont calculate from the right spot. 160 in the for loop mean barIndex 1443 on a 1602 bars chart.

          TY
          Attached Files

          Comment


            #6
            Hello frankduc,

            Thank you for your reply.

            I am not familiar with the RMMA, but it looks like it plots multiple plots per bar.

            I need some clarification from you on what exactly you're trying to achieve here.

            What values are you trying to plot for each bar? The more detail here, the better.

            ​​​​​​​Thanks in advance; I look forward to assisting you further.
            Kate W.NinjaTrader Customer Service

            Comment


              #7
              Kate,

              First of all i need to understand what is going on with OBU. Even if i can make the RMMA happen if cma OBU return the wrong answer it wont solve the problem.

              As you can see in the charts i provided earlier there's a gap between CMA OBU and CMA OR.
              This is the CMA OnRender

              Code:
              double sum1 =0;
              double sum2 = 0;
              
                  for(int barIndex = foundIndex; barIndex <= ChartBars.ToIndex; barIndex++)
                  {
                  double closePrice = Bars.GetClose(barIndex);
                  double volumes = Bars.GetVolume(barIndex); 
              
                  double clovol = closePrice * volumes; 
              
              
                  sum1 += clovol++;
                  sum2 += volumes++;
              
                  cma = sum1 / sum2;
              
                  Value[0] = cma;
                  }
              It return the right answer in OBU, id line to know why.

              As for the RMMA you can see in attachment the code.

              I took that part to generate more than one cma in a new indicator.

              Code:
              if (CurrentBar < Period)
                              return;
              
                 int LowPeriod = 2;
                 int HighPeriod = 160;
                 int StepAverage = 3;
                 int count = 0;
                 for (int i = LowPeriod; i <= HighPeriod; i += StepAverage)
                 {
              
              
                  Values[count][0] = MTYCMA(i)[0];
              
                  Print(Values[count][0]);
              
                  count++;
              
                 }
              The problem it is not working the code wont generate more than one cma. It should generate a cma every 3 period from period 2 to 160.

              Actually if i replace the last part by:

              Code:
              [LEFT][COLOR=#4D4D4D][FONT=Helvetica][SIZE=13px]Value[0] = MTYCMA(0)[0];   // it is working but only the cma from MTYCMA show in the chart not the 53 cma's we should be able to see, well sometimes it does sometimes its not//[/SIZE][/FONT][/COLOR][/LEFT]
              Frank

              Thank you
              Attached Files

              Comment


                #8
                Hello frankduc,

                Thank you for your post.

                Four points:
                1. OnBarUpdate uses BarsAgo indexing.
                2. OnRender uses literal indexing.
                3. You can achieve the same results in both if proper indexing is minded.
                4. We do not advise doing data based calculations in OnRender because this is not performant. OnRender routines should be done for "what needs to be drawn", and calculations should be performed in OnBarUpdate.

                It seems like you're struggling with looping and indexes and I'd encourage you to use lots of prints to focus on how your loops are generating indexes and what those indexes are.

                I'm including an example script that shows correctly using indexing to achieve the same calculations in OnBarUpdate and OnRender. Open a NinjaScript Output window from the New menu, then apply this indicator to a chart. What it does is print the results of the same calculation in both OnBarUpdate and OnRender. The difference is that if you scroll the chart back in time, the OnRender version will recalculate from the rightmost bar on the chart back 20 bars, whereas the OnBarUpdate version will continue calculating on the currently forming bar. However, if you assigned the calculation from OnBarUpdate to a plot, you could use BarsAgo indexing to access the value from any past bar if you need to.

                Please let us know if we may be of further assistance to you.
                Attached Files
                Kate W.NinjaTrader Customer Service

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by algospoke, Yesterday, 06:40 PM
                2 responses
                19 views
                0 likes
                Last Post algospoke  
                Started by ghoul, Today, 06:02 PM
                3 responses
                14 views
                0 likes
                Last Post NinjaTrader_Manfred  
                Started by jeronymite, 04-12-2024, 04:26 PM
                3 responses
                45 views
                0 likes
                Last Post jeronymite  
                Started by Barry Milan, Yesterday, 10:35 PM
                7 responses
                20 views
                0 likes
                Last Post NinjaTrader_Manfred  
                Started by AttiM, 02-14-2024, 05:20 PM
                10 responses
                181 views
                0 likes
                Last Post jeronymite  
                Working...
                X