Dabbling with MQL, here is my take on Chaikin Money Flow, adapted from Forex Indicators. Happy for suggestions/ any pointers if you think this is incorrect.
#property copyright "Copyright 2019, Saveen Kumar"
#property copyright "Copyright 2019, Saveen Kumar"
#property link "https://www.linkedin.com/in/saveenkumar/"
#property version "1.00"
#property strict
//indicator properties
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Magenta
#property indicator_level1 0
#property indicator_levelstyle STYLE_DOT
#property indicator_levelcolor Black
//indicator inputs
extern int CMFPeriod = 20; //period for CMF
//buffers
double CMFLineBuffer[]; //for line, value of actual CMF
//+---------------------------------------------------+
//| Custom indicator initialization function |
//+---------------------------------------------------+
int OnInit()
{
//--- check if CMF period is acceptable
if(CMFPeriod<2)
{
Print("CMF period needs to be more than 2");
return(INIT_FAILED);
}
//set up the buffer
IndicatorBuffers(indicator_buffers);
SetIndexStyle(0, DRAW_LINE);
SetIndexBuffer(0, CMFLineBuffer);
//show labels if wanted
SetIndexLabel(0, "CMF");
IndicatorShortName("CMF (" +
IntegerToString(CMFPeriod) +")");
//begin drawing
SetIndexDrawBegin(0,CMFPeriod);
return(INIT_SUCCEEDED);
}
//+-------------------------------------------------+
//| Custom indicator iteration function |
//+-------------------------------------------------+
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[])
{
//need minimum bars
if(rates_total<=CMFPeriod) return(0);
//the number of bars to calculate in
//this iteration
int limit=0;
//if bars calculated are less than the
//CMF period, buffer value up to the
//period will be zero and we begin our
//calculation of CMF after these
//initial zero bars
if(prev_calculated <= CMFPeriod)
{
for(int i=1;i<=CMFPeriod;i++)
{
CMFLineBuffer[rates_total-i]=0.0;
}
limit=rates_total-CMFPeriod;
}
//if more than CMF period bars already
//calculated, start after them
else{
limit=rates_total-prev_calculated;
}
//main loop, where we are calculating
//only as many bars as are absolutely
//necessary
for(int i=0;i<=limit;i++)
{
double ADSum = 0.0;
double VolSum = 0.0;
for(int j=0;j0)
ADSum += tick_volume[i+j]*
(close[i+j]-open[j+i])/
(high[i+j]-low[i+j]);
}
CMFLineBuffer[i]= ADSum/VolSum;
}
return(rates_total);
}
2>