No documentation for "cannot refresh history [4073]"? How to properly handle this error? - page 2

 
Carl Schreiber:

I wont try to catch this problem in OnInit!

  1. Check in OnInit() if you have everything you need - may be in a separate function

Doesn't the code I initially posted do exactly that?

 
6xfngb5dgfe6d:

So to summarize this up:

To avoid error 4073 and also achieve immediate logic execution after initialization, one should use this code:

Is this the best practice?


For starting up the EA, yes. Then you need logic in place to handle the errors. For example:

void OnTick()
{
//---
   const uint time_out = 1000;    
   uint       ms       = GetTickCount();                               
   double     ma;                               
   do
   {                                                      
      ResetLastError();                                     
      ma = iMA(_Symbol,PERIOD_H4,50,0,0,0,0);
   }
   while(_LastError != ERR_NO_ERROR && GetTickCount()-ms < time_out && !IsStopped());
   if(_LastError != ERR_NO_ERROR)
      return;
}
 
nicholishen:

Yes, you are correct... I read too fast and didn't understand the question... I thought he was asking about calling OnTick from OnInit 

Yes but you are right to think about this problem. 

Actually I just checked and the OnTimer is not executed if OnInit() is not returning INIT_SUCCEEDED. 

 
6xfngb5dgfe6d:

Isn't OnTimer event running in a different thread?

Of course not. 1 thread by EA.

 
6xfngb5dgfe6d:

So to summarize this up:

To avoid error 4073 and also achieve immediate logic execution after initialization, one should use this code:

Is this the best practice?

So since OnTimer is definitely called after OnInit ends, this code should be perfectly ok and therefore avoid the mentioned error, correct?

= no chance of encountering uninitialized values in OnTick()

 
6xfngb5dgfe6d:

I am using ChartOpen and then ChartApplyTemplate methods to execute an EA on a new chart from the current EA.

Sometimes (about 5% of all cases and it seems completely random) this newly executed EA throws an "cannot refresh history [4073]" error when initializing. Once this happens, the strategy becomes unusable - you can't access any series or info about the chart that it's running on. Also, if you afterwards put the EA again directly from the navigator on that same chart, it works.

I've tried to handle this error, look for any kind of documentation or info on this, but there's pretty much nothing.

What causes this error and how to handle it properly?

Here's an unsuccessful attempt that I made (once encountered, it would just loop infinitely, because the state won't change).


I would also suggest that you stop using deprecated functions (use the MQL4/5 common functions instead) because it will be a nightmare to convert when you eventually have to port your code over to MQL5.


ArrayCopySeries(...)

CopyTime(...)

 
6xfngb5dgfe6d:

So since OnTimer is definitely called after OnInit ends, this code should be perfectly ok and therefore avoid the mentioned error, correct?

= no chance of encountering uninitialized values in OnTick()


No guarantee about that.

 
Alain Verleyen:

No guarantee about that.


Exactly. This guarantees that you've completed step 1 (returning INIT_SUCCEEDED), which is required before you can continue further into downloading new data from the broker server, etc. You have to complete step 1 before you move to step 2...

 
Ok, let's make an attempt to make this complete, so someone else can also reuse it. This is how I see the step 2:


int OnInit()
{
   //init logic

   EventSetMillisecondTimer(1); //right before return
   return INIT_SUCCEEDED;
}

void OnTimer()
{
   while(!/*you have everything you need*/)
   {  
       Sleep(1000); 
       RefreshRates(); 
   }
   OnTick();
   EventKillTimer();
}

void OnTick()
{
   //Logic here
}

 
6xfngb5dgfe6d:
Ok, let's make an attempt to make this complete, so someone else can also reuse it. This is how I see the step 2:



No sleep, and RefreshRates won't help you because they only refresh the predefined's. Make sure you ResetLastError at the beginning of every loop. Feel free to incorporate this lib

#include <multi_symbol_timeframe.mqh>
string symbols[]={"EURUSD","USDJPY","EURJPY"};
void OnTimer()
{
   if(InitSymbolsHistory(symbols,PERIOD_M15,PERIOD_H4))
   {
      EventKillTimer();
      OnTick();
   }
   else
      EventSetTimer(1);
}
Reason: