How to prevent stale data on M1/M5/M30/H1/H4 charts?

 

Hi,

I've created an EA for MT4 that scans all the Forex pairs and all timeframes looking for engulfing patterns and pinbars.  The code runs on a timer, every 10 seconds.  The code works fine most of the time, but I've noticed that when I use "iTime" in the following code, it returns dates from the day before.

I've tried checking for errors and I'm calling "RefreshRates", but it still returns me old data.  I suspect that the data hasn't finished downloading even though "GetLastError" returns zero.  But I'm not sure how else to check if there data has been downloaded or not.

Here's my code.  If someone could point me in the right direction that would be great. 

Thank you.

void scanForPatterns() {

    for (int symbolIndex = 0; symbolIndex < ArraySize(SYMBOLS); symbolIndex++) {

        ENUM_TIMEFRAMES timeframe = PERIOD_M1;
        while (timeframe <= PERIOD_MN1) {
                    
            if(ShouldCheckTimeframe(timeframe)) {
            
                bool dataUpdated = RefreshRates();
                ResetLastError();
            
                // Get the fully closed candle to the left of the current candle
                int current = 1; // shift of 1 means the previous fully closed candle
                int previous = 2;
                
                double currentClose = iClose(SYMBOLS[symbolIndex], timeframe, current);
                double currentOpen = iOpen(SYMBOLS[symbolIndex], timeframe, current);
                double currentHigh = iHigh(SYMBOLS[symbolIndex], timeframe, current);
                double currentLow = iLow(SYMBOLS[symbolIndex], timeframe, current);
                
                double prevClose = iClose(SYMBOLS[symbolIndex], timeframe, previous);
                double prevOpen = iOpen(SYMBOLS[symbolIndex], timeframe, previous);
                
                datetime currentCandleTime = iTime(SYMBOLS[symbolIndex], timeframe, current);  
               
                int error = GetLastError();
                     
                if(error == ERR_NO_ERROR && currentCandleTime != 0) {    
                                                                      
                    if(panel.IsEngulferChecked()) {
                    
                        if(IsBullishEngulfingCandle(currentClose, currentOpen, prevClose, prevOpen)) {
                            string patternEntry = GetPatternEntry(ENGULFER_PATTERN, TimeframeToString(timeframe), SYMBOLS[symbolIndex], TimeToString(currentCandleTime));
                            panel.AddNewEntry(patternEntry, true, SYMBOLS[symbolIndex], timeframe, currentCandleTime, currentHigh, currentLow);                      
                        }           
                        
                        if(IsBearishEngulfingCandle(currentClose, currentOpen, prevClose, prevOpen)) {
                            string patternEntry = GetPatternEntry(ENGULFER_PATTERN, TimeframeToString(timeframe), SYMBOLS[symbolIndex], TimeToString(currentCandleTime)); 
                            panel.AddNewEntry(patternEntry, false, SYMBOLS[symbolIndex], timeframe, currentCandleTime, currentHigh, currentLow);               
                        }     
                    }
                    
                    if(panel.IsPinbarChecked()) {
                    
                        if(IsBullishPinbarCandle(currentClose, currentOpen, currentHigh, currentLow)) {
                            string patternEntry = GetPatternEntry(PINBAR_PATTERN, TimeframeToString(timeframe), SYMBOLS[symbolIndex], TimeToString(currentCandleTime));
                            panel.AddNewEntry(patternEntry, true, SYMBOLS[symbolIndex], timeframe, currentCandleTime, currentHigh, currentLow);
                        }
                        
                        if(IsBearishPinbarCandle(currentClose, currentOpen, currentHigh, currentLow)) {
                            string patternEntry = GetPatternEntry(PINBAR_PATTERN, TimeframeToString(timeframe), SYMBOLS[symbolIndex], TimeToString(currentCandleTime));
                            panel.AddNewEntry(patternEntry, false, SYMBOLS[symbolIndex], timeframe, currentCandleTime, currentHigh, currentLow);             
                        } 
                    }
                }
            }

            timeframe = (ENUM_TIMEFRAMES)(timeframe + 1);
        }
    }
}
 
  1. Why did you post your MT4 question in the MT5 General section instead of the MQL4 section, (bottom of the Root page)?
              General rules and best pratices of the Forum. - General - MQL5 programming forum? (2017)
    Next time, post in the correct place. The moderators will likely move this thread there soon.

  2. Do not assume that bar i on the current chart is bar i on other charts. Always use iBarShift.

  3. On MT4: Unless the current chart is that specific symbol(s)/TF(s) referenced, you must handle 4066/4073 errors before accessing candle/indicator values.
              Download history in MQL4 EA - MQL4 programming forum - Page 3 #26.4 (2019)

  4.         ENUM_TIMEFRAMES timeframe = PERIOD_M1;
            while (timeframe <= PERIOD_MN1) {
    ⋮
                timeframe = (ENUM_TIMEFRAMES)(timeframe + 1);
    You can't do that; PERIOD_M1 is 1 while PERIOD_M5 is 5. There is no timeframe 2, etc. Because the enumerations are not sequential, you can not increment/decrement them to get the next larger/smaller one.
              Why are MT5 ENUM_TIMEFRAMES strange? - General - MQL5 programming forum - Page 2 #11 (2020)

 
William Roeder #:
  1. Why did you post your MT4 question in the MT5 General section instead of the MQL4 section, (bottom of the Root page)?
              General rules and best pratices of the Forum. - General - MQL5 programming forum? (2017)
    Next time, post in the correct place. The moderators will likely move this thread there soon.

  2. Do not assume that bar i on the current chart is bar i on other charts. Always use iBarShift.

  3. On MT4: Unless the current chart is that specific symbol(s)/TF(s) referenced, you must handle 4066/4073 errors before accessing candle/indicator values.
              Download history in MQL4 EA - MQL4 programming forum - Page 3 #26.4 (2019)

  4. You can't do that; PERIOD_M1 is 1 while PERIOD_M5 is 5. There is no timeframe 2, etc. Because the enumerations are not sequential, you can not increment/decrement them to get the next larger/smaller one.
              Why are MT5 ENUM_TIMEFRAMES strange? - General - MQL5 programming forum - Page 2 #11 (2020)

1.  Sorry about that, will know for next time.

2.  Sure, will use iBarShift.  How do I use this to get the previous candle data and the second previous candle data please? @William Roeder

3.  I'm checking GetLastError before using iClose, iOpen etc because I thought that calling those methods would reveal any errors if there are any.  You're saying I need to do this before call iOpen etc?

4.  Thank you, thought I could iterate through.

With regards to the stale date, are you saying I can use the following code?

bool     download_history(ENUM_TIMEFRAMES period=PERIOD_CURRENT){
   return download_history(_Symbol, period);
}
bool     download_history(SYMBOL symbol, ENUM_TIMEFRAMES period=PERIOD_CURRENT){
   if(period == PERIOD_CURRENT)  period = (ENUM_TIMEFRAMES)_Period;
   ResetLastError();    datetime other = iTime(symbol, period, 0);
   if(_LastError == 0 && other != 0)   return true;
   if(_LastError != ERR_HISTORY_WILL_UPDATED
   && _LastError != ERR_NO_HISTORY_DATA
     )   PrintFormat("iTime(%s,%i) Failed: %i", symbol, period, _LastError);
   return false;
}

Thank you.

 
Please don't create topics randomly in any section. It has been moved to the section: MQL4 e MetaTrader 4
 
Fernando Carreiro #:
Please don't create topics randomly in any section. It has been moved to the section: MQL4 e MetaTrader 4
Sorry mate.
 

@William Roeder How do I use  iBarShift to get the previous candle data and the second previous candle data please? 

I would need it to work for any symbol and any timeframe.

Thank you.

William Roeder
William Roeder
  • www.mql5.com
Trader's profile
 
Baz #: @William Roeder How do I use  iBarShift to get the previous candle data and the second previous candle data please? 

There is no “the previous.” There are many previous. Show us your code and state the nature of your difficulty.

Reason: