Donchian Channels in NinjaScript use the built-in MAX/MIN (or HighestBar-style
lookbacks) for the rolling extremes. See
the explainer for the concept and the breakout
shift.
What you’ll need
- NinjaTrader 8
- New → NinjaScript Editor → Indicators → New Indicator, name it
AlgoGenDonchian
The source
#region Using declarations
using System;
using System.Windows.Media;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.Indicators;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class AlgoGenDonchian : Indicator
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "AlgoGen Donchian";
Description = "Donchian Channel (highest high / lowest low)";
Period = 20;
IsOverlay = true;
AddPlot(new Stroke(Brushes.MediumPurple, 1), PlotStyle.Line, "Upper");
AddPlot(new Stroke(Brushes.OrangeRed, 2), PlotStyle.Line, "Middle");
AddPlot(new Stroke(Brushes.MediumPurple, 1), PlotStyle.Line, "Lower");
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < Period - 1)
return;
double hh = MAX(High, Period)[0];
double ll = MIN(Low, Period)[0];
Upper[0] = hh;
Lower[0] = ll;
Middle[0] = (hh + ll) / 2.0;
}
#region Properties
[NinjaScriptProperty][System.ComponentModel.DataAnnotations.Range(1, int.MaxValue)]
[System.ComponentModel.Display(Name = "Period", GroupName = "Parameters", Order = 0)]
public int Period { get; set; }
[Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> Upper => Values[0];
[Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> Middle => Values[1];
[Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> Lower => Values[2];
#endregion
}
}
Compile & apply
- Press F5 to compile.
- Add AlgoGen Donchian to a chart; the stepped channel overlays price, matching the output chart.
Gotchas
MAX/MINbuilt-ins.MAX(High, Period)[0]is the highest high over the window — cleaner than a manual loop and matches the platform.- Prior-bar breakout in a strategy. For a signal, compare
Close[0]toUpper[1]/Lower[1](the prior bar’s channel):
if (Close[0] > Upper[1]) EnterLong(); // new N-bar high
if (Close[0] < MIN(Low, 10)[1]) ExitLong(); // 10-bar low exit (Turtle-style)
- Warm-up. The
CurrentBar < Period - 1guard ensures the window is full. - Asymmetric entry/exit. The Turtle system used different lengths for entries
(20/55) and exits (10/20). In a strategy, use one
MAX/MINlength for entries and a shorter one for exits — the classic “let winners run, cut losers on a shorter channel” structure. - Width squeeze.
(Upper[0] - Lower[0]) / Close[0]at a multi-bar low flags a coiled market; breakouts out of a squeeze tend to be cleaner than breakouts in open range.
That’s the five-language set: Python, MQL5, Pine Script, EasyLanguage, and this one. Now test a Donchian breakout 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
- NinjaScript system indicator methods (NinjaTrader)
