Skip to main content

Custom Script Development Guide

This guide is the practical checklist for writing HyperionX Code Lab scripts. Use it when creating indicators, strategies, optimization fitness modules, commissions, and other custom script files.

File Locations

Custom source files live under:

%USERPROFILE%\Documents\HyperionX\Bin\Custom

Common folders:

FolderNamespaceBase type
IndicatorsHyperionX.Custom.IndicatorsIndicator
StrategiesHyperionX.Custom.StrategiesStrategy
OptimizersHyperionX.Custom.OptimizersOptimizer
OptimizationFitnessesHyperionX.Custom.OptimizationFitnessesOptimizationFitness
CommissionsHyperionX.Custom.CommissionsCommission
MoneyManagementsHyperionX.Custom.MoneyManagementsMoney management base

Compile from Code Lab after editing. If a script does not compile, its generated helper methods and property-grid metadata may not update.

Script Lifecycle

Most scripts use two methods:

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:

ModeBehavior
CalculateMode.OnBarCloseUpdates after each completed bar. This is the default and safest backtest mode.
CalculateMode.OnEachTickUpdates on each real-time tick when tick data is available.
CalculateMode.OnPriceChangeUpdates 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 Display names 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:

MemberMeaning
OpenOpen price series.
HighHigh price series.
LowLow price series.
CloseClose price series.
VolumeVolume series.
DateTimeBar timestamp series.
InputSelected 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:

MemberPurpose
BarBrushSets the candle body color for the current bar.
CandleOutlineBrushSets the candle outline or wick color for the current bar.
BackBrushAllSets the chart background behind the current bar.
PlotColorsSets 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 HyperionX order APIs.

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) for tracked orders and Ctx.Orders.CancelAllWorking() when a strategy needs to cancel every working order in its strategy context.

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(...), or Cover(...) helpers.

Use the HyperionX equivalents:

  • Draw.FixedText(...) or Draw.HudText(...).
  • ChartHudAnchor.
  • AddPanePlot(...), AddPane(...), and IsAutoscale.
  • SubmitOrder(...), EnterLong(...), EnterShort(...), ExitLong(...), and ExitShort(...).

Build Checklist

Before using a script live:

  1. Compile it in Code Lab.
  2. Fix every compiler error.
  3. Check the platform log for disabled indicators or strategy calculation errors.
  4. Run on historical data.
  5. Test in playback or simulation.
  6. Confirm order quantities, stops, targets, commissions, and position state.
  7. Only then connect it to a broker account.