Accessing historical bar values outside of OnBarUpdate throws 'BarsAgo out of range' error

Hi guys, I need your help.

I’m working on an indicator that exports historical OHLCV data to a CSV file when a button is clicked. The export function loops through all loaded bars using a for-loop and tries to access data with Opens[0][i], Highs[0][i], etc. However, any index other than zero causes a runtime error:

“‘BarsAgo’ must be between 0 and 683 but was X”

This happens even though the chart has all historical data loaded, and Bars.Count confirms 683 bars.
Is there a correct way to loop over historical bars outside of OnBarUpdate() (e.g., inside a button click event) and safely access their OHLCV values?

This is the part of the code calling ExportCSV().

    private void ExportCSV()
    {
        try
        {
            int barCount = Bars != null ? Bars.Count : 0;
            if (barCount < 10)
            {
                Print($"❌ Zu wenige Bars zum Exportieren: {barCount}");
                return;
            }

            using (StreamWriter sw = new StreamWriter(exportFilePath, false))
            {
                sw.WriteLine("Datum;Zeit;Open;High;Low;Close;Volumen");
                
                // Starte bei der aktuellen Bar (0) und gehe bis zur ältesten Bar
                for (int i = 0; i < barCount; i++)
                {
                    try
                    {
                        Print($"Exportiere Bar {i}");
                        // Verwende CurrentBar - i statt i, da wir von der ältesten zur neuesten Bar exportieren
                        DateTime time = Times[0][i];
                        double open = Opens[0][i];
                        double high = Highs[0][i];
                        double low = Lows[0][i];
                        double close = Closes[0][i];
                        double volume = Volumes[0][i];

                        string line = $"{time:yyyy-MM-dd};{time:HH:mm};{open};{high};{low};{close};{volume}";
                        sw.WriteLine(line);
                    }
                    catch (Exception exBar)
                    {
                        Print($"⚠️ Fehler bei Bar {i}: {exBar.Message}");
                    }
                }
            }

            Print($"✅ Export abgeschlossen: {exportFilePath}");
        }
        catch (Exception ex)
        {
            Print("❌ Fehler beim Export: " + ex.Message);
        }
    }

Thank you for your help.

The index [i] the way that is used in your script does not indicate the bar number. It accesses data in the series i bars ago.

To get the values at a given bar, you can change your code to the following:

                    DateTime time = Times[0].GetValueAt(i);
                    double open = Opens[0].GetValueAt(i);
                    double high = Highs[0].GetValueAt(i);
                    double low = Lows[0].GetValueAt(i);
                    double close = Closes[0].GetValueAt(i);
                    double volume = Volumes[0].GetValueAt(i);

This will print all information from bar 0 all the way to the last bar in the correct sequence.

And if you don’t have multiple data series in your script and are just attempting to access values from price bars, you can further simplify to the following:
Note Time instead of Times[0], Open instead of Opens[0], etc.

                    DateTime time = Time.GetValueAt(i);
                    double open = Open.GetValueAt(i);
                    double high = High.GetValueAt(i);
                    double low = Low.GetValueAt(i);
                    double close = Close.GetValueAt(i);
                    double volume = Volume.GetValueAt(i);

Hope this helps.

3 Likes

Thank you so much. It works. :partying_face:

1 Like