Keltner Channels in MetaTrader 5 — MQL5 Source Code

A modern EMA/ATR Keltner Channel for MT5

Keltner Channels in MetaTrader 5
Keltner Channels in MetaTrader 5

We previously published an MT4 Keltner Channel; here’s the modern MQL5 version, using MT5’s built-in indicator handles for the EMA and ATR so the code stays short and correct. See the explainer for the concept.

What you’ll need

  • MetaTrader 5 with MetaEditor
  • Save as AlgoGen.Keltner.mq5 under MQL5/Indicators/

The source

//+------------------------------------------------------------------+
//|                                              AlgoGen.Keltner.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  "Middle"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrOrangeRed
#property indicator_width1  2
#property indicator_label2  "Upper"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrMediumPurple
#property indicator_label3  "Lower"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrMediumPurple

input int    InpEmaPeriod = 20;
input int    InpAtrPeriod = 10;
input double InpMult       = 2.0;

double MidBuffer[], UpBuffer[], LoBuffer[];
int    emaHandle, atrHandle;

int OnInit()
  {
   SetIndexBuffer(0, MidBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, UpBuffer,  INDICATOR_DATA);
   SetIndexBuffer(2, LoBuffer,  INDICATOR_DATA);
   emaHandle = iMA(_Symbol, _Period, InpEmaPeriod, 0, MODE_EMA, PRICE_CLOSE);
   atrHandle = iATR(_Symbol, _Period, InpAtrPeriod);
   if(emaHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE)
      return(INIT_FAILED);
   IndicatorSetString(INDICATOR_SHORTNAME, "AlgoGen Keltner");
   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[])
  {
   int need = MathMax(InpEmaPeriod, InpAtrPeriod);
   if(rates_total < need) return(0);

   double ema[], atr[];
   if(CopyBuffer(emaHandle, 0, 0, rates_total, ema) <= 0) return(prev_calculated);
   if(CopyBuffer(atrHandle, 0, 0, rates_total, atr) <= 0) return(prev_calculated);

   int start = (prev_calculated > 0) ? prev_calculated - 1 : need;
   for(int i = start; i < rates_total; i++)
     {
      MidBuffer[i] = ema[i];
      UpBuffer[i]  = ema[i] + InpMult * atr[i];
      LoBuffer[i]  = ema[i] - InpMult * atr[i];
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Install & compile

  1. Drop it in MQL5/Indicators/, press F7.
  2. Drag onto a chart — three lines overlay price, matching the output chart.

Gotchas

  • Handles + CopyBuffer. Reusing iMA(MODE_EMA) and iATR guarantees your EMA and ATR match MT5’s own, so your channel is standard. Copying full arrays each pass is simple; cache for performance in production.
  • EMA vs SMA centerline. MODE_EMA gives the modern Keltner; the 1960 original used an SMA of typical price with a range-based band — a different indicator.
  • MT4 version. Our earlier MT4 post computes the bands with an EMA/ATR directly in MQL4; the math is the same, only the API differs.

Same indicator elsewhere: Python, Pine Script, EasyLanguage, NinjaScript. Then test a Keltner 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

  1. Technical indicator functions (MetaQuotes)

Historical research from the Algogen archive. Not investment advice.

Blog

Have a strategy idea?

Describe it in plain English, preview where your rules fire, then decide whether the evidence is worth a backtest.

Keep me postedHow it works