Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Help Needed with "OnBarUpdate" Method Error

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

    Help Needed with "OnBarUpdate" Method Error

    Hello,

    I'm encountering an issue with my NinjaTrader strategy where I'm getting the following error message:

    "Error on calling 'OnBarUpdate' method on bar 4: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing
    a series [barsAgo] with a value of 5 when there are only 4 bars on the chart."


    Here are the steps and code changes I've tried to resolve the issue:

    Initial Check for Bars Count:
    protected override void OnBarUpdate() { if (CurrentBar < Period + 1) return; // Rest of the code }

    Data Series Initialization:
    protected override void OnStateChange() { if (State == State.SetDefaults) { // Default settings } else if (State == State.DataLoaded) { priceData = new Series<double>(this); volumeData = new Series<double>(this); } }

    Ensuring Data Availability:
    priceData[0] = Close[0]; volumeData[0] = Volume[0]; if (priceData.Count < SomeThreshold || volumeData.Count < SomeThreshold) return; double[] filteredPriceData = ApplyFilter(priceData, SomeThreshold); double[] filteredVolumeData = ApplyFilter(volumeData, SomeThreshold); if (filteredPriceData.Length < Period + 1 || filteredVolumeData.Length < Period + 1) return;

    Loop Adjustments:
    private double CalculateER(double[] data, int period) { if (data.Length < period + 1) return 0; double priceChange = Math.Abs(data[data.Length - 1] - data[data.Length - 1 - period]); double sumOfAbsChanges = 0.0; for (int i = data.Length - period + 1; i < data.Length; i++) { sumOfAbsChanges += Math.Abs(data[i] - data[i - 1]); } return sumOfAbsChanges == 0 ? 0 : priceChange / sumOfAbsChanges; }

    Despite these efforts, the error persists. I suspect it might be related to how the logic checks bar indexes before there are enough bars in the series.

    Could someone provide guidance on the best practices to ensure that I am not accessing indexes that are out of range? Specifically, how should I handle conditions
    in OnBarUpdate to prevent this error from happening?

    Any advice or examples would be greatly appreciated!

    Thank you!
    António

    #2
    Hello antoniocruz1962,

    Do you know which specific line is throwing the error? Before doing the steps you mentioned you would need to know what line is having an error to better understand what needs fixed. As a first step please do the following process:

    Comment out all of your logic in OnBarUpdate
    Uncomment the first few lines and retest the script.
    If no error is observed repeat this process until you hit the error. The last uncommented lines should relate to the problem. Once that is known it may be more obvious what the problem is, if it is not Prints can be used to output the values at that time to get a better idea of what is happening.

    Comment


      #3
      Thank you for your prompt reply.
      The error (Error on calling 'OnBarUpdate' method on bar 3: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing
      a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.) occurs on the following:

      protected override void OnBarUpdate()
      {
      // Ensure there are enough bars to perform calculations
      if (CurrentBar < Math.Max(Period, 1) + 1)
      return;

      priceData[0] = Close[0];
      volumeData[0] = Volume[0];

      // Placeholder for future filtering logic
      double[] filteredPriceData = priceData; // Placeholder, replace with actual filtering logic
      double[] filteredVolumeData = volumeData; // Placeholder, replace with actual filtering logic
      }​

      Comment


        #4
        Hello antoniocruz1962,

        From the given code I don't see what would cause the error, which line specifically are you seeing the error with?

        Comment


          #5
          Hi Jesse
          I wanted to extend my heartfelt thanks for your help and patience with my recent coding issue.
          Following your suggestion, I commented out all the logic in the OnBarUpdate method. However, when
          I tried to uncomment that section of the code, everything stopped working.

          Could you please assist me in troubleshooting this issue further?
          Shall I post the full code here?

          Thank you once again for your time and expertise.
          António

          Comment


            #6
            Hello antoniocruz1962,

            When you comment your code out that will stop the script from plotting or doing what it normally does, that is not a problem. The purpose of using comments is to find the single line having an error, you need to isolate what single line of code produces the error when uncommented. Once that line is known it may be more obvious what the problem is but we need to know what specific line had the error before doing anything else.

            Another way to approach the problem is to add a print in between every line of code so you can trace where the prints stop. You would see your prints up to when you get the error, the last print seen would be the last line of code executed before the error. That can also help to isolate a specific line of code.

            Comment


              #7
              Hi Jesse, my apologies for the late reply.

              I'm still encountering an issue, that is driving me crazy, with my NinjaTrader strategy where I'm getting the following error message:

              "Error on calling 'OnBarUpdate' method on bar 4: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart."

              The strategy works perfectly with stocks but not with micro e-minis (specifically MNQ).

              Here are the steps and code changes I've tried to resolve the issue:

              Initial Check for Bars Count:
              protected override void OnBarUpdate()
              {
              if (CurrentBar < Period + 1)
              return;
              // Rest of the code
              }

              Data Series Initialization:
              protected override void OnStateChange()
              {
              if (State == State.SetDefaults)
              {
              // Default settings
              }
              else if (State == State.DataLoaded)
              {
              priceData = new Series<double>(this);
              volumeData = new Series<double>(this);
              }
              }
              Ensuring Data Availability:
              priceData[0] = Close[0];
              volumeData[0] = Volume[0];

              if (priceData.Count < SomeThreshold || volumeData.Count < SomeThreshold)
              return;

              double[] filteredPriceData = ApplyFilter(priceData, SomeThreshold);
              double[] filteredVolumeData = ApplyFilter(volumeData, SomeThreshold);

              if (filteredPriceData.Length < Period + 1 || filteredVolumeData.Length < Period + 1)
              return;
              Loop Adjustments:
              private double CalculateER(double[] data, int period)
              {
              if (data.Length < period + 1)
              return 0;

              double priceChange = Math.Abs(data[data.Length - 1] - data[data.Length - 1 - period]);
              double sumOfAbsChanges = 0.0;
              for (int i = data.Length - period + 1; i < data.Length; i++)
              {
              sumOfAbsChanges += Math.Abs(data[i] - data[i - 1]);
              }
              return sumOfAbsChanges == 0 ? 0 : priceChange / sumOfAbsChanges;
              }
              Despite these efforts, the error persists. I suspect it might be related to how the logic checks bar indexes before there are enough bars in the series.

              Full Code for Context:
              protected override void OnBarUpdate()
              {
              // Ensure there are enough bars to perform calculations
              if (CurrentBar < Math.Max(Period, 1) + 1)
              return;

              priceData[0] = Close[0];
              volumeData[0] = Volume[0];

              // Placeholder for future filtering logic
              double[] filteredPriceData = priceData; // Placeholder, replace with actual filtering logic
              double[] filteredVolumeData = volumeData; // Placeholder, replace with actual filtering logic
              }
              From the given code, the error seems to occur at the point where I access priceData[0] and volumeData[0].

              Request for Assistance:
              Is there a specific best practice for ensuring that bar indexes are always within range before accessing them?
              Could someone provide guidance on how to handle conditions in OnBarUpdate to prevent out-of-range errors effectively?
              Why might this strategy work for stocks but not for MNQ futures, and what adjustments should I consider for futures?
              Any advice or examples would be greatly appreciated!

              Thank you in advance for your help and patience!

              Best regards,
              António

              Comment


                #8
                Hello antoniocruz1962,

                I cant see from the snippets what may be wrong, have you found the specific line having an error yet? Making adjustments to the code at this point may or may not work, you might guess the right line and accidently solve it. To continue you need to follow the steps I previously mentioned and find the 1 specific line that has the error, once that is know I could assist further.

                I would also suggest making a sample file if you are trying to show a problem, I cant see from the extracts of code what may be wrong. Once you comment out the code to where the script works, uncomment 1 line at a time until you get the error. At that point make a note of the line having an error and attach the .cs file so we can view the full context.

                Comment


                  #9
                  Hi Jesse

                  I tried everything . The code that follows, has Kaufman Efficiency Ratio (ER) for price and volume data filtered using a Fourier Transform.
                  I fix it from on side, an error occurs on the other. Help in fixing this code will be very welcome.
                  region Using declarations
                  using System;
                  using System.Linq;
                  using System.ComponentModel;
                  using System.ComponentModel.DataAnnotations;
                  using NinjaTrader.Cbi;
                  using NinjaTrader.Gui.Tools;
                  using NinjaTrader.NinjaScript;
                  using NinjaTrader.Data;
                  using NinjaTrader.NinjaScript.Strategies;
                  using System.Windows.Media;
                  using NinjaTrader.Gui;
                  using NinjaTrader.NinjaScript.DrawingTools;
                  #endregion

                  namespace NinjaTrader.NinjaScript.Strategies
                  {
                  public class KaufmanEfficiencyStrategy : Strategy
                  {
                  [NinjaScriptProperty]
                  [Range(1, 100)]
                  [Display(Name = "Period", Order = 1, GroupName = "Parameters")]
                  public int Period { get; set; }

                  [NinjaScriptProperty]
                  [Range(1, 50)]
                  [Display(Name = "CutoffFrequency", Order = 2, GroupName = "Parameters")]
                  public int CutoffFrequency { get; set; }

                  private Series<double> priceData;
                  private Series<double> volumeData;

                  protected override void OnStateChange()
                  {
                  if (State == State.SetDefaults)
                  {
                  Description = @"Strategy using Kaufman Efficiency Ratio and Fourier Transform";
                  Name = "KaufmanEfficiencyStrategy";
                  Calculate = Calculate.OnEachTick;
                  EntriesPerDirection = 1;
                  EntryHandling = EntryHandling.AllEntries;
                  IsExitOnSessionCloseStrategy = true;
                  ExitOnSessionCloseSeconds = 30;
                  IsInstantiatedOnEachOptimizationIteration = false;

                  Period = 14;
                  CutoffFrequency = 3;

                  AddPlot(Brushes.Blue, "FilteredPriceER");
                  AddPlot(Brushes.Red, "FilteredVolumeER");
                  }
                  else if (State == State.DataLoaded)
                  {
                  priceData = new Series<double>(this);
                  volumeData = new Series<double>(this);
                  }
                  }

                  protected override void OnBarUpdate()
                  {
                  // Ensure there are enough bars to perform calculations
                  if (CurrentBar < Math.Max(Period, CutoffFrequency) + 1)
                  return;

                  // Ensure data series have enough values
                  if (priceData.Count < Math.Max(Period, CutoffFrequency) + 1 || volumeData.Count < Math.Max(Period, CutoffFrequency) + 1)
                  return;

                  priceData[0] = Close[0];
                  volumeData[0] = Volume[0];

                  double[] filteredPriceData = ApplyFourierFilter(priceData, CutoffFrequency);
                  double[] filteredVolumeData = ApplyFourierFilter(volumeData, CutoffFrequency);

                  // Ensure we have enough filtered data
                  if (filteredPriceData.Length < Period + 1 || filteredVolumeData.Length < Period + 1)
                  return;

                  double filteredPriceER = CalculateKaufmanER(filteredPriceData, Period);
                  double filteredVolumeER = CalculateKaufmanER(filteredVolumeData, Period);

                  Values[0][0] = filteredPriceER;
                  Values[1][0] = filteredVolumeER;

                  // Setting background color for visual indication
                  if (filteredPriceER > 0.5 && filteredVolumeER > 0.5)
                  {
                  BackBrush = Brushes.LightGreen;
                  }
                  else if (filteredPriceER < 0.3 && filteredVolumeER < 0.3)
                  {
                  BackBrush = Brushes.LightCoral;
                  }
                  else
                  {
                  BackBrush = Brushes.Transparent;
                  }

                  // Buy and Sell logic
                  if (filteredPriceER > 0.5 && filteredVolumeER > 0.5 && Position.MarketPosition != MarketPosition.Long)
                  {
                  EnterLong("BuyOrder");
                  }
                  else if (filteredPriceER < 0.3 && filteredVolumeER < 0.3 && Position.MarketPosition != MarketPosition.Short)
                  {
                  EnterShort("SellOrder");
                  }
                  }

                  private double CalculateKaufmanER(double[] data, int period)
                  {
                  if (data.Length < period + 1)
                  return 0;

                  double priceChange = Math.Abs(data[data.Length - 1] - data[data.Length - 1 - period]);
                  double sumOfAbsChanges = 0.0;
                  for (int i = data.Length - period; i < data.Length; i++)
                  {
                  sumOfAbsChanges += Math.Abs(data[i] - data[i - 1]);
                  }
                  return sumOfAbsChanges == 0 ? 0 : priceChange / sumOfAbsChanges;
                  }

                  private double[] ApplyFourierFilter(Series<double> data, int cutoffFrequency)
                  {
                  if (data.Count < cutoffFrequency)
                  return new double[0];

                  int n = data.Count;
                  double[] transformedData = new double[n];
                  for (int i = 0; i < n; i++)
                  {
                  transformedData[i] = data[i];
                  }

                  Complex[] fftData = new Complex[n];
                  for (int i = 0; i < n; i++)
                  {
                  fftData[i] = new Complex(transformedData[i], 0);
                  }
                  FourierTransform.FFT(fftData, FourierTransform.Direction.Forward);

                  for (int i = cutoffFrequency; i < n - cutoffFrequency; i++)
                  {
                  fftData[i] = Complex.Zero;
                  }

                  FourierTransform.FFT(fftData, FourierTransform.Direction.Backward);
                  for (int i = 0; i < n; i++)
                  {
                  transformedData[i] = fftData[i].Real;
                  }
                  return transformedData;
                  }

                  private struct Complex
                  {
                  public double Real;
                  public double Imaginary;

                  public Complex(double real, double imaginary)
                  {
                  Real = real;
                  Imaginary = imaginary;
                  }

                  public static Complex Zero => new Complex(0, 0);
                  public static Complex One => new Complex(1, 0); // Added this line

                  public double Magnitude => Math.Sqrt(Real * Real + Imaginary * Imaginary);

                  public static Complex operator +(Complex a, Complex b)
                  {
                  return new Complex(a.Real + b.Real, a.Imaginary + b.Imaginary);
                  }

                  public static Complex operator -(Complex a, Complex b)
                  {
                  return new Complex(a.Real - b.Real, a.Imaginary - b.Imaginary);
                  }

                  public static Complex operator *(Complex a, Complex b)
                  {
                  return new Complex(a.Real * b.Real - a.Imaginary * b.Imaginary, a.Real * b.Imaginary + a.Imaginary * b.Real);
                  }
                  }

                  private class FourierTransform
                  {
                  public enum Direction
                  {
                  Forward,
                  Backward
                  }

                  public static void FFT(Complex[] data, Direction direction)
                  {
                  int n = data.Length;
                  int m = (int)Math.Log(n, 2);

                  for (int i = 0; i < n; i++)
                  {
                  int j = BitReverse(i, m);
                  if (j > i)
                  {
                  var temp = data[i];
                  data[i] = data[j];
                  data[j] = temp;
                  }
                  }

                  for (int s = 1; s <= m; s++)
                  {
                  int m2 = 1 << s;
                  Complex wm = direction == Direction.Forward ?
                  new Complex(Math.Cos(-2.0 * Math.PI / m2), Math.Sin(-2.0 * Math.PI / m2)) :
                  new Complex(Math.Cos(2.0 * Math.PI / m2), Math.Sin(2.0 * Math.PI / m2));
                  for (int k = 0; k < n; k += m2)
                  {
                  Complex w = Complex.One;
                  for (int j = 0; j < m2 / 2; j++)
                  {
                  Complex t = w * data[k + j + m2 / 2];
                  Complex u = data[k + j];
                  data[k + j] = u + t;
                  data[k + j + m2 / 2] = u - t;
                  w *= wm;
                  }
                  }
                  }

                  if (direction == Direction.Backward)
                  {
                  for (int i = 0; i < n; i++)
                  {
                  data[i].Real /= n;
                  data[i].Imaginary /= n;
                  }
                  }
                  }

                  private static int BitReverse(int n, int bits)
                  {
                  int reversedN = n;
                  int count = bits - 1;

                  n >>= 1;
                  while (n > 0)
                  {
                  reversedN = (reversedN << 1) | (n & 1);
                  count--;
                  n >>= 1;
                  }
                  return ((reversedN << count) & ((1 << bits) - 1));
                  }
                  }
                  }
                  }

                  Kindest regards
                  António

                  Comment


                    #10
                    Hello antoniocruz1962,

                    Our support cannot debug the script for you but we can make suggestions on how you can debug your logic. Have you commented out your code to find the specific line that is having an error? That is really the first step in finding the solution, without doing that no progress will be made. An alternative to commenting out the logic is to add prints into your code between each line of code. You can increment a number in each print so when the error happens the last print will highlight the last successful code that was execution, the code following that had an error.

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by argusthome, 03-08-2026, 10:06 AM
                    0 responses
                    83 views
                    0 likes
                    Last Post argusthome  
                    Started by NabilKhattabi, 03-06-2026, 11:18 AM
                    0 responses
                    47 views
                    0 likes
                    Last Post NabilKhattabi  
                    Started by Deep42, 03-06-2026, 12:28 AM
                    0 responses
                    29 views
                    0 likes
                    Last Post Deep42
                    by Deep42
                     
                    Started by TheRealMorford, 03-05-2026, 06:15 PM
                    0 responses
                    32 views
                    0 likes
                    Last Post TheRealMorford  
                    Started by Mindset, 02-28-2026, 06:16 AM
                    0 responses
                    66 views
                    0 likes
                    Last Post Mindset
                    by Mindset
                     
                    Working...
                    X