Why OnCalculate does not update in real time???

 

Hello everyone, I have this indicator:

//OBJ_LABEL prefix+"close" already created during OnInit
//OBJ_LABEL prefix+"mkt_open" already created during OnInit
//int mkt_time = 1

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 lookback = 1000;
   for(int iBar =Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar)
     {
      double price = (MarketInfo(Symbol(),MODE_BID) + MarketInfo(Symbol(),MODE_ASK)) /2;
      ObjectSetText(prefix+"close",DoubleToString(price,5),24,"Arial",clrWhite);
      
      if(mkt_time == TimeHour(Time[iBar]) && TimeMinute(Time[iBar]) == 0)
        {
         mkt_open = Open[iBar];
        }
      ObjectSetText(prefix+"mkt_open",DoubleToString(mkt_open,5),24,"Arial",clrWhite);

     }
   return(rates_total);
  }

I do not understand why the label with current price does not update regularly, it seems to update once every new candle, I need it to update regoularly. Just like the built-in MA indicator does update with every new tick. 

Any hint on why this does not behave as intended? Thank's. 

 
You have one object. Why are you looping over multiple bars?
 
William Roeder #:
You have one object. Why are you looping over multiple bars?

I want a label object that display current price. 

Edit: regarding the loop - I need it because I want also other labels that display indicator values. ie. a label that display current MA(x) price.  Also, for the label displaying market open I need the loop because I can't just call iOpen on daily chart because my broker daily candle does not open at the time I need. 
 
ironhak #:

I want a label object that display current price. 

Edit: regarding the loop - I need it because I want also other labels that display indicator values. ie. a label that display current MA(x) price.  Also, for the label displaying market open I need the loop because I can't just call iOpen on daily chart because my broker daily candle does not open at the time I need. 
Bars-1-prev_calculated is >= 0 only at start and when new bar appears otherwise it is -1 so your for loop exits without making a single cycle. 
 
Laszlo Tormasi #:
Bars-1-prev_calculated is >= 0 only at start and when new bar appears otherwise it is -1 so your for loop exits without making a single cycle. 

Thank you. I just copied and pasted Williams post about how to correctly do for loops... Guess I've never understood it actually. So, how does one modify the structure of the loop in order to update indicators real time? 

 
ironhak #:

Thank you. I just copied and pasted Williams post about how to correctly do for loops... Guess I've never understood it actually. So, how does one modify the structure of the loop in order to update indicators real time? 


Extract current price reading from the loop.
You don't want to read same data for each bar and especially you don't want to redraw that object for each bar in the loop.

      double price = (MarketInfo(Symbol(),MODE_BID) + MarketInfo(Symbol(),MODE_ASK)) /2;
      ObjectSetText(prefix+"close",DoubleToString(price,5),24,"Arial",clrWhite);
 
Drazen Penic #:


Extract current price reading from the loop.
You don't want to read same data for each bar and especially you don't want to redraw that object for each bar in the loop.

And what if I need to calculate e certain indicator inside the loop and then giving it to the label? And specially making the calculation real time and not only at new bar. 

 
ironhak #:

And what if I need to calculate e certain indicator inside the loop and then giving it to the label? And specially making the calculation real time and not only at new bar. 

Then you calculate the value inside the loop and put the extracted lines after the loop.

In you above code, label value had no any dependency on the loop index, so it was sufficient to put those two lines before loop.

If you want to display some value dependent on the loop, then calculate that value in the loop and store it in some local variable.

For correct calculation, you already read posts William linked.

You have one label which will hold one value after the OnTick() finishes and you really shouldn't redraw text object for each pass of the loop. 

 
Drazen Penic #:

Then you calculate the value inside the loop and put the extracted lines after the loop.

In you above code, label value had no any dependency on the loop index, so it was sufficient to put those two lines before loop.

If you want to display some value dependent on the loop, then calculate that value in the loop and store it in some local variable.

For correct calculation, you already read posts William linked.

You have one label which will hold one value after the OnTick() finishes and you really shouldn't redraw text object for each pass of the loop. 

Yes ok, but still, indicator calculated inside the loop does not updates real time. 

 
ironhak #:

Yes ok, but still, indicator calculated inside the loop does not updates real time. 

Do you know what the prev_calculated is doing?
Its value is the previous call's return value (mostly). 
So, on the second call prev_calculated=rates_total. 
In your for loop you have rates_total-prev_calculated-1 which equals to -1 in that case. 
As your for loop cycles until iBar>=0 and iBar is -1, it won't do anything. 
When a new bar opens, the rates_total increases. So rates_total-prev_calculated-1 equals to 0 that's why the for loop iterates once. 
You need to make sure that iBar is always at least 0. 

 
Laszlo Tormasi #:
Do you know what the prev_calculated is doing?
Its value is the previous call's return value (mostly). 
So, on the second call prev_calculated=rates_total. 
In your for loop you have rates_total-prev_calculated-1 which equals to -1 in that case. 
As your for loop cycles until iBar>=0 and iBar is -1, it won't do anything. 
When a new bar opens, the rates_total increases. So rates_total-prev_calculated-1 equals to 0 that's why the for loop iterates once. 
You need to make sure that iBar is always at least 0. 

So you suggesting that by doing this: 

for(int iBar =Bars-MathMax(lookback, prev_calculated); iBar >= 0; --iBar) //I removed -1

I'll achieve the desired outcome without altering the proper structure of the loop? 

Reason: