Download history in MQL4 EA - page 3

William Roeder
25075
William Roeder  
minor corrections
int      TimeOfDay(datetime when=0){      if(when == 0)  when = TimeCurrent();
                                          return( int(when % HR2400) );            }

  if(_LastError != ERR_HISTORY_WILL_UPDATED
   && _LastError != ERR_NO_HISTORY_DATA
   )  Print(StringFormat("iTime(%s,%i) Failed: %i", symbol, period,_LastError));
jsftrade
8
jsftrade  
William Roeder:
minor corrections

Hi William,
I am having problems with this code.

I have made the minor corrections, It just keeps returning false. Never returns true. Am I doing something wrong?

William Roeder
25075
William Roeder  
jsftrade: I have made the minor corrections, It just keeps returning false. Never returns true. Am I doing something wrong?
Yes, expecting an answer! We can't see your broken code. There are no mind readers here and our crystal balls are cracked.
jsftrade
8
jsftrade  
William Roeder:
Yes, expecting an answer! We can't see your broken code. There are no mind readers here and our crystal balls are cracked.;-)

Thank you for your reply, If we had the crystal ball we would not be trading :-)

I just copied and pasted the code from this form, but only returns Failed: 0

2019.05.14 20:27:19.063 TestIndicator USDJPY,M30: iTime(USDJPY,30) Failed: 0

Which does not make sense. If the Fail code is 0 then there is no error, I thought. 

Here is the code, I hope you can see something I am doing wrong.

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) {
//---
   
      if( !download_history(PERIOD_CURRENT) ) return prev_calculated;
         else Print( "Good download of history");
         
//--- return value of prev_calculated for next call
   return(rates_total);
}
#define HR2400 PERIOD_D1 * 60    // 86400 = 24 * 3600
int      TimeOfDay(datetime when=0){      if(when == 0)  when = TimeCurrent();
                                          return( int(when % HR2400) );            }
datetime DateOfDay(datetime when=0){      if(when == 0)  when = TimeCurrent();
                                          return( when - TimeOfDay(when) );   }
#define SYMBOL string
#define THIS_SYMBOL ""
bool  download_history(ENUM_TIMEFRAMES period=PERIOD_CURRENT){
   return download_history(_Symbol, period); 
}
bool  download_history(
      SYMBOL            symbol=THIS_SYMBOL,     ///< The symbol required.
      ENUM_TIMEFRAMES   period=PERIOD_CURRENT   /**< The standard timeframe.*/){
   if(symbol == THIS_SYMBOL)     symbol = _Symbol;
   if(period == PERIOD_CURRENT)  period = _Period;
   datetime today = DateOfDay();
   ResetLastError();
   datetime other = iTime(symbol, period, 0);
   if(_LastError == 0 
   && today == DateOfDay(other)) return true;   
   if(_LastError != ERR_HISTORY_WILL_UPDATED
   && _LastError != ERR_NO_HISTORY_DATA )
      Print(StringFormat("iTime(%s,%i) Failed: %i", symbol, period,_LastError));
   return false;
}
jsftrade
8
jsftrade  
William Roeder:
Yes, expecting an answer! We can't see your broken code. There are no mind readers here and our crystal balls are cracked.

Did you find anything wrong with the code?

William Roeder
25075
William Roeder  
  1. jsftrade: Did you find anything wrong with the code?
    if( !download_history(PERIOD_CURRENT) ) return prev_calculated;

    Why are you using current? That will always be correct. It's purpose is to get other symbols/TFs.

  2. jsftrade:

    2019.05.14 20:27:19.063 TestIndicator USDJPY,M30: iTime(USDJPY,30) Failed: 0

    Which does not make sense. If the Fail code is 0 then there is no error, I thought.

    Correct.

  3. #define HR2400 PERIOD_D1 * 60    // 86400 = 24 * 3600
    Had to go to my sources. Originally had HR2400 86400. Changed it sometime to the above which broke it. Equal precedence, left to right: dt % PERIOD_D1 * 60 not equal to dt % (PERIOD_D1 * 60).
    #define HR2400 (PERIOD_D1 * 60 // 86400 = 24 * 3600
    

  4. Wouldn't have been a problem if you had used the corrected version which doesn't use TimeOfDay(). Try this:
    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;
    }

jsftrade
8
jsftrade  
William Roeder:
  1. Why are you using current? That will always be correct. It's purpose is to get other symbols/TFs.

  2. Correct.

  3. Had to go to my sources. Originally had HR2400 86400. Changed it sometime to the above which broke it. Equal precedence, left to right: dt % PERIOD_D1 * 60 not equal to dt % (PERIOD_D1 * 60).

  4. Wouldn't have been a problem if you had used the corrected version which doesn't use TimeOfDay(). Try this:
Thank you William. It now works. Appreciate your help.
Cezarion
52
Cezarion  

Hello, 

I have a problem strongly related with this thread. I want to read iHigh and iLow from D1 timeframe being on H1.

During testing my EA I added to chart my indicator. Indicator contain code posted belowe.

When I try to read iHigh(NULL,PERIOD_D1,0) I have always the same value and the same amount of bars using this iBars(NULL,PERIOD_D1). 

What can be still wrong?

#define HR2400 86400
#define SYMBOL string
#define THIS_SYMBOL ""

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

  if( !download_history(PERIOD_D1) ) return prev_calculated;
         else Print( "Good download of history.  ",
iHigh("USDJPY+",PERIOD_D1,0)," ",iBars(NULL,PERIOD_D1)); 
  

   return(rates_total);
  }
  
//+------------------------------------------------------------------+
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;
} 
Quint Boney
5508
Quint Boney  

I wonder how many EA have looked really well in Backtesting, only to generate incorrect trades on live/demo... How many custom MTF indicators out there are useless? Completely incorrect data is far more of a problem that repainting ever was!

The fact that ERR 4066 will fail silent on subsequent attempts is a coding nightmare. 

From Williams Post  155707:

 * 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.

Thanks to William &  Alain for these efforts, starting back in post 155707. Your detail and efforts are massively appreciated.

真 木 英 maki
169
真 木 英 maki  

Looking at the error does not help.

if(_LastError == 0 && other != 0){Print(other); return true;}

This will display past times for some pairs.