CMF in MetaTrader 5 — MQL5 Source Code

A custom Chaikin Money Flow oscillator for MT5

CMF in MetaTrader 5
CMF in MetaTrader 5

Chaikin Money Flow isn’t a default MT5 indicator, so it’s a worthwhile custom build. The math is a money flow multiplier, a volume weight, and two rolling sums (see the explainer).

What you’ll need

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

The source

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

input int  InpPeriod        = 20;
input bool InpUseRealVolume = true;

double CMFBuffer[], MFVBuffer[];

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

   // Money flow volume per bar.
   int mfvStart = (prev_calculated > 1) ? prev_calculated - 1 : 0;
   for(int i = mfvStart; i < rates_total; i++)
     {
      double rng = high[i] - low[i];
      double vol = InpUseRealVolume ? (double)volume[i] : (double)tick_volume[i];
      double mfm = (rng == 0.0) ? 0.0
                   : ((close[i] - low[i]) - (high[i] - close[i])) / rng;
      MFVBuffer[i] = mfm * vol;
     }

   int start = (prev_calculated > InpPeriod) ? prev_calculated - 1 : InpPeriod - 1;
   for(int i = start; i < rates_total; i++)
     {
      double sumMFV = 0.0, sumVol = 0.0;
      for(int j = 0; j < InpPeriod; j++)
        {
         sumMFV += MFVBuffer[i - j];
         sumVol += InpUseRealVolume ? (double)volume[i - j] : (double)tick_volume[i - j];
        }
      CMFBuffer[i] = (sumVol == 0.0) ? 0.0 : sumMFV / sumVol;
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Install & compile

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

Gotchas

  • Flat-bar guard. rng == 0.0 ? 0.0 avoids dividing by zero on a locked bar.
  • Real vs tick volume. CMF needs real traded volume to be meaningful; most FX feeds only offer tick volume, which makes it a rough proxy. Toggle InpUseRealVolume accordingly.
  • Sum then divide. The two inner sums (money flow volume and volume) are divided after summing over the window — not per-bar averaged.

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