Check History loader from code base.
If you are doing it from an indicator, you need a different approach.
As a trick, you can instantiate iATR internally and let it build on the data you need.
Then all you need to check is when the indicator is ready loaded.
For mt5 you load the indicators in OnInit. You can check in OnCalculate or in OnTimer for completion.
Here is an idea on how it can be done...
//+------------------------------------------------------------------+ //| TimeframeAlignBegin() | //+------------------------------------------------------------------+ datetime TimeframeAlignBegin(const ENUM_TIMEFRAMES timeframe, datetime _time) { datetime _end = _time; if(TimeframeAlign(timeframe, _time, _end)) { return(_time); } // Return return(NULL); } //+------------------------------------------------------------------+ //| TimeframeAlignEnd() | //+------------------------------------------------------------------+ datetime TimeframeAlingEnd(const ENUM_TIMEFRAMES timeframe, datetime _time) { datetime _start = _time; if(TimeframeAlign(timeframe, _start, _time)) { return(_time); } // Return return(NULL); } //+------------------------------------------------------------------+ //| TimeframeAlign() | //+------------------------------------------------------------------+ bool TimeframeAlign(const ENUM_TIMEFRAMES timeframe, datetime& start, datetime& end) { // Local init MqlDateTime st_time = { 0x00 }; datetime scope = NULL; bool retval = false; // Switch calculation granularity switch(PeriodSeconds(timeframe)) { // Adjust timeframe to monthly scope case 2592000: // PERIOD_MN1: // Start retval = TimeToStruct(start, st_time); start -= (((st_time.day - 1) * 86400) + (start % 86400)) * retval; // End retval &= TimeToStruct(end, st_time); end += ((((DaysOfMonth(st_time.mon, st_time.year) - st_time.day) * 86400) - ((st_time.hour * 3600) + (st_time.min * 60) + st_time.sec)) - 1) * retval; break; // Adjust timeframe to weekly scope case 604800: // PERIOD_W1: // Start retval = TimeToStruct(start, st_time); start -= ((st_time.day_of_week * 86400) + (start % 86400)) * retval; // End retval &= TimeToStruct(end, st_time); end += ((((7 - st_time.day_of_week) * 86400) - ((st_time.hour * 3600) + (st_time.min * 60) + st_time.sec)) - 1) * retval; break; // Adjust timeframe to hourly scope case 86400: // PERIOD_D1: case 43200: // PERIOD_H12: case 28800: // PERIOD_H8: case 21600: // PERIOD_H6: case 14400: // PERIOD_H4: case 10800: // PERIOD_H3: case 7200: // PERIOD_H2: case 3600: // PERIOD_H1: scope = PeriodSeconds(timeframe) / 3600; // Start retval = TimeToStruct(start, st_time); start -= (((st_time.hour % scope) * 3600) + (st_time.min * 60) + st_time.sec) * retval; // End retval &= TimeToStruct(end, st_time); end += ((((scope - (st_time.hour % scope)) * 3600) - ((st_time.min * 60) + st_time.sec)) - 1) * retval; break; // Adjsut timeframe to minute scope default: scope = PeriodSeconds(timeframe); // Start retval = TimeToStruct(start, st_time); start -= (start % scope) * retval; // End retval &= TimeToStruct(end, st_time); end -= (((end % scope) - scope) + 1) * retval; } // Return success return(retval); } //+------------------------------------------------------------------+ //| DaysOfMonth() | //+------------------------------------------------------------------+ int DaysOfMonth(const int month, const int year) { switch(month) { case 0x01: return(31); case 0x02: return(28 + (((year % 4) == NULL) && ((year % 100) != NULL)) + (((year % 100) == NULL) && ((year % 400) != NULL)) + ((year % 400) == NULL)); case 0x03: return(31); case 0x04: return(30); case 0x05: return(31); case 0x06: return(30); case 0x07: return(31); case 0x08: return(31); case 0x09: return(30); case 0x0A: return(31); case 0x0B: return(30); case 0x0C: return(31); default: return(NULL); } } //+------------------------------------------------------------------+ //| TerminalDataLoad() | //+------------------------------------------------------------------+ bool TerminalDataLoad(const string symbol, const ENUM_TIMEFRAMES timeframe, datetime& history_begin) { // Local init const datetime trm_first_date = (datetime)SeriesInfoInteger(symbol, timeframe, SERIES_FIRSTDATE); const int trm_bars = TerminalInfoInteger(TERMINAL_MAXBARS); datetime srv_first_date = NULL; const datetime time_current = TimeframeAlignBegin(timeframe, TimeCurrent()); int retry_cnt = NULL; datetime tmp[]; // Check timeframe if(MQLInfoInteger(MQL_PROGRAM_TYPE) == PROGRAM_INDICATOR) { // Check for current timeframe if(timeframe == Period()) { return(true); } // Check data availability const datetime request_begin = history_begin; const datetime terminal_begin = (TimeCurrent() - (trm_bars * PeriodSeconds(timeframe))) * (TimeCurrent() > (TimeCurrent() - (trm_bars * PeriodSeconds(timeframe)))); const datetime series_begin = (datetime)SeriesInfoInteger(symbol, timeframe, SERIES_FIRSTDATE); MqlRates tmp_data[]; if(CopyRates(symbol, timeframe, TimeCurrent(), MathMax(series_begin, terminal_begin), tmp_data) > NULL) { history_begin = tmp_data[0].time; return(history_begin <= request_begin); } // Return return(false); } // Check load data if(trm_first_date > NULL) { CopyTime(symbol, timeframe, trm_first_date + PeriodSeconds(timeframe), 0x01, tmp); if(SeriesInfoInteger(symbol, timeframe, SERIES_FIRSTDATE) >= time_current) { return(true); } } // Verify terminal and server data while( (!SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE, srv_first_date)) && (!_StopFlag) ) { Sleep(25); } if(trm_first_date < srv_first_date) { return(false); } // Step by step loader while( (retry_cnt < 25) && (!_StopFlag) ) { // Wait for timeseries to be built while( (!SeriesInfoInteger(symbol, timeframe, SERIES_SYNCHRONIZED)) && (!_StopFlag) ) { Sleep(25); } // Check amount of available bars if( (Bars(symbol, timeframe) > NULL) && (SeriesInfoInteger(symbol, timeframe, SERIES_FIRSTDATE) <= history_begin) ) { history_begin = (datetime)SeriesInfoInteger(symbol, timeframe, SERIES_FIRSTDATE); return(true); } // Read data from terminal and verify state if(CopyTime(symbol, timeframe, history_begin, 0x01, tmp) == -1) { if(retry_cnt < 23) { history_begin = time_current - (PeriodSeconds(timeframe) * Bars(symbol, timeframe)); } else { history_begin = (datetime)SeriesInfoInteger(symbol, timeframe, SERIES_FIRSTDATE); } retry_cnt++; Sleep(25); continue; } // Check data state if(tmp[0x00] <= history_begin) { return(true); } // Update loop control retry_cnt++; Sleep(25); } // Return return(false); }
hi , iam looking programmer who can create robot for me, i have strategy already that is based on candles, time, timeframe for open and close candles only.
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hello guys
I need to implement such feature for my panel. I will create a button, which will load candle data for all Market Watch symbols. So when I change the symbol, the chart will be ready.
So there are several options with similar logic, i.e. request iHighest of last 100 bars for each market watch symbol in the loop.
Anyone has experience with this? Is it optimal way or I should consider another option. Is there any suitable asynchronus function for this?