Using OnCalculate(...) but indicator still flattens out

 

Hi, 

I literally took the example listed on https://docs.mql4.com/customind/indicatorbuffers and just modified it slightly to create a ROC [rate of change] indicator.

However even though new quotes arrive the indicator flattens out after a while. Like seen in the attached image. What am I doing wrong here ?


Why doesn't the buffer gets updated while new quotes arrive ? What is it that I'm  missing ?

Thanks so much !

C.

// https://docs.mql4.com/customind/indicatorbuffers
// https://book.mql4.com/samples/icustom
#property copyright   "2005-2013, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"
#property description "Rate of Change"
#property strict
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Blue
#property indicator_style1 STYLE_SOLID
#property indicator_width1  2
#property indicator_level1 0
//--- input parameter
input int InpRocPeriod=1;
//--- buffers
double ExtRocBuffer[];

void OnInit(void)   {
 string short_name;
 IndicatorBuffers(1);
 IndicatorDigits(Digits);

 SetIndexStyle(0, DRAW_LINE);
 SetIndexBuffer(0, ExtRocBuffer);

 short_name = "Roc("+IntegerToString(InpRocPeriod)+")";
 IndicatorShortName( short_name);
 SetIndexLabel(0, short_name);
}

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[])
  {
   int limit = rates_total - prev_calculated;

   if(rates_total <= InpRocPeriod)
      return(0);

   if(prev_calculated > 0)
      limit++;

   for(int i = 0; i < limit - InpRocPeriod; i++) {
    ExtRocBuffer[i] = (close[i] - close[i+InpRocPeriod]) / close[i+InpRocPeriod] * 100.0;
   }

   return(rates_total);
IndicatorBuffers - Custom Indicators - MQL4 Reference
IndicatorBuffers - Custom Indicators - MQL4 Reference
  • docs.mql4.com
IndicatorBuffers - Custom Indicators - MQL4 Reference
 
Cynthia: What am I doing wrong here ?
if(prev_calculated > 0) limit++;

ExtRocBuffer[i] = (close[i] - close[i+InpRocPeriod]) / close[i+InpRocPeriod] * 100.0;
  1. You don't need the increment if you return a proper value.
  2. When previous is zero limit is Bars, thus i becomes limit - InpRocPeriod and i + InpRocPeriod is equal to Bars. Array exceeded. Didn't you bother to look in the Experts tab?
  3. Get in the habit of counting down, so you can't repaint by using future data with a bar calculation.


Do your lookbacks correctly.
 
whroeder1:

  1. You don't need the increment if you return a proper value.
  2. When previous is zero limit is Bars, thus i becomes limit - InpRocPeriod and i + InpRocPeriod is equal to Bars. Array exceeded. Didn't you bother to look in the Experts tab?
  3. Get in the habit of counting down, so you can't repaint by using future data with a bar calculation.


Do your lookbacks correctly.

Hello Whroeder1,

1st thank you for your response and comment.

Ehm, yes I've looked in the experts tab, but now that you made me uncertain I've looked at it again, and monitored it - but no array out of bounds errors. I swear.

What I did is updated the code like so.

   for(int i = limit - 1; i > 0; --i) {
    ExtRocBuffer[i] = (close[i - InpRocPeriod] - close[i]) / close[i - InpRocPeriod] * 100.0;
   }

   return rates_total - 1;

It's a bit strange thinking going backward in the time series, especially if the access mechanism to the values isn't entirely clear to me yet.

I will test this backward traversing method tonight.

Thanks again !

C.


update: just tested it, both solutions side by side, however as you can see also the new code flattens out after a period of deliberate non-refresh.


 
Cynthia: update: just tested it, both solutions side by side, however as you can see also the new code flattens out after a period of deliberate non-refresh.
   for(int i = limit - 1; i > 0; --i) {
    ExtRocBuffer[i] = (close[i - InpRocPeriod] - close[i]) / close[i - InpRocPeriod] * 100.0;
  1. Of course not. Now when i goes below InpRocPeriod your array access is negative.
  2. And unless you set close to asSeries you are accessing future values for past buffer values.
Use the Predefined Variables - MQL4 Reference and do your lookbacks correctly.
Reason: