Lifecycle Reference
HyperionX scripts are state-driven. Most script setup belongs in OnStateChanged(). Calculation logic belongs in OnBarUpdate().
State Values
The runtime state enum currently includes:
| State | Meaning |
|---|---|
Undefined | Script is not initialized or has been stopped. |
SetDefaults | Set name, version, default parameters, and default plot definitions. |
Configured | Allocate runtime series, add plots/panes, add extra data series, and create child indicators. |
Historical | Historical calculation is running. |
Finalized | Declared enum value. The general 1.1.10 calculation host does not reliably notify scripts of this state. |
Calculated | Calculation finished. |
Playback | Playback/replay mode is running. |
RealTime | Live calculation is running. |
DataLoaded | Data has loaded. |
Transition | Runtime is moving between states. |
Terminated | Declared enum value. No reliable general script termination callback was verified in the reviewed host. |
Standard Pattern
public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
Name = "My Script";
Version = "1.0";
}
else if (State == State.Configured)
{
// Allocate series, child indicators, panes, plots, and extra series.
}
}
public override void OnBarUpdate()
{
if (CurrentBar < 20)
return;
// Per-bar logic.
}
Setup Responsibilities
Use State.SetDefaults for stable defaults:
NameVersion[HyperionXProperty]default values- plot appearance defaults
- non-runtime constants
Use State.Configured for runtime objects:
Series<double>instancesAddSeries(...)AddPane(...)AddPanePlot(...)- plot
DataSourceassignment - child indicators such as
SMA(20) AddDataSeries(...)
Update Methods
| Method | Purpose |
|---|---|
OnBarUpdate() | Main per-bar calculation. |
OnTickUpdate(ICandle candle, ICandle tick) | Tick update hook when tick data is available. |
OnMarketData(MarketDataEventArgs marketData) | Market data update hook with price, volume, bid/ask volume, and trade count fields. |
OnMarketDepth(MarketDepthEventArgs marketDepth) | Depth snapshot hook after depth data is requested or subscribed. |
OnAfterBarUpdate() | Runtime post-update hook. Most scripts do not override it. |
OnConnectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus, string connectionName) | Connection state changes. |
Bar Guards
Always check CurrentBar before reading prior bars.
if (CurrentBar < Period + 1)
return;
double prior = Close[1];
double older = Close[Period];
The indexer uses bars ago. Close[0] is the current bar. Close[1] is one bar ago.
Internally, CurrentBar behaves as the count of processed bars, and series translate [0] to the latest processed absolute index. Out-of-range reads can return a default value such as 0 instead of throwing, so a plausible number does not prove the requested bar existed. Guards remain mandatory.
Multi-Series Timing
BarsInProgress identifies the series currently being processed. Primary series is 0. Extra data series use indexes starting at 1.
if (BarsInProgress != 0)
return;
Use CurrentBars[seriesIndex] before reading extra series values.
During a secondary-series callback, read the matching collection member—for example, Closes[BarsInProgress][0]—rather than assuming the primary Close series represents the series that triggered the update.
Calculation Mode
Scripts expose Calculate, which is a CalculateMode value. The default is OnBarClose.
| Mode | Behavior |
|---|---|
CalculateMode.OnBarClose | Runs after each completed bar. Use this for stable historical and backtest logic. |
CalculateMode.OnEachTick | Runs on every tick when tick data is available. |
CalculateMode.OnPriceChange | Runs when the current trade price changes, which avoids duplicate same-price tick work. |
For tick-aware scripts, override OnTickUpdate(ICandle candle, ICandle tick). candle is the active bar and tick is the incoming tick. Use tick.IsFirstTickOfBar when the script must reset per-bar real-time counters.
Live tick delivery to OnTickUpdate(...) and OnMarketData(...) is independent of Calculate. The calculation mode controls whether additional OnBarUpdate() calls occur on bar close, each tick, or price change; it does not subscribe or unsubscribe the dedicated tick/market-data callbacks. Keep each callback idempotent enough to avoid counting the same event twice.
The current chart/data context determines when real-time or playback scripts receive updates. Strategy developers should explicitly test the same mode they intend to trade.
Cleanup Boundary
Do not depend on State.Finalized or State.Terminated for required cleanup. The values exist in the enum, but the reviewed general calculation host does not provide a reliable native callback for them.
Use an explicitly documented host-specific cleanup contract where one exists. For example, an add-on receives OnUnload() after a successful load, but an add-on whose OnLoad() throws must roll back its own partial registrations before rethrowing because a later unload callback is not guaranteed. Avoid long-lived threads, event subscriptions, timers, or unmanaged resources unless their owning host has a verified release path.