Creating My First Indicator: Relative Volume
After reading a bit more from the book Expert Advisor Programming for MetaTrader 5, I was able to get it closer to working, but still not quite there.
My updated OnCalculate() code is below:
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[]) { // Make sure we have at least "length" bars showing if(rates_total<length) return(prev_calculated); // or //if(Bars(_Symbol,_Period)<rates_total) return(prev_calculated); // or //if(Bars(_Symbol,_Period)<rates_total) return(-1); ArraySetAsSeries(Relative_VolumeBuffer, true); ArraySetAsSeries(volume, true); int bars = rates_total - 1; if(prev_calculated > 0) bars = rates_total - (prev_calculated - 1); for(int i = bars; i >= 0; i--) { long sum_of_recent_volumes = 0; int relative_volume = 0; for(int j=1; j<length+1; j++) { sum_of_recent_volumes += tick_volume[i]; } Relative_VolumeBuffer[i] = tick_volume[i] / (sum_of_recent_volumes/length); } return(rates_total); }
So the first loop iterates over all the uncalculated bars, and the inner loop attempts to calculate the relative volume for those bars.
However, the output is just 1.00:
Oh my, silly mistake, I had `i` as the locator for tick_volume[i] when it should have been tick_volume[j], so I made that change to line 76 and it results in this output:
...which still isn't correct. When I overlay the volume with a 14 period moving average on it, we should be seeing a spike in relative volume everywhere the tick volume > the ma. I've highlighted some key areas where we should be seeing a spike in relative volume but we don't:
I'll try to keep working on it, but I'm stuck now.
I THINK I FOUND THE WINNER!
//+------------------------------------------------------------------+ //| 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[]) { // Make sure we have at least "length" bars showing if(rates_total<length) return(prev_calculated); // or //if(Bars(_Symbol,_Period)<rates_total) return(prev_calculated); // or //if(Bars(_Symbol,_Period)<rates_total) return(-1); ArraySetAsSeries(Relative_VolumeBuffer, true); ArraySetAsSeries(tick_volume, true); int bars = rates_total - 1; if(prev_calculated > 0) bars = rates_total - (prev_calculated - 1); for(int i=bars; i>=0; i--) { float sum_of_recent_volumes = 0; float relative_volume = 0; for(int j=1; j<length+1; j++) { sum_of_recent_volumes += tick_volume[j]; } Relative_VolumeBuffer[i] = tick_volume[i] / (sum_of_recent_volumes/(float)length); } return(rates_total); }
Have to be mindful of integer math/casting `length` to a float, and using appropriate data types for the variables. This results in this output, which is much more accurate:
Thanks for letting me work through this one haha and I hope it helps some other newbies some day!
int bars = rates_total - 1; if(prev_calculated > 0) bars = rates_total - (prev_calculated - 1); for(int i=bars; i>=0; i--){ ⋮ for(int j=1; j<length+1; j++){ sum_of_recent_volumes += tick_volume[j];
Still wrong.
- For a specific i, you need to sum j over [i … i + length-1]. You are summing over [1 … length+1]. The same bars for every candle!
- Your look back is length-1.
How to do your lookbacks correctly #9 — #14 & #19 (2016)




I'm attempting to create my first MQL5 indicator, the Relative Volume. Relative Volume is just the current tick's volume / average volume over past n bars. Simple.
I've read the two articles for newbies (here and here), but am just a bit unclear on some things that I will be able to decipher on my own once I get some help with this indicator.
This is what I have so far:
...which currently results in this (wrong) output:
Can I get some assistance in programming this simple indicator to help me better understand the buffers and rates_total and how these arrays are loc'd, etc. Thanks!!!