NinjaTrader indicators are C# classes, and the Simple Moving Average is the
gentlest possible introduction to writing one. Yes, NinjaTrader has SMA() built
in — but building it yourself teaches you the OnBarUpdate lifecycle you’ll need
for everything else. See the explainer for the concept.
What you’ll need
- NinjaTrader 8
- New → NinjaScript Editor → Indicators → New Indicator, name it
AlgoGenSMA
The source
We keep an efficient running sum so the indicator is O(1) per bar rather than re-summing the window every time.
#region Using declarations
using System;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.Indicators;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class AlgoGenSMA : Indicator
{
private double runningSum;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "AlgoGen SMA";
Description = "Simple Moving Average (equal-weighted)";
Period = 20;
IsOverlay = true; // draws on the price panel
AddPlot(new Stroke(System.Windows.Media.Brushes.OrangeRed, 2), PlotStyle.Line, "SMA");
}
else if (State == State.DataLoaded)
{
runningSum = 0;
}
}
protected override void OnBarUpdate()
{
runningSum += Close[0];
if (CurrentBar >= Period)
runningSum -= Close[Period]; // drop the price leaving the window
if (CurrentBar >= Period - 1)
Value[0] = runningSum / Period;
}
#region Properties
[NinjaScriptProperty]
[System.ComponentModel.DataAnnotations.Range(1, int.MaxValue)]
[System.ComponentModel.Display(Name = "Period", GroupName = "Parameters", Order = 0)]
public int Period { get; set; }
#endregion
}
}
Compile & apply
- Press F5 in the NinjaScript Editor to compile — it builds clean.
- Right-click a chart → Indicators → add AlgoGen SMA, set the period.
Because
IsOverlay = true, it draws on price, matching the output chart above.
Gotchas
Close[Period], notClose[Period-1]. On the bar whereCurrentBar == Period, the price that must leave the window is the onePeriodbars back. Off-by-one here is the classic SMA bug; the guardCurrentBar >= Periodmakes sure that look-back exists before we subtract.Value[0]is the plot. With a singleAddPlot,Value[0]is the SMA series other scripts can reference.- Built-in shortcut. In a strategy you can just call
SMA(Close, Period)[0]. The hand-rolled version is for learning and for a plot you fully control.
That’s the five-language set: Python, MQL5, Pine Script, EasyLanguage, and this one. Now find out if an SMA crossover actually beats buy-and-hold in AlgoGen.
This post is educational, not financial advice. Indicators describe the past; they don’t predict the future. Backtest anything before you risk real money on it.
Sources and further reading
- Gartley and the early use of moving averages (CMT Association)
- NinjaScript system indicator methods (NinjaTrader)
