I wont try to catch this problem in OnInit!
Doesn't the code I initially posted do exactly that?
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:
const uint time_out = 1000;
uint ms = GetTickCount();
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)
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.
Isn't OnTimer event running in a different thread?
Of course not. 1 thread by EA.
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()
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 " 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.
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...
EventSetMillisecondTimer(1); //right before return
while(!/*you have everything you need*/)
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