Download history in MQL4 EA

 

I need 15M 1H 4H 1D 1W  for all 28 pairs for 30 periods back in my EA.

I have used a very good tool in MQL5 published  here but is there a way of doing this in MQl4?

 
Just wait for the download to complete
In an EA
void OnTick(){
   while(!download_history(PERIOD_M15) ){ Sleep(1000); RefreshRates(); }
   :
In an indicator
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_M15) ) return prev_calculated;
#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) );   }
#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;
}
 

You wrote:

 if(!download_history(PERIOD_M15) ) return prev_calculated;

But shouldn't it be:

 if(!download_history(PERIOD_M15) ) return 0;

As this way the indicator starts to paint itself on the history of the chart as soon as the history has arrived?

 
Carl Schreiber: But shouldn't it be:
Just because you are now missing some history (on some pair,) doesn't mean all previously completed work (if any) is invalid. For example, lose of connection for a minute, why would you want to recalculate everything? Wait for the update and continue from where previously left off.
 

Where do I put this portion of the code?

#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) );   }
#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;
}
 

Hello everyone! I'm doing some tests to figure out how to wait for the data download but nothing happens.


//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window



#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) );   }
#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_H4        /**< 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;
}

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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_H4) ){
 
    
    return prev_calculated;
   }
 
 

    Print("Open:"+DoubleToString(iOpen(Symbol(),240,1),Digits)); 
  
   return(rates_total);
  }
//+------------------------------------------------------------------+

I am in the M30 chart and I want to wait for the data of this symbol to be downloaded for the H4 time frame and then used correctly.

Help me please!!!

 
fly7680: I'm doing some tests to figure out how to wait for the data download but nothing happens.
Not possible, unless you are not connected to a broker or not running the indicator. Use the debugger or print out your variables, including _LastError and find out why.
 

I'm back! I changed my path and after several tests I understood how to download the history of other TimeFrame, is this code correct?

//-- Global Scope
bool TickH4=false;
double OpenH4[];
double CloseH4[];
datetime TempoH4[];

//-- My Function
void CopiaArrayH4(string Asset){
      
   if(!TickH4){
   
      //--- set access to the array like to a timeseries
      ArraySetAsSeries(OpenH4 ,true);
      ArraySetAsSeries(CloseH4,true);       
      ArraySetAsSeries(TempoH4,true); 
      ResetLastError();
      
      int copied1=CopyOpen (Asset,240,0,1100,OpenH4);
      int copied2=CopyClose(Asset,240,0,1100,CloseH4);
      int copied3=CopyTime (Asset,240,0,50,  TempoH4);
      
      if(copied1<=0 || copied2<=0 || copied3<=0){
        
         Print("error+": "+IntegerToString(GetLastError())); //-- if there is no data I receive 4073 error
         return;
        }                
        
        else TickH4=true;
        Print("Data OK");
       }
} 

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[]){
CopiaArrayH4(Symbol());
         if(TickH4){                          //-- my code here only if I have correctly received the data from the server           }
 
Any advice please?
 
fly7680: Any advice please?
  1. Advice about what? You haven't stated a problem or a question.
  2. Because of your TickH4, your arrays will only be updated once. Never again.
 

you're right, I'm sorry I forgot part of the code

Every 240 minutes TickH4 becomes false and enables a new search for data ... is this passage correct? will the data be downloaded again from the Broker server?
When data is downloaded from the server, are it allocated to the Ram on PC or to another folder? I say this because as long as the MT4 is open, in the AppData \ Roaming \ MetaQuotes \ Terminal \ A6DFBB1B8DE9672D2328FF3445436DEC \ history folder there is no data, when the MT4 is closed, the data is actually copied to that folder


//-- Global Scope
bool TickH4=false;
double OpenH4[];
double CloseH4[];
datetime TempoH4[];

datetime lastbar;
datetime prevBar;

//-- Function NewBar
bool NewBar(int timeframe){
   
   prevBar =lastbar; lastbar=iTime(Symbol(),timeframe,0);
   return   prevBar!=lastbar;
}

//-- My Function
void CopiaArrayH4(string Asset){
      
   if(!TickH4){
   
      //--- set access to the array like to a timeseries
      ArraySetAsSeries(OpenH4 ,true);
      ArraySetAsSeries(CloseH4,true);       
      ArraySetAsSeries(TempoH4,true); 
      ResetLastError();
      
      int copied1=CopyOpen (Asset,240,0,1100,OpenH4);
      int copied2=CopyClose(Asset,240,0,1100,CloseH4);
      int copied3=CopyTime (Asset,240,0,50,  TempoH4);
      
      if(copied1<=0 || copied2<=0 || copied3<=0){
        
         Print("error+": "+IntegerToString(GetLastError())); //-- if there is no data I receive 4073 error
         return;
        }                
        
        else TickH4=true;
        Print("Data OK");
       }
} 

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(NewBar(240)) TickH4=false;

        CopiaArrayH4(Symbol());


         if(TickH4){
            
            //-- my code here only if I have correctly received the data from the server
          }
Reason: