Skip to main content

Indicator Development

Indicators are C# classes in the HyperionX.Custom.Indicators namespace. They inherit from Indicator and use HyperionX chart/data APIs.

Minimal Indicator

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Windows.Media;
using System.Xml.Serialization;
using HyperionX.Chart.Classes;
using HyperionX.Chart.Enums;
using HyperionX.Core.Attributes;
using HyperionX.Core.DataCalc;
using HyperionX.Core.Enums;

namespace HyperionX.Custom.Indicators;

public class MyMovingAverage : Indicator
{
private Plot _plot;

[HyperionXProperty]
[Display(Name = "Period", GroupName = "Parameters", Order = 1)]
public int Period { get; set; }

[Browsable(false)]
[XmlIgnore]
public Series<double> Average { get; set; }

public override void OnStateChanged()
{
if (State == State.SetDefaults)
{
Name = "My Moving Average";
Version = "1.0";
Period = 14;

_plot = new Plot(Colors.DeepSkyBlue, "Average", 2, PlotLineType.Solid, PlotChartType.Linear);
AddPanePlot(_plot);
}
else if (State == State.Configured)
{
Average = new Series<double>();
AddSeries(Average);
_plot.DataSource = Average;
}
}

public override void OnBarUpdate()
{
if (CurrentBar < Period)
return;

double sum = 0;
for (int i = 0; i < Period; i++)
sum += Input[i];

Average[0] = sum / Period;
}
}

Plots

A Plot defines how a series is rendered.

_plot = new Plot(
Colors.DeepSkyBlue,
"Average",
2,
PlotLineType.Solid,
PlotChartType.Linear);

Supported line types currently include:

  • PlotLineType.Solid
  • PlotLineType.Dashed

Supported chart types currently include:

  • PlotChartType.Linear
  • PlotChartType.Bars

Use _plot.DataSource = YourSeries; in State.Configured after creating and registering the series.

Series

Use Series<double> for indicator output.

[Browsable(false)]
[XmlIgnore]
public Series<double> Signal { get; set; }

Signal = new Series<double>();
AddSeries(Signal);
Signal[0] = Close[0] - Close[1];

Always register custom series with AddSeries(...) before writing values.

Built-In Indicators From Scripts

Generated indicator helper methods are available from the Indicator base class and from strategies. For example, the built-in SMA helper is generated from the SMA class:

private SMA _sma;

public override void OnStateChanged()
{
if (State == State.Configured)
_sma = SMA(14);
}

public override void OnBarUpdate()
{
double average = _sma[0];
}

Only call helpers that exist in your local Code Lab build. If a custom indicator class does not compile, its generated helper will not be available.

Drawing On The Chart

Use the HyperionX Draw API.

Draw.LineHorizontal(this, "last-close", Close[0], Brushes.DeepSkyBlue, 1, DashStyles.Dash);

Draw.FixedText(
this,
"status",
$"Close: {Close[0]:0.####}",
ChartHudAnchor.TopRight,
textBrush: Brushes.White,
backgroundBrush: Brushes.Black,
borderBrush: Brushes.DeepSkyBlue,
fontSize: 12);

Use Draw.FixedText(...) or Draw.HudText(...) for fixed panel text. Do not use Draw.TextFixed(...).

Custom Overlay Renderers

For advanced drawing, implement IChartOverlayRenderer and draw through IChartRenderContext instead of reaching directly into WPF chart internals.

The render context exposes:

  • Visible bar indexes
  • Price and pixel coordinate transforms
  • Price range and chart dimensions
  • Draw methods for lines, rectangles, circles, and text

This is the correct direction for advanced tools such as timers, labels, volume profile overlays, and order-flow overlays.

Stability Rules

  • Guard early bars with if (CurrentBar < requiredBars) return;.
  • Do not assume Input, indicators, or external series have enough bars.
  • Keep secrets out of parameters.
  • Do not mutate UI objects from background threads.
  • Let one indicator fail without taking down the chart.