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.SolidPlotLineType.Dashed
Supported chart types currently include:
PlotChartType.LinearPlotChartType.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.