Question about OnCalculate() regarding prev_calculated / rates_total / IndicatorCounted()

 

Hi guys,

I am (still) confused about the things in the headline. I made a little test indicator which plots a dot in the middle of a candle if the candle's size is larger than its ATR(100).

Of course the indicator should only work if a new bar is printed and I still use this old IndicatorCounted() because I don't know how to use the prev_calculated and rates_total parameters.

Can anyone please tell me how to use these parameters correctly so that I can get rid of IndicatorCounted()?


#property strict
#property indicator_chart_window
#property indicator_buffers 1

double testArray[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

   SetIndexBuffer(0, testArray);
   SetIndexStyle(0, DRAW_ARROW, 0, 2, clrYellow);
   SetIndexArrow(0, 159);
   
//---
   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[])
  {
//---

   int Counted_bars=IndicatorCounted();
   int i=Bars-100-Counted_bars;
   while(i>0) {
      if (High[i]-Low[i]>iATR(_Symbol, _Period, 100, i)) testArray[i]=(High[i]+Low[i])/2;
      i--;
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 

I tried it this way but that doesn't seem to work once a new bar is printed:

//+------------------------------------------------------------------+
//| 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[])
  {
//---

   for (int i=Bars-1-MathMax(100, prev_calculated); i>=0; --i) {
      if (High[i]-Low[i]>iATR(_Symbol, _Period, 100, i)) testArray[i]=(High[i]+Low[i])/2;
   }
//--- return value of prev_calculated for next call
   return(rates_total-1);
  }
 
Marbo:

Hi guys,

I am (still) confused about the things in the headline. I made a little test indicator which plots a dot in the middle of a candle if the candle's size is larger than its ATR(100).

Of course the indicator should only work if a new bar is printed and I still use this old IndicatorCounted() because I don't know how to use the prev_calculated and rates_total parameters.

Can anyone please tell me how to use these parameters correctly so that I can get rid of IndicatorCounted()?


  int i=(prev_calculated==0 ? rates_total-100 : rates_total-prev_calculated);

  while(i>0)
   {
    if (high[i]-low[i]>iATR(_Symbol, _Period, 100, i)) testArray[i]=(high[i]+low[i])/2;
    i--;
   }
//--- return value of prev_calculated for next call
  return(rates_total);

On first call or when the indicator needs to be recalculated (bars on chart reached the limit "Max bars in chart" for example), prev_calculated = 0

On subsequent call, prev_calculated equals the previous rates_total (value returned at the end of OnCalculate), if it's a simple tick prev_calculated=(current) rates_total, if it's a tick with a new bar, prev_calculated = (current)rates_total-1.

rates_total is similar to "Bars".

Also use the OnCalculate() parameters high/low and not the old predefined arrays High/Low.

 
Alain Verleyen:

On first call or when the indicator needs to be recalculated (bars on chart reached the limit "Max bars in chart" for example), prev_calculated = 0

On subsequent call, prev_calculated equals the previous rates_total (value returned at the end of OnCalculate), if it's a simple tick prev_calculated=(current) rates_total, if it's a tick with a new bar, prev_calculated = (current)rates_total-1.

rates_total is similar to "Bars".

Also use the OnCalculate() parameters high/low and not the old predefined arrays High/Low.

Great! Thank you very much!

Could you please tell me what the following means? I have never seen this kind of syntax:

int i=(prev_calculated==0 ? rates_total-100 : rates_total-prev_calculated);
 
Marbo:

Great! Thank you very much!

Could you please tell me what the following means? I have never seen this kind of syntax:

It's the ternary operator.

It's similar to

int i;
if(prev_calculated==0)
  i=rates_total-100;
else
  i=rates_total-prev_calculated;
Documentation on MQL5: Language Basics / Operators / Ternary Operator ?:
Documentation on MQL5: Language Basics / Operators / Ternary Operator ?:
  • www.mql5.com
, the third operand - "expression3" is performed. The second and third operands, i.e. "expression2" and "expression3" should return values of one type and should not be of void type. The result of the conditional operator execution is the result of expression2 or result of the expression3, depending on the result of expression1. Operator Use...
 
Marbo: I still use this old IndicatorCounted() because I don't know how to use the prev_calculated and rates_total parameters.

Can anyone please tell me how to use these parameters correctly so that I can get rid of IndicatorCounted()?

See How to do your lookbacks correctly.
 
Alain Verleyen:

It's the ternary operator.

It's similar to

Ah, ok... so many things I have to learn. :)

 
William Roeder:
See How to do your lookbacks correctly.

I saved your posting about lookbacks a long time ago in my bookmarks and I tried to understand it. In the second version above I tried it the new way, couting down as a time series as you described.

But as you can see I made something wrong and it didn't work as expected.

Reason: