History data and error 4066
| ArrayCopySeries - MQL4 Documentation states |
If data are copied from another chart
with different symbol and/or timeframe, it is possible that the
necessary data will lack. In this case, error ERR_HISTORY_WILL_UPDATED
(4066 - requested history data under updating) will be placed into the
last_error variable, and there will be necessary to retry copying after a
certain period of time. And shows an example.
|
| So I wrote this. |
/** Starts and waits for a download of chart history. * In Technical Indicator Functions - MQL4 Documentation][TIF3] it states: * > If data (symbol name and/or timeframe differ from the current ones) are * > requested from another chart, the situation is possible that the * > corresponding chart was not opened in the client terminal and the * > necessary data must be requested from the server. In this case, error * > `ERR_HISTORY_WILL_UPDATED` (4066 - the requested history data are under * > updating) will be placed in the last_error variable, and and there will * > be necessary to retry \[the operation] after a certain period of time. * * The [ArrayCopySeries][ACS] example tests array[0] against server time. * [ACS]: https://docs.mql4.com/array/arraycopyseries * [TIF3]: https://docs.mql4.com/en/indicators * * Note: you _only_ get 4066 once. Subsequent calls (\::ArrayCopyRates and * apparently \::ArrayCopySeries) silently succeed but the data is bogus * until the download completes. These calls should have been synchronous, * but then they couldn't be used in indicators. */ bool download_history( ENUM_TIMEFRAMES period=PERIOD_CURRENT, ///< The standard timeframe. string msg=__FUNSIG__ ///< Debug. SYMBOL symbol=THIS_SYMBOL /**< The symbol required.*/){ if(symbol == THIS_SYMBOL) symbol = _Symbol; if(period == PERIOD_CURRENT) period = _Period; ResetLastError(); datetime other = iTime(symbol, period, 0); if(_LastError == 0) return true; if(_LastError != ERR_HISTORY_WILL_UPDATED){ AssertFailure(StringFormat("%s: iTime(%s,%i) Failed: %i", msg, symbol, period, _LastError) ); return false; } datetime today = DateOfDay(); for(int i = 0;i < 15; i++){ Sleep(1000); ResetLastError(); other = iTime(symbol, period, 0); if(today == DateOfDay(other)){ RefreshRates(); return true; } } AssertFailure(StringFormat("%s: iTime(%s,%i) Failed: %i (15 secs)", msg, symbol, period, _LastError) ); return false; } |
#define HR2400 PERIOD_D1 * 60 // 86400 = 24 * 3600
int TimeOfDay(datetime when=0){ if(when == 0) when = TimeCurrent();
return( when % HR2400 ); }
datetime DateOfDay(datetime when=0){ if(when == 0) when = TimeCurrent();
return( when - TimeOfDay(when) ); }
//datetime Tomorrow( datetime when=0){ if(when == 0) when = TimeCurrent();
// return(DateOfDay(when) + HR2400); }
//datetime Yesterday(datetime when=0){ if(when == 0) when = TimeCurrent();
// int iD1 = iBarShift(NULL, PERIOD_D1, DateOfDay(when) - 1);
// return( iTime(NULL, PERIOD_D1, iD1) ); }
int TimeOfDay(datetime when=0){ if(when == 0) when = TimeCurrent();
return( when % HR2400 ); }
datetime DateOfDay(datetime when=0){ if(when == 0) when = TimeCurrent();
return( when - TimeOfDay(when) ); }
//datetime Tomorrow( datetime when=0){ if(when == 0) when = TimeCurrent();
// return(DateOfDay(when) + HR2400); }
//datetime Yesterday(datetime when=0){ if(when == 0) when = TimeCurrent();
// int iD1 = iBarShift(NULL, PERIOD_D1, DateOfDay(when) - 1);
// return( iTime(NULL, PERIOD_D1, iD1) ); }
Sleep() is not executed in indicators.
I tend to use OnTimer() with a simple flag in OnTick() / OnCalculate() to be compatible with both.
Although I believe OnTimer() wasn't an option back in 2015
honest_knave:
OnTimer was available since 2014.
I tend to use OnTimer() with a simple flag in OnTick() / OnCalculate() to be compatible with both.
Although I believe OnTimer() wasn't an option back in 2015
Ovo Cz:
OnTimer was available since 2014.
OnTimer was available since 2014.
I stand corrected! ![]()
I guess it was a build 600 thing.
Alain Verleyen: Sleep() is not executed in indicators.
True. In another thread I posted a variation of download_history that didn't have the internal wait, but immediately returned false. Thus the calls would be:| In indicators | int OnCalculate(...){ Return and wait for the next tick and retry.if(!download_history(...) return prev_calculated; : |
| In EAs | void OnTick(){ while(!download_history(...){ Sleep(1000); RefreshRates(); } : |
whroeder1:
True. In another thread I posted a variation of download_history that didn't have the internal wait, but immediately returned false. Thus the calls would be:
Yes. I didn't notice it was an old post.
True. In another thread I posted a variation of download_history that didn't have the internal wait, but immediately returned false. Thus the calls would be:
| In indicators | int OnCalculate(...){ Return and wait for the next tick and retry.if(!download_history(...) return prev_calculated; : |
| In EAs | void OnTick(){ while(!download_history(...){ Sleep(1000); RefreshRates(); } : |
Hello,
Is there any safe method to check if history is current after error 4066?.
THX!!