Donchian Channels aren’t a default MT5 indicator, so this is a useful one to own. The math is a rolling high/low; the subtlety is the breakout shift (see the explainer).
What you’ll need
- MetaTrader 5 with MetaEditor
- Save as
AlgoGen.Donchian.mq5underMQL5/Indicators/
The source
//+------------------------------------------------------------------+
//| AlgoGen.Donchian.mq5 |
//| Copyright 2026, AlgoGen |
//| https://www.algogen.io |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, AlgoGen"
#property link "https://www.algogen.io"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_label1 "Upper"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrMediumPurple
#property indicator_label2 "Middle"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrOrangeRed
#property indicator_label3 "Lower"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrMediumPurple
input int InpPeriod = 20;
double UpBuffer[], MidBuffer[], LoBuffer[];
int OnInit()
{
SetIndexBuffer(0, UpBuffer, INDICATOR_DATA);
SetIndexBuffer(1, MidBuffer, INDICATOR_DATA);
SetIndexBuffer(2, LoBuffer, INDICATOR_DATA);
for(int p = 0; p < 3; p++)
PlotIndexSetInteger(p, PLOT_DRAW_BEGIN, InpPeriod - 1);
IndicatorSetString(INDICATOR_SHORTNAME, "AlgoGen Donchian(" + (string)InpPeriod + ")");
return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total, const int prev_calculated,
const datetime &time[], const double &open[],
const double &high[], const double &low[],
const double &close[], const long &tick_volume[],
const long &volume[], const int &spread[])
{
if(rates_total < InpPeriod) return(0);
int start = (prev_calculated > InpPeriod) ? prev_calculated - 1 : InpPeriod - 1;
for(int i = start; i < rates_total; i++)
{
double hh = high[i], ll = low[i];
for(int j = 1; j < InpPeriod; j++)
{
if(high[i - j] > hh) hh = high[i - j];
if(low[i - j] < ll) ll = low[i - j];
}
UpBuffer[i] = hh;
LoBuffer[i] = ll;
MidBuffer[i] = (hh + ll) / 2.0;
}
return(rates_total);
}
//+------------------------------------------------------------------+
Install & compile
- Drop it in
MQL5/Indicators/, press F7. - Drag onto a chart — the stepped upper/lower/mid channel overlays price, matching the output chart.
Gotchas
- Prior-bar breakout in an EA. For a signal, compare the current close to
UpBuffer[i-1]/LoBuffer[i-1](the channel excluding the current bar). UsingUpBuffer[i]would include today’s own high and never trigger. - Built-in high/low. You can also use
iHighest/iLowestinstead of the inner loop; the loop is shown for clarity. - MQL4. Same math; swap the
OnCalculatesignature and buffer setup, or useiHighest/iLowest.
Same indicator elsewhere: Python, Pine Script, EasyLanguage, NinjaScript. Then 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
- Technical indicator functions (MetaQuotes)
