ROC in MetaTrader 5 — MQL5 Source Code

A custom Rate of Change oscillator for MT5

ROC in MetaTrader 5
ROC in MetaTrader 5

The Rate of Change is one of the easiest custom indicators to write in MQL5 — a single subtraction and division per bar. See the explainer for the concept.

What you’ll need

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

The source

//+------------------------------------------------------------------+
//|                                                  AlgoGen.ROC.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 1
#property indicator_plots   1

#property indicator_label1  "ROC"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2
#property indicator_level1  0.0

input int InpPeriod = 12; // ROC period

double ROCBuffer[];

int OnInit()
  {
   SetIndexBuffer(0, ROCBuffer, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpPeriod);
   IndicatorSetString(INDICATOR_SHORTNAME, "AlgoGen ROC(" + (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;
   for(int i = start; i < rates_total; i++)
     {
      double past = close[i - InpPeriod];
      ROCBuffer[i] = (past != 0.0) ? 100.0 * (close[i] - past) / past : 0.0;
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Install & compile

  1. Drop it in MQL5/Indicators/, press F7.
  2. Drag onto a chart — a separate window shows the ROC oscillating around its zero line, matching the output chart.

Gotchas

  • Divide-by-zero guard. past != 0.0 protects against a zero reference price (rare, but cheap to guard).
  • PLOT_DRAW_BEGIN. Set to InpPeriod so the line doesn’t draw before there’s an N-bars-ago price to compare against.
  • Percentage vs difference / MQL4. MT5’s built-in iMomentum is the ratio form (close/close[n]×100), which oscillates around 100, not 0 — our version is the percent-change form around 0. Pick the convention you want. MQL4 ports directly by swapping the OnCalculate signature.

Adding a signal line

To trade crossovers rather than the jumpy raw line, add a second buffer holding a moving average of the ROC buffer (via iMAOnArray(ROCBuffer, ...) or a short manual SMA loop), plot it, and act when ROC crosses it. Because ROC has no fixed extremes, this signal-line approach — or a rolling z-score for “stretched” readings — is more robust than hard-coding overbought/oversold numbers that won’t hold across symbols.

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