CCI in MetaTrader 5 — MQL5 Source Code

A custom Commodity Channel Index for MT5

CCI in MetaTrader 5
CCI in MetaTrader 5

Building CCI in MQL5 is a good exercise because the mean-absolute-deviation step forces you to loop the window twice — once for the average, once for the deviation. See the explainer for the concept.

What you’ll need

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

The source

//+------------------------------------------------------------------+
//|                                                  AlgoGen.CCI.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  "CCI"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2
#property indicator_level1  100.0
#property indicator_level2  -100.0

input int    InpPeriod   = 20;
input double InpConstant  = 0.015;

double CCIBuffer[], TPBuffer[];

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

   // Typical price for every bar.
   int tpStart = (prev_calculated > 1) ? prev_calculated - 1 : 0;
   for(int i = tpStart; i < rates_total; i++)
      TPBuffer[i] = (high[i] + low[i] + close[i]) / 3.0;

   int start = (prev_calculated > InpPeriod) ? prev_calculated - 1 : InpPeriod - 1;
   for(int i = start; i < rates_total; i++)
     {
      // SMA of typical price.
      double sum = 0.0;
      for(int j = 0; j < InpPeriod; j++) sum += TPBuffer[i - j];
      double ma = sum / InpPeriod;

      // Mean ABSOLUTE deviation from that average.
      double mad = 0.0;
      for(int j = 0; j < InpPeriod; j++) mad += MathAbs(TPBuffer[i - j] - ma);
      mad /= InpPeriod;

      CCIBuffer[i] = (mad == 0.0) ? 0.0
                     : (TPBuffer[i] - ma) / (InpConstant * mad);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Install & compile

  1. Drop it in MQL5/Indicators/, press F7.
  2. Drag onto a chart — a separate window shows CCI with the ±100 level lines, matching the output chart.

Gotchas

  • Two passes over the window. The first computes the SMA; the second uses that SMA to accumulate mean absolute deviation. Don’t substitute a standard-deviation routine — that’s a different indicator.
  • mad == 0 guard. A perfectly flat window gives zero deviation; return 0 rather than dividing by zero.
  • Built-in / MQL4. MT5 has iCCI; MQL4 does too. The custom version exposes the math and lets you tweak the constant.

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