//+------------------------------------------------------------------+
//|                                  QuoteToExcel_MultiPair v2.0.mq4 |
//|                                     'gilani' at forexfactory.com |

#include <stdlib.mqh>


bool DoHistoryAvailabilecheck = False;

string pairs[]  = {"EURAUD","EURCAD","EURCHF","EURGBP","EURJPY","EURNZD","EURUSD","CHFJPY","CADJPY","USDJPY","NZDJPY","GBPJPY","AUDJPY","GBPUSD","AUDUSD","NZDUSD","USDCHF","USDCAD","GBPNZD","GBPCAD","GBPCHF","NZDCAD","AUDNZD","GBPAUD","AUDCAD","AUDCHF","CADCHF","NZDCHF","USDLFX","EURLFX","GBPLFX","CHFLFX","LFXJPY","CADLFX","AUDLFX","NZDLFX"};

string months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
string name; 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int totalPairs;

int init() {
   name = "MT4Export";
   totalPairs = ArraySize (pairs);  
       
   return (0);

}

int start() {
   
   if (IsConnected() == false) {
      Alert ("You must be connected to the server first!");
      return (0);
   }

   /*for (int x=0; x<totalPairs; x++) { //asking for updates for H1 & D1 so that the reqest is sent in parallel.
      iBars(pairs[x], PERIOD_D1);
      iBars(pairs[x], PERIOD_W1);
      iBars(pairs[x], PERIOD_MN1);
      iBars(pairs[x], PERIOD_H4);
   }*/
  
   if(DoHistoryAvailabilecheck)
   {   
      bool HistoryAvailable = isHistoryAvailable(PERIOD_D1);  
      if(HistoryAvailable) HistoryAvailable = isHistoryAvailable(PERIOD_W1);
      if(HistoryAvailable) HistoryAvailable = isHistoryAvailable(PERIOD_MN1);
      if(HistoryAvailable) HistoryAvailable = isHistoryAvailable(PERIOD_H4);

      if(!HistoryAvailable) return;
   }
       
   bool isError=False;
   int err = generateFile();
   if (err != 0) 
   {
      Alert("Symbol Error(",err,"): ",ErrorDescription(err));
      isError = true;
   }
   
   //string msg = periodDesc(period)+" for "+totalPairs+" pairs - "+StringSubstr(pairNames,0, StringLen(pairNames)-1);
   
   if (isError == false) {
      Alert(name+" - Successfully exported history data on all pairs and all time frames");
   } else {
      Alert(name+" - Export unsuccessful! Please check the errors.");
   }
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isHistoryAvailable (int period) 
{
   int err = 0;
   
   err = checkHistoryAvailability (period);
   if (err != 0) {
      Alert ("Error "+err+" - local history files being updated!. Please rerun the script later");   
      return (False);
   }
   
   return (True);
}
  
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int generateFile () {
   double D0O,D0H,D0L,D0C,D1O,D1H,D1L,D1C,W0O,W0H,W0L,W0C,W1O,W1H,W1L,W1C,M0O,M0H,M0L,M0C,M1O,M1H,M1L,M1C,H40O,H40H,H40L,H40C,H41O,H41H,H41L,H41C;   
   string symbol;
   //int handle=FileOpen(StringSubstr(symbol,0,6) + "_" + periodDesc(period)+".csv", FILE_CSV|FILE_WRITE, ',');
   int handle=FileOpen("mt4export.csv", FILE_CSV|FILE_WRITE, ',');
   
   if(handle>=0)
   {
      FileWrite(handle, "SYMBOL","D0_OPEN","D0_HIGH","D0_LOW","D0_CLOSE","D1_OPEN","D1_HIGH","D1_LOW","D1_CLOSE","W0_OPEN","W0_HIGH","W0_LOW","W0_CLOSE","W1_OPEN","W1_HIGH","W1_LOW","W1_CLOSE","M0_OPEN","M0_HIGH","M0_LOW","M0_CLOSE","M1_OPEN","M1_HIGH","M1_LOW","M1_CLOSE","H40_OPEN","H40_HIGH","H40_LOW","H40_CLOSE","H41_OPEN","H41_HIGH","H41_LOW","H41_CLOSE");

      for (int x=0; x<totalPairs; x++) 
      {
         symbol =(pairs[x]);
      
         if(handle>0) 
         {
            D0O = iOpen (symbol, 1440, 0);
            D0H = iHigh (symbol, 1440, 0);      
            D0L = iLow  (symbol, 1440, 0);      
            D0C = iClose(symbol, 1440, 0);
            D1O = iOpen (symbol, 1440, 1);
            D1H = iHigh (symbol, 1440, 1);      
            D1L = iLow  (symbol, 1440, 1);      
            D1C = iClose(symbol, 1440, 1);               
            W0O = iOpen (symbol, 10080, 0);
            W0H = iHigh (symbol, 10080, 0);      
            W0L = iLow  (symbol, 10080, 0);      
            W0C = iClose(symbol, 10080, 0);
            W1O = iOpen (symbol, 10080, 1);
            W1H = iHigh (symbol, 10080, 1);      
            W1L = iLow  (symbol, 10080, 1);      
            W1C = iClose(symbol, 10080, 1);
            M0O = iOpen (symbol, 43200, 0);
            M0H = iHigh (symbol, 43200, 0);      
            M0L = iLow  (symbol, 43200, 0);      
            M0C = iClose(symbol, 43200, 0);
            M1O = iOpen (symbol, 43200, 1);
            M1H = iHigh (symbol, 43200, 1);      
            M1L = iLow  (symbol, 43200, 1);      
            M1C = iClose(symbol, 43200, 1);  
            H40O = iOpen (symbol, 240, 0);
            H40H = iHigh (symbol, 240, 0);      
            H40L = iLow  (symbol, 240, 0);      
            H40C = iClose(symbol, 240, 0);
            H41O = iOpen (symbol, 240, 1);
            H41H = iHigh (symbol, 240, 1);      
            H41L = iLow  (symbol, 240, 1);      
            H41C = iClose(symbol, 240, 1); 

            FileWrite(handle, symbol,D0O,D0H,D0L,D0C,D1O,D1H,D1L,D1C,W0O,W0H,W0L,W0C,W1O,W1H,W1L,W1C,M0O,M0H,M0L,M0C,M1O,M1H,M1L,M1C,H40O,H40H,H40L,H40C,H41O,H41H,H41L,H41C);
        }
      } 
      FileClose(handle);
   }

   return(GetLastError());
}
  
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
/*string periodDesc(int period) {
   switch (period) {
      case PERIOD_M1:  return ("M1");
      case PERIOD_M5:  return ("M5");
      case PERIOD_M15: return ("M15");
      case PERIOD_M30: return ("M30");
      case PERIOD_H1:  return ("H1");
      case PERIOD_H4:  return ("H4");
      case PERIOD_D1:  return ("D1");
      case PERIOD_W1:  return ("W1");
      case PERIOD_MN1:  return ("MN1");
   }
   return ("");
}*/

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int checkHistoryAvailability(int period) {
   int bars;
   int err;
   int pause = 5;
   
   int maxBars = maxBarsToRead(period);
   
   for (int i=0;i <10; i++) {
      bars = maxBars;
      for (int x=0; x<totalPairs; x++) {
         int getBars = iBars(pairs[x], period);
         if (getBars < maxBars) bars = getBars;
      }
      err = GetLastError();
      if (err != 0 || bars < maxBars) {
         Alert ("Local history files are being updated from the server. Attempting again in "+pause+" seconds... ");
         Sleep (pause*1000);
         pause += 0;
      } else {
         break;
      }
   }
   return (err);
}   

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int maxBarsToRead (int period) {
   switch (period) {
      case PERIOD_D1:  return (4);
      case PERIOD_W1:  return (4);
      case PERIOD_MN1: return (4);
      case PERIOD_H4: return (4);
   }
      
  return (0);
  
}