MACD in MetaTrader 5 — MQL5 Source Code

A full MACD with the histogram MT5's built-in leaves out

MACD in MetaTrader 5
MACD in MetaTrader 5

Here’s a fun quirk: MetaTrader’s built-in MACD draws the MACD line as a histogram and skips the classic MACD-vs-signal histogram entirely. So building your own isn’t just an exercise — it’s how you get the real, three-component MACD from the explainer on an MT5 chart.

What you’ll need

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

The source

We build the two EMAs onto internal buffers, subtract them for the MACD line, EMA-smooth that for the signal, and plot the difference as the histogram.

//+------------------------------------------------------------------+
//|                                                 AlgoGen.MACD.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 5
#property indicator_plots   3

#property indicator_label1  "Histogram"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrMediumSeaGreen
#property indicator_width1  2
#property indicator_label2  "MACD"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrDodgerBlue
#property indicator_width2  2
#property indicator_label3  "Signal"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrOrangeRed
#property indicator_width3  2

input int InpFast   = 12; // Fast EMA period
input int InpSlow   = 26; // Slow EMA period
input int InpSignal = 9;  // Signal EMA period

double HistBuffer[], MacdBuffer[], SignalBuffer[];
double FastEMA[], SlowEMA[];

int OnInit()
  {
   SetIndexBuffer(0, HistBuffer,   INDICATOR_DATA);
   SetIndexBuffer(1, MacdBuffer,   INDICATOR_DATA);
   SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA);
   SetIndexBuffer(3, FastEMA,      INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, SlowEMA,      INDICATOR_CALCULATIONS);
   IndicatorSetString(INDICATOR_SHORTNAME,
      StringFormat("AlgoGen MACD(%d,%d,%d)", InpFast, InpSlow, InpSignal));
   return(INIT_SUCCEEDED);
  }

// Recursive EMA helper writing into buf[i].
void EmaStep(const double &price[], double &buf[], int i, int period)
  {
   double k = 2.0 / (period + 1.0);
   if(i == 0) buf[0] = price[0];
   else       buf[i] = price[i] * k + buf[i - 1] * (1.0 - k);
  }

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 start = (prev_calculated > 0) ? prev_calculated - 1 : 0;

   for(int i = start; i < rates_total; i++)
     {
      EmaStep(close, FastEMA, i, InpFast);
      EmaStep(close, SlowEMA, i, InpSlow);
      MacdBuffer[i] = FastEMA[i] - SlowEMA[i];
      // Signal = EMA of the MACD line.
      double k = 2.0 / (InpSignal + 1.0);
      SignalBuffer[i] = (i == 0) ? MacdBuffer[0]
                        : MacdBuffer[i] * k + SignalBuffer[i - 1] * (1.0 - k);
      HistBuffer[i] = MacdBuffer[i] - SignalBuffer[i];
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Install & compile

  1. Drop AlgoGen.MACD.mq5 in MQL5/Indicators/ and press F7 to compile.
  2. Drag it onto a chart — it opens in a separate window with the blue MACD line, orange signal line, and green/red histogram, matching the output chart.

Gotchas

  • Calculation buffers. FastEMA and SlowEMA use INDICATOR_CALCULATIONS, so they hold intermediate values without being plotted — the clean way to carry the two EMAs bar to bar.
  • Recompute the last bar. Starting at prev_calculated - 1 re-runs the most recent (still-forming) bar each tick while leaving history alone.
  • MQL4? Same math. MQL4 has iMACD, but it (like MT5’s built-in) doesn’t give you the MACD-vs-signal histogram — the hand-rolled version above ports directly by swapping the OnCalculate signature and buffer setup.

Same indicator elsewhere: Python, Pine Script, EasyLanguage, NinjaScript. Then backtest a MACD rule 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. Gerald Appel (CMT Association)
  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