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)

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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!!!