Custom Script Development Guide
This guide is the practical checklist for writing HyperionX Code Lab scripts. Use it with the Extension Type Catalog, which identifies each category's lifecycle and current support status.
File Locations
Custom source files live under:
%USERPROFILE%\Documents\HyperionX\Bin\Custom
Common folders:
| Folder | Namespace | Base type |
|---|---|---|
Indicators | HyperionX.Custom.Indicators | Indicator |
Strategies | HyperionX.Custom.Strategies | Strategy |
BarTypes | HyperionX.Custom.BarTypes | CustomBarType / BarTypeBase |
Optimizers | HyperionX.Custom.Optimizers | Optimizer |
OptimizationFitnesses | HyperionX.Custom.OptimizationFitnesses | OptimizationFitness |
Commissions | HyperionX.Custom.Commissions | Commission |
MoneyManagements | HyperionX.Custom.MoneyManagements | MoneyManagement |
Addons | HyperionX.Custom.Addons | AddonBase |
Compile from Code Lab after editing. If a script does not compile, its generated helper methods and property-grid metadata may not update.
Indicator And Strategy Lifecycle
Indicators and strategies use two primary methods. Other extension types have their own contracts; do not assume they expose this lifecycle.
public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
Name = "My Script";
Version = "1.0";
Calculate = CalculateMode.OnBarClose;
}
else if (State == State.Configured)
{
// Allocate Series<T>, child indicators, panes, plots, or extra data series.
}
}
public override void OnBarUpdate()
{
if (CurrentBar < 20)
return;
// Calculation or trading logic.
}
Use State.SetDefaults for default values and display metadata. Use State.Configured for runtime objects that depend on chart data, child indicators, plots, or secondary series.
Calculate Modes
Calculate controls how often the script updates:
| Mode | Behavior |
|---|---|
CalculateMode.OnBarClose | Updates after each completed bar. This is the default and safest backtest mode. |
CalculateMode.OnEachTick | Updates on each real-time tick when tick data is available. |
CalculateMode.OnPriceChange | Updates only when the current price changes, reducing duplicate tick work. |
Use OnTickUpdate(ICandle candle, ICandle tick) for tick-aware logic. tick.IsFirstTickOfBar is useful when a real-time indicator needs to reset per-bar counters.
Parameters
Editable and optimizable parameters use [HyperionXProperty].
[HyperionXProperty]
[Display(Name = "ATR Period", GroupName = "Parameters", Order = 1)]
public int AtrPeriod { get; set; }
Rules:
- Set default parameter values in
State.SetDefaults. - Use clear
Displaynames and groups. - Keep parameter ranges realistic for optimization.
- Do not put credentials, API keys, or account secrets in script parameters.
Series And Bars
Primary bar series:
| Member | Meaning |
|---|---|
Open | Open price series. |
High | High price series. |
Low | Low price series. |
Close | Close price series. |
Volume | Volume series. |
DateTime | Bar timestamp series. |
Input | Selected input price series. |
The indexer uses bars ago. Close[0] is the current bar, Close[1] is one bar ago.
Always guard history access:
if (CurrentBar < Period + 1)
return;
double change = Close[0] - Close[Period];
Indicator Plots And Colors
Use Series<double> for output and Plot for chart display.
private Plot _plot;
[Browsable(false)]
[XmlIgnore]
public Series<double> Values { get; set; }
public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
_plot = new Plot(Colors.DeepSkyBlue, "Values", 2, PlotLineType.Solid, PlotChartType.Linear);
AddPanePlot(_plot);
}
else if (State == State.Configured)
{
Values = new Series<double>();
AddSeries(Values);
_plot.DataSource = Values;
}
}
For per-bar visuals:
| Member | Purpose |
|---|---|
BarBrush | Sets the candle body color for the current bar. |
CandleOutlineBrush | Sets the candle outline or wick color for the current bar. |
BackBrushAll | Sets the chart background behind the current bar. |
PlotColors | Sets per-bar plot colors where supported. |
These are protected script members. Use them inside OnBarUpdate() or real-time update logic.
Strategy Orders
Strategies should use managed HyperionX order helpers for normal workflows.
SetStopLossTicks("Long Entry", 20);
SetProfitTargetTicks("Long Entry", 40);
EnterLong(1, "Long Entry");
Managed entries and exits include market, limit, and stop-market variants. Use direct SubmitOrder(...) only when those helpers cannot express the required lifecycle.
Advanced direct signature:
Canonical signature:
SubmitOrder(
selectedBarsInProgress: 0,
orderAction: OrderAction.Buy,
orderType: OrderType.Market,
quantity: 1,
limitPrice: 0,
stopPrice: 0,
oco: "",
signalName: "Enter Long");
Compatibility signature:
SubmitOrder(
selectedBarsInProgress: 0,
orderAction: OrderAction.Sell,
orderType: OrderType.StopMarket,
quantity: 1,
limitPrice: 0,
auxiliaryPrice: 0,
stopPrice: stopPrice,
oco: "",
signalName: "Long Stop");
The compatibility overload accepts an extra price slot before stopPrice. For stop orders, a non-zero stopPrice wins. Otherwise, HyperionX uses auxiliaryPrice as the stop price.
Use CancelOrder(order) or Ctx.Orders.Cancel(orderId) for a tracked order. For cleanup, prefer Ctx.Orders.CancelStrategyWorking(), which is limited to working orders owned by the strategy and defaults to the current instrument. Ctx.Orders.CancelAccountWorking() is explicitly account-wide and can affect manual orders or other strategies. Ctx.Orders.CancelAllWorking() is obsolete and aliases the account-wide operation; do not use it in new code.
Order lifecycle hooks:
public override void OnOrderUpdate(Order order)
{
// Track accepted, working, filled, cancelled, or rejected order state.
}
public override void OnExecutionUpdate(Order order)
{
// React to fills.
}
Optimization And Validation Modules
Optimization depends on three things:
- Strategy parameters marked with
[HyperionXProperty]. - A selected optimizer that can generate parameter combinations.
- A selected fitness module that assigns a score.
Fitness modules implement:
public override void OnCalculatePerformanceValue(StrategyBase strategy)
{
Value = strategy.NetProfit ?? 0;
}
Commission modules implement:
public override double GetCommission(Trade trade)
{
return 0;
}
Backtests, optimization, and validation are only useful when the selected commission, slippage, account sizing, and instrument settings match the market being tested.
Porting Rules
When adapting script ideas from any other platform or public source, translate the concept into HyperionX APIs.
Do not paste unsupported APIs such as:
- Other-platform namespaces.
- Other-platform generated cache regions.
Draw.TextFixed.TextPosition.IsOverlay.- External
Buy(...),Sell(...),ShortSell(...), orCover(...)helpers.
Use the HyperionX equivalents:
Draw.FixedText(...)orDraw.HudText(...).ChartHudAnchor.AddPanePlot(...),AddPane(...), andIsAutoscale.SubmitOrder(...),EnterLong(...),EnterShort(...),ExitLong(...), andExitShort(...).
Build Checklist
Before using a script live:
- Compile it in Code Lab.
- Fix every compiler error.
- Check the platform log for disabled indicators or strategy calculation errors.
- Run on historical data.
- Test with an explicitly selected
LocalPaperaccount in playback or simulation. Playback does not select the account automatically; the current release-candidate build rejects external-account order mutations while Playback is active. - Confirm order quantities, stops, targets, commissions, and position state.
- Only then connect it to a broker account.