Errors, bugs, questions - page 1391

 
Ilya Malev:

After pressing "refresh" everything is calculated. It would be more convenient if indicator data, created in the inite, was calculated before the first call of OnCalculate/OnTimer etc.

It would be useful to have a possibility to wait for their calculation after the initialization in the loop inside the indicator.

To calculate the indicator, the user should press "refresh" on the chart several times. Does he need it. He will remember good old MT4 and will stay on it, despite some advantages of MT5.

Any calculations in the indicators MUST be done only in OnCalculate().
 
Karputov Vladimir:
Any calculations in indicators MUST be done only in OnCalculate().
I am talking about the readings of the Ishimoku indicator in this case. I am talking about indicator readings that are used in the current one, i.e. in OnCalculate. So they are calculated before call of OnCalculate, as it was in MT4. Or it would be possible to wait for their calculation in OnCalculate. Otherwise users will have to press Update several times to build an indicator. Because not all indicators are built on the entire history in 1 second, there are complex indicators that take longer to calculate. All this time the user will have to wait over the "Refresh" button, while in MT4 you just have to wait for it to be drawn.
 
Ilya Malev:
I'm talking about the Ishimoku indicator readings in this case. I'm talking about indicator readings that are used in the current one, i.e. OnCalculate. So they are calculated before OnCalculate is called, as it was in MT4.
In OnInit() the preparation of the trading environment for the indicator is performed. And only in OnCalculate() you can use the indicator data.
 
Ilya Malev:
I am talking about the readings of the Ishimoku indicator in this case. I am talking about indicator readings that are used in current, i.e. in OnCalculate. So they are calculated before call of OnCalculate, as it was in MT4. Or it would be possible to wait for their calculation in OnCalculate. Otherwise users will have to press Update several times to build an indicator. Because not all indicators are built on the entire history in 1 second, there are complex indicators that take longer to calculate. All this time the user will have to wait over the "Refresh" button, while in MT4 you just have to wait for it to be drawn.

This problem comes up from time to time on the forum. Unfortunately, calling OnCalculate() in OnTimer() does not solve the problem.

But you can try it. An example can be found in this article: MQL5 Recipes - Development of a Multicurrency Volatility Indicator in MQL5.

Afterwards you will be able to write whether it worked or not.

 
Karputov Vladimir:
OnInit() prepares the trading environment for the indicator. And only in OnCalculate() you can use the indicator data.
It turns out that you cannot, without pressing the "Update" button on the chart once or several times (or wait for 1/number of ticks), if the indicator uses other indicators from other symbols and/or tf.
 
Anatoli Kazharski:

This problem comes up from time to time on the forum. Unfortunately, calling OnCalculate() in OnTimer() does not solve the problem.

But you can try it. An example can be found in this article: MQL5 Recipes - Development of a Multicurrency Volatility Indicator in MQL5.

Afterwards write whether it worked or not, if not too much trouble.

Thank you for the link. I will try it and let you know.
 
Ilya Malev:
It turns out that you can't, without pressing "Update" button on the chart once or several times (or wait for 1/few ticks), if the indicator uses other indicators from other symbols and/or tf.

And if you look more closely at the workings of the code I gave? And in particular to the Experts? After restarting the terminal at the weekend:

2015.10.11 14:44:01.672 test (USDCAD,M5)        0
2015.10.11 14:44:01.681 test (USDCAD,M5)        1
2015.10.11 14:44:01.682 test (USDCAD,M5)        Расчитано 16518 баров за 0 секунд
2015.10.11 14:44:01.705 test (USDCAD,M5)        2
2015.10.11 14:44:01.705 test (USDCAD,M5)        Расчитано 16518 баров за 0 секунд

You can perfectly see that the calculation only went through on the second call to OnCaalculate(). So no one removes from the programmer responsibility to check: check the result of CopyBuffer() in OncalCulate() - if the function did not return anything, it must be checked at the next input in OnCalculate().

 
Anatoli Kazharski:

This problem comes up from time to time on the forum. Unfortunately, calling OnCalculate() in OnTimer() does not solve the problem.

But you can try it. An example can be found in this article: MQL5 Recipes - Development of a Multicurrency Volatility Indicator in MQL5.

Please write later, if not too much trouble, whether it worked or not.

I have not read the article yet, but it works fine with OnTimer

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   0
int i_ich=INVALID_HANDLE;
double ind_buf[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetTimer(1);
   i_ich=iIchimoku(Symbol(),PERIOD_H4,9,26,52);
   if(i_ich==INVALID_HANDLE)
     {
      Print("Невозможно создать индиктор Ишимоку!");
      return(INIT_FAILED);
     }
   SetIndexBuffer(0,ind_buf,INDICATOR_DATA);
   ArraySetAsSeries(ind_buf,true);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

void OnTimer(){
   datetime Arr1[];
   double Arr2[];
   long Arr3[];
   int Arr4[];
   OnCalculate(0, 0, Arr1, Arr2, Arr2, Arr2, Arr2, Arr3, Arr3, Arr4);
}

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[])
  {
   static int count=0;
   static datetime now=0;
   if(now==0)  now=TimeLocal();
   if(count>=0){
      Print(count);
      double temp[];
      int copied=CopyBuffer(i_ich,0,0,1,temp);
      if(copied>0){
         Print("Расчитано ",BarsCalculated(i_ich)," баров за ",int(TimeLocal()-now)," секунд");
         EventKillTimer(); // Индикаторы рассчитались, далее работаем только с OnCalculate
         count=-1;
      }else
         count++;
   }
   if(rates_total==0)   return(0); // Если это вызов из OnTimer, то возврат
   
   // ...
   return(rates_total);
}

I have a strange picture showing that call of OnCalculate from OnTimer works) I need to add correct values in timeseries

 
Ilya Malev:

Haven't read the article yet, but the reception with OnTimer works fine

In simple indicators it works fine. But in more complex ones, for some reason, it sometimes sticks. )
 
Ilya Malev:

Haven't read the article yet, but the reception with OnTimer works fine

Use the Styler - it's better for identifying errors.

   if(count>=0)
     {
      Print(count);
      double temp[];
      int copied=CopyBuffer(i_ich,0,0,1,temp);
      if(copied>0)
        {
         Print("Расчитано ",BarsCalculated(i_ich)," баров за ",int(TimeLocal()-now)," секунд");
         EventKillTimer(); // Индикаторы рассчитались, далее работаем только с OnCalculate
         count=-1;
        }
      else
         count++;
     }
Increase count variable before exit from OnCalculate() - in this case this variable will correctly count all runs in OnCalculate.