ATR in MetaTrader 5 — MQL5 Source Code

A custom Average True Range indicator for MT5

ATR in MetaTrader 5
ATR in MetaTrader 5

ATR in MQL5 is a good exercise in building an indicator that plots in its own window and uses Wilder’s smoothing. See the explainer for why True Range includes the previous close.

What you’ll need

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

The source

//+------------------------------------------------------------------+
//|                                                  AlgoGen.ATR.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_separate_window
#property indicator_buffers 2
#property indicator_plots   1

#property indicator_label1  "ATR"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrOrangeRed
#property indicator_width1  2

input int InpPeriod = 14; // ATR period

double ATRBuffer[], TRBuffer[];

int OnInit()
  {
   SetIndexBuffer(0, ATRBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, TRBuffer,  INDICATOR_CALCULATIONS);
   IndicatorSetString(INDICATOR_SHORTNAME, "AlgoGen ATR(" + (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);

   // True Range for each bar.
   int trStart = (prev_calculated > 1) ? prev_calculated - 1 : 0;
   for(int i = trStart; i < rates_total; i++)
     {
      if(i == 0)
         TRBuffer[0] = high[0] - low[0];
      else
        {
         double hl = high[i] - low[i];
         double hc = MathAbs(high[i] - close[i - 1]);
         double lc = MathAbs(low[i]  - close[i - 1]);
         TRBuffer[i] = MathMax(hl, MathMax(hc, lc));
        }
     }

   // Wilder smoothing of TR.
   if(prev_calculated == 0)
     {
      double sum = 0.0;
      for(int j = 1; j <= InpPeriod; j++) sum += TRBuffer[j];
      ATRBuffer[InpPeriod] = sum / InpPeriod;
      for(int i = InpPeriod + 1; i < rates_total; i++)
         ATRBuffer[i] = (ATRBuffer[i - 1] * (InpPeriod - 1) + TRBuffer[i]) / InpPeriod;
     }
   else
     {
      for(int i = prev_calculated - 1; i < rates_total; i++)
         if(i > InpPeriod)
            ATRBuffer[i] = (ATRBuffer[i - 1] * (InpPeriod - 1) + TRBuffer[i]) / InpPeriod;
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Install & compile

  1. Drop it in MQL5/Indicators/, press F7.
  2. Drag onto a chart — a separate window shows the orange ATR line, matching the output chart.

Gotchas

  • The gap terms. hc and lc compare to close[i-1] — that’s what captures overnight/limit gaps. Dropping them collapses ATR into a plain range and defeats the point.
  • Wilder seed. The first ATR value is a simple average of the first InpPeriod True Ranges; subsequent bars use the 1/N recurrence.
  • Built-in / MQL4. MT5 has iATR; MQL4 has iATR too and the same recurrence applies if you hand-roll it. The custom version lets you also expose True Range for other calculations.

Same indicator elsewhere: Python, Pine Script, EasyLanguage, NinjaScript. Then backtest an ATR stop 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. New Concepts in Technical Trading Systems (Windsor Books)
  2. 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