Series And Bars Reference
HyperionX series use bars-ago indexing. Close[0] is the current bar, Close[1] is the previous bar, and Close[10] is ten bars ago.
Bar Counts And Absolute Indexes
CurrentBar is the number of primary bars processed by the script, not a zero-based absolute index. On the first processed bar, CurrentBar is 1, while the corresponding absolute storage index is 0.
The bars-ago mapping is:
absolute index = CurrentBar - 1 - barsAgo
This is why a read of Close[1] requires CurrentBar >= 2. CurrentBars[seriesIndex] follows the same count convention for each configured series.
In the earlier documented implementation, unavailable primary OHLCV reads could return 0 and generic Series<T> reads could return default(T); some specialized secondary accessors could reject invalid indexes. Guard bars-ago reads with CurrentBar, CurrentBars, or V2 IsReady(...). Absolute IsValidPoint(...) checks storage indexes and is not a substitute for knowing how many bars have been processed.
Unreleased Strict-Indexer Migration
Reviewed 1.1.27 development source rejects negative or not-yet-available bars-ago reads and writes with ArgumentOutOfRangeException, including SetValid(barsAgo). The changelog labels this change Unreleased; do not infer that the stable feed or signed 1.1.25 package contains it. For an offset n, require at least n + 1 processed bars on the relevant timeline before accessing it. Preloaded future bars are not available script history.
Tolerant absolute APIs such as GetValueAt, GetRange, and IsValidPoint keep their existing behavior. Use these only when absolute storage access is intended, not to bypass script history guards. See the documentation version map.
Series Interface
Common series methods and properties:
| Member | Purpose |
|---|---|
series[0] | Get or set the current bars-ago value. |
Count | Number of values in the series. |
GetValueAt(index) | Reads by zero-based absolute internal index; the core Series<T> implementation returns default(T) when the index is invalid. |
GetRange(startIndex, count) | Reads a range by absolute index. |
IsValidPoint(index) | Checks whether an absolute index is valid. |
SetValid(barsAgo) | Marks a bars-ago point as valid; guard its availability before calling it. |
For normal script logic, prefer bars-ago access.
Custom Output Series
Indicators should register custom series before writing to them.
[Browsable(false)]
[XmlIgnore]
public Series<double> Signal { get; set; }
public override void OnStateChanged()
{
if (State == State.Configured)
{
Signal = new Series<double>();
AddSeries(Signal);
}
}
Write the current value in OnBarUpdate() only after at least two bars are available for the following fragment (CurrentBar >= 2), because it also reads Close[1].
Signal[0] = Close[0] - Close[1];
Extra Data Series
Use AddDataSeries(...) in State.Configured.
AddDataSeries(DataSeriesType.Minute, 60);
AddDataSeries(DataSeriesType.Day, 1, "BTC");
Available data series types:
| Type | Description |
|---|---|
DataSeriesType.Tick | Tick bars. |
DataSeriesType.Second | Second bars. |
DataSeriesType.Minute | Minute bars. |
DataSeriesType.Hour | Hour bars. |
DataSeriesType.Day | Daily bars. |
DataSeriesType.Week | Weekly bars. |
DataSeriesType.Month | Monthly bars. |
Multi-Series Access
After an extra series is configured:
double primaryClose = Closes[0][0];
double hourlyClose = Closes[1][0];
double hourlyVolume = Volumes[1][0];
System.DateTime hourlyTime = DateTimes[1][0];
Guard both primary and secondary series.
if (CurrentBars[0] < 50 || CurrentBars[1] < 10)
return;
Use BarsInProgress when logic should only run for one series.
if (BarsInProgress != 0)
return;
During a secondary-series callback, BarsInProgress identifies the series being processed, while CurrentBar remains the primary-series count. Route reads through the plural collections and guard the active count explicitly:
int seriesIndex = BarsInProgress;
if (CurrentBars[seriesIndex] < 2)
return;
double current = Closes[seriesIndex][0];
double previous = Closes[seriesIndex][1];
Bar Timing Context
Ctx.MarketData exposes time-based helpers:
System.TimeSpan? duration = Ctx.MarketData.GetCurrentBarDuration();
System.TimeSpan? remaining = Ctx.MarketData.GetTimeRemainingInBar();
System.DateTime? openTime = Ctx.MarketData.GetCurrentBarOpenTime();
System.DateTime? closeTime = Ctx.MarketData.GetCurrentBarCloseTime();
Tick series may not have a predictable close time. These helpers can return null.
Common Mistakes
| Problem | Fix |
|---|---|
Reading Close[1] on the first bar | Guard with if (CurrentBar < 2) return;. |
| Treating an out-of-range numeric read as real zero data | Guard the processed bar count; earlier builds can return fallback values, while strict development builds throw. |
Using DateTime.Now and getting a compile issue | Use System.DateTime.Now; DateTime is also a bar series. |
Adding a data series in OnBarUpdate() | Add it in State.Configured. |
Writing a series before AddSeries(...) | Allocate and register in State.Configured. |
Accessing Closes[1] before the extra series is ready | Guard CurrentBars[1]. |