Search code examples
csvquantitative-financemql4metatrader4

How to export more than 63 parameters using a FileWrite() function in MQL4?


Below I have the full code that allows me to download the data of one currency pair, the USDJPY

#property copyright ""
#property link      ""
#property version   "1.00"
#property strict
datetime LastActiontime;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
  start("USDJPY",60);  // This will produce daily history for GBPUSD
                       // Copy the above line of code for each currency pair and timeframe, and then press F5 to recompile (or restart MT4)
                       // First parameter must be a valid currency pair, e.g. GBPUSD
                       // Second parameter must be valid timeframe, i.e. one of 1, 5, 15, 30, 60 (=H1), 240 (=H4), 1440 (daily), 10080 (weekly), 43200 (monthly) 
                       // To use the currently displayed chart: out_hist(Symbol(),Period());

  return(0);           // return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
                       //void OnTick()
                       //{
                       //---    
                       // Comparing LastActionTime with the current starting time for the candle
                       // if(LastActiontime!=Time[0]){  //Code to execute once in the bar
                       //    Print("This code is executed only once in the bar started ",Time[0]);
                       //    LastActiontime=Time[0];
                       // }
                       //} 
int start(string ccy, int tf)
{
  string fname = ccy + "," + tf + ".csv";                         // Same folder for each TF (...\experts\files)
//string fname = "TF-" + tf + "\\" + ccy + "," + tf + ".csv";     // Different subfolder for each timeframe
  int handle = FileOpen(fname, FILE_CSV|FILE_WRITE, ",");         // "," means that output data will be separated by commas; change if necessary
  if(LastActiontime!=Time[0] && handle>0)
    {
     FileWrite(handle,"Date,Time,Open,Low,High,Close,Volume,RSI,AC,AD,ADX,Alligator,AO,ATR,BearsPower,Bands,BullsPower,CCI,DeMarker,Envelopes,Force,Fractals,Gator,Ichimoku,BWMFI,Momentum,MFI,MA,OsMA,MACD,OBV,SAR,RVI,StdDev,Stochastic,WPR,Vortex_minus,Vortex_positive,CCI13,CCI12,CCI11,CC10,CCI9,CCI8,CCI7,CCI6,CCI5,CCI4,CCI3,CCI15,CCI16,CCI17,CCI18,CCI19,CCI20,CCI21,CCI22,CCI24,CCI25,CCI26,sstoch");    // This writes the Header record to the file (change or remove to suit)
//   for(int i=0; i<iBars(ccy,tf); i++)                           // Use descending date sequence
     for(int i=iBars(ccy,tf)-1; i>=0; i--)                        // Use ascending date sequence
       {
       string date1 = TimeToStr(iTime(ccy,tf,i),TIME_DATE);


       date1 = StringSubstr(date1,5,2) + "-" + StringSubstr(date1,8,2) + "-" + StringSubstr(date1,0,4);
// NOTE: StringSubstr(date1,5,2) is the MONTH
//       StringSubstr(date1,8,2) is the DAY
//       StringSubstr(date1,0,4) is the YEAR (4 digits)
//       "-" means the separator will be a hyphen
//       So if, for example, you want to change the output date format to DD/MM/YYYY, change the above line of code to:
//     date1 = StringSubstr(date1,8,2) + "/" + StringSubstr(date1,5,2) + "/" + StringSubstr(date1,0,4);

       string time1 = TimeToStr(iTime(ccy,tf,i),TIME_MINUTES);
       FileWrite(handle, date1, time1, iOpen(ccy,tf,i), iLow(ccy,tf,i), iHigh(ccy,tf,i), iClose(ccy,tf,i), iVolume(ccy,tf,i),iRSI(ccy,tf,14,PRICE_CLOSE,i), iAC(ccy,tf,i), iAD(ccy,tf,i),iADX(ccy,tf,14,PRICE_CLOSE,MODE_MAIN,i),iAlligator(ccy,tf,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORJAW,i), iAO(ccy,tf,i), iATR(ccy,tf,14,i), iBearsPower(ccy,tf,13,PRICE_CLOSE,i), iBands(ccy,tf,34,2,0,PRICE_CLOSE,MODE_LOWER,i), iBullsPower(ccy,tf,13,PRICE_CLOSE,i),iCCI(ccy,tf,14,PRICE_TYPICAL,i),iDeMarker(ccy,tf,14,i), iEnvelopes(ccy,tf,14,MODE_SMA,10,PRICE_CLOSE,0.10,MODE_UPPER,i),iForce(ccy,tf,13,MODE_SMA,PRICE_CLOSE,i),iFractals(ccy,tf,MODE_UPPER,i),iGator(ccy,tf,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_UPPER,i),iIchimoku(ccy,tf,9,26,52,MODE_TENKANSEN,i),iBWMFI(ccy,tf,i),iMomentum(ccy,tf,14,PRICE_CLOSE,i), iMFI(ccy,tf,14,i), iMA(ccy,tf,13,8,MODE_SMMA,PRICE_MEDIAN,i), iOsMA(ccy,tf,12,26,9,PRICE_CLOSE,i), iMACD(ccy,tf,12,26,9,PRICE_CLOSE,MODE_MAIN,i),iOBV(ccy,tf,PRICE_CLOSE,i), iSAR(ccy,tf,0.02,0.2,i), iRVI(ccy,tf,10,MODE_MAIN,i), iStdDev(ccy,tf,10,0,MODE_EMA,PRICE_CLOSE,i), iStochastic(ccy,tf,5,3,3,MODE_SMA,0,MODE_MAIN,i), iWPR(ccy,tf,14,i), iCustom(ccy,tf,"Vortex_Indicator",14,1,i),iCustom(ccy,tf,"Vortex_Indicator",14,0,i),iCCI(ccy,tf,13,PRICE_TYPICAL,i),iCCI(ccy,tf,12,PRICE_TYPICAL,i),iCCI(ccy,tf,11,PRICE_TYPICAL,i),iCCI(ccy,tf,10,PRICE_TYPICAL,i),iCCI(ccy,tf,9,PRICE_TYPICAL,i),iCCI(ccy,tf,8,PRICE_TYPICAL,i),iCCI(ccy,tf,7,PRICE_TYPICAL,i),iCCI(ccy,tf,6,PRICE_TYPICAL,i),iCCI(ccy,tf,5,PRICE_TYPICAL,i),iCCI(ccy,tf,4,PRICE_TYPICAL,i),iCCI(ccy,tf,3,PRICE_TYPICAL,i),iCCI(ccy,tf,15,PRICE_TYPICAL,i), iCCI(ccy,tf,16,PRICE_TYPICAL,i),iCCI(ccy,tf,17,PRICE_TYPICAL,i),iCCI(ccy,tf,18,PRICE_TYPICAL,i),iCCI(ccy,tf,19,PRICE_TYPICAL,i),iCCI(ccy,tf,20,PRICE_TYPICAL,i),iCCI(ccy,tf,21,PRICE_TYPICAL,i),iCCI(ccy,tf,22,PRICE_TYPICAL,i),iCCI(ccy,tf,24,PRICE_TYPICAL,i),iCCI(ccy,tf,25,PRICE_TYPICAL,i),iCCI(ccy,tf,26,PRICE_TYPICAL,i),iStochastic(ccy,tf,1,3,3,MODE_SMA,0,MODE_MAIN,i));
// The above line writes the data to the file in the order: date, time, open, low, high, close, volume. Change the order to suit, if necessary      
       }
     FileClose(handle);
     LastActiontime=Time[0];
     Comment("History output complete");     // Display a comment in the upper left corner of the chart to advise that process is complete
    }
//----
   return(0);
  }

As you can see, I have a "Filewrite" near the bottom with different parameters. However, these are just for USDJPY. I would like to write to the same csv file with the same 63 parameters but multiple times for multiple currency pairs such as AUDUSD as shown in the code below.

The code below is what I want to do but doesnt work.

#property copyright ""
#property link      ""
#property version   "1.00"
#property strict
datetime LastActiontime;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{   start("USDJPY",60);  // This will produce daily history for GBPUSD    
    return(0);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---   
  }
int start( string ccy, int tf )
{
    string fname = ccy + "," + tf + ".csv";                         // Same folder for each TF (...\experts\files)
    int handle   = FileOpen( fname, FILE_CSV|FILE_WRITE, "," );     // "," means that output data will be separated by commas; change if necessary
    if (  LastActiontime != Time[0] && handle >  0 )
    {
          FileWrite( handle,     // This writes the Header record to the file (change or remove to suit)
                     "Date,Time,Open,Low,High,Close,Volume,RSI,AC,AD,ADX,Alligator,AO,ATR,BearsPower,Bands,BullsPower,CCI,DeMarker,Envelopes,Force,Fractals,Gator,Ichimoku,BWMFI,Momentum,MFI,MA,OsMA,MACD,OBV,SAR,RVI,StdDev,Stochastic,WPR,Vortex_minus,Vortex_positive,CCI13,CCI12,CCI11,CC10,CCI9,CCI8,CCI7,CCI6,CCI5,CCI4,CCI3,CCI15,CCI16,CCI17,CCI18,CCI19,CCI20,CCI21,CCI22,CCI24,CCI25,CCI26,sstoch,Open,Low,High,Close,Volume,RSI,AC,AD,ADX,Alligator,AO,ATR,BearsPower,Bands,BullsPower,CCI,DeMarker,Envelopes,Force,Fractals,Gator,Ichimoku,BWMFI,Momentum,MFI,MA,OsMA,MACD,OBV,SAR,RVI,StdDev,Stochastic,WPR,Vortex_minus,Vortex_positive,CCI13,CCI12,CCI11,CC10,CCI9,CCI8,CCI7,CCI6,CCI5,CCI4,CCI3,CCI15,CCI16,CCI17,CCI18,CCI19,CCI20,CCI21,CCI22,CCI24,CCI25,CCI26,sstoch"
                     );
//   for (  int i = 0;                    i <  iBars( ccy, tf ); i++ )                           // Use descending date sequence
     for (  int i = iBars( ccy, tf ) - 1; i >= 0;                i-- )                        // Use ascending date sequence
     {
         string date1 = TimeToStr( iTime( ccy, tf, i ), TIME_DATE );
                date1 = StringSubstr( date1, 5, 2 ) + "-"
                      + StringSubstr( date1, 8, 2 ) + "-"
                      + StringSubstr( date1, 0, 4 );
// NOTE: StringSubstr(date1,5,2) is the MONTH
//       StringSubstr(date1,8,2) is the DAY
//       StringSubstr(date1,0,4) is the YEAR (4 digits)
//       "-" means the separator will be a hyphen
//       So if, for example, you want to change the output date format to DD/MM/YYYY, change the above line of code to:
//              date1 = StringSubstr(date1,8,2) + "/" + StringSubstr(date1,5,2) + "/" + StringSubstr(date1,0,4);

         string time1 = TimeToStr( iTime( ccy, tf, i ), TIME_MINUTES );

         FileWrite( handle,
                    date1, time1,
                    iOpen(       ccy, tf, i ),
                    iLow(        ccy, tf, i ),
                    iHigh(       ccy, tf, i ),
                    iClose(      ccy, tf, i ),
                    iVolume(     ccy, tf, i ),
                    iRSI(        ccy, tf, 14, PRICE_CLOSE, i ),
                    iAC(         ccy, tf, i ),
                    iAD(         ccy, tf, i ),
                    iADX(        ccy, tf, 14, PRICE_CLOSE, MODE_MAIN, i ),
                    iAlligator(  ccy, tf, 13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN, MODE_GATORJAW, i ),
                    iAO(         ccy, tf, i ),
                    iATR(        ccy, tf, 14, i ),
                    iBearsPower( ccy, tf, 13, PRICE_CLOSE, i ),
                    iBands(      ccy, tf, 34, 2, 0, PRICE_CLOSE, MODE_LOWER, i ),
                    iBullsPower( ccy, tf, 13, PRICE_CLOSE, i ),
                    iCCI(        ccy, tf, 14, PRICE_TYPICAL, i ),
                    iDeMarker(   ccy, tf, 14, i ),
                    iEnvelopes(ccy,tf,14,MODE_SMA,10,PRICE_CLOSE,0.10,MODE_UPPER,i),iForce(ccy,tf,13,MODE_SMA,PRICE_CLOSE,i),iFractals(ccy,tf,MODE_UPPER,i),iGator(ccy,tf,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_UPPER,i),iIchimoku(ccy,tf,9,26,52,MODE_TENKANSEN,i),iBWMFI(ccy,tf,i),iMomentum(ccy,tf,14,PRICE_CLOSE,i), iMFI(ccy,tf,14,i), iMA(ccy,tf,13,8,MODE_SMMA,PRICE_MEDIAN,i), iOsMA(ccy,tf,12,26,9,PRICE_CLOSE,i), iMACD(ccy,tf,12,26,9,PRICE_CLOSE,MODE_MAIN,i),iOBV(ccy,tf,PRICE_CLOSE,i), iSAR(ccy,tf,0.02,0.2,i), iRVI(ccy,tf,10,MODE_MAIN,i), iStdDev(ccy,tf,10,0,MODE_EMA,PRICE_CLOSE,i), iStochastic(ccy,tf,5,3,3,MODE_SMA,0,MODE_MAIN,i), iWPR(ccy,tf,14,i), iCustom(ccy,tf,"Vortex_Indicator",14,1,i),iCustom(ccy,tf,"Vortex_Indicator",14,0,i),iCCI(ccy,tf,13,PRICE_TYPICAL,i),iCCI(ccy,tf,12,PRICE_TYPICAL,i),iCCI(ccy,tf,11,PRICE_TYPICAL,i),iCCI(ccy,tf,10,PRICE_TYPICAL,i),iCCI(ccy,tf,9,PRICE_TYPICAL,i),iCCI(ccy,tf,8,PRICE_TYPICAL,i),iCCI(ccy,tf,7,PRICE_TYPICAL,i),iCCI(ccy,tf,6,PRICE_TYPICAL,i),iCCI(ccy,tf,5,PRICE_TYPICAL,i),iCCI(ccy,tf,4,PRICE_TYPICAL,i),iCCI(ccy,tf,3,PRICE_TYPICAL,i),iCCI(ccy,tf,15,PRICE_TYPICAL,i), iCCI(ccy,tf,16,PRICE_TYPICAL,i),iCCI(ccy,tf,17,PRICE_TYPICAL,i),iCCI(ccy,tf,18,PRICE_TYPICAL,i),iCCI(ccy,tf,19,PRICE_TYPICAL,i),iCCI(ccy,tf,20,PRICE_TYPICAL,i),iCCI(ccy,tf,21,PRICE_TYPICAL,i),iCCI(ccy,tf,22,PRICE_TYPICAL,i),iCCI(ccy,tf,24,PRICE_TYPICAL,i),iCCI(ccy,tf,25,PRICE_TYPICAL,i),iCCI(ccy,tf,26,PRICE_TYPICAL,i),iStochastic(ccy,tf,1,3,3,MODE_SMA,0,MODE_MAIN,i), iOpen("AUDUSD",tf,i), iLow("AUDUSD",tf,i), iHigh("AUDUSD",tf,i), iClose("AUDUSD",tf,i), iVolume("AUDUSD",tf,i),iRSI("AUDUSD",tf,14,PRICE_CLOSE,i), iAC("AUDUSD",tf,i), iAD("AUDUSD",tf,i),iADX("AUDUSD",tf,14,PRICE_CLOSE,MODE_MAIN,i),iAlligator("AUDUSD",tf,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORJAW,i), iAO("AUDUSD",tf,i), iATR("AUDUSD",tf,14,i), iBearsPower("AUDUSD",tf,13,PRICE_CLOSE,i), iBands("AUDUSD",tf,34,2,0,PRICE_CLOSE,MODE_LOWER,i), iBullsPower("AUDUSD",tf,13,PRICE_CLOSE,i),iCCI("AUDUSD",tf,14,PRICE_TYPICAL,i),iDeMarker("AUDUSD",tf,14,i), iEnvelopes("AUDUSD",tf,14,MODE_SMA,10,PRICE_CLOSE,0.10,MODE_UPPER,i),iForce("AUDUSD",tf,13,MODE_SMA,PRICE_CLOSE,i),iFractals("AUDUSD",tf,MODE_UPPER,i),iGator("AUDUSD",tf,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_UPPER,i),iIchimoku("AUDUSD",tf,9,26,52,MODE_TENKANSEN,i),iBWMFI("AUDUSD",tf,i),iMomentum("AUDUSD",tf,14,PRICE_CLOSE,i), iMFI("AUDUSD",tf,14,i), iMA("AUDUSD",tf,13,8,MODE_SMMA,PRICE_MEDIAN,i), iOsMA("AUDUSD",tf,12,26,9,PRICE_CLOSE,i), iMACD("AUDUSD",tf,12,26,9,PRICE_CLOSE,MODE_MAIN,i),iOBV("AUDUSD",tf,PRICE_CLOSE,i), iSAR("AUDUSD",tf,0.02,0.2,i), iRVI("AUDUSD",tf,10,MODE_MAIN,i), iStdDev("AUDUSD",tf,10,0,MODE_EMA,PRICE_CLOSE,i), iStochastic("AUDUSD",tf,5,3,3,MODE_SMA,0,MODE_MAIN,i), iWPR("AUDUSD",tf,14,i), iCustom("AUDUSD",tf,"Vortex_Indicator",14,1,i),iCustom("AUDUSD",tf,"Vortex_Indicator",14,0,i),iCCI("AUDUSD",tf,13,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,12,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,11,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,10,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,9,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,8,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,7,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,6,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,5,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,4,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,3,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,15,PRICE_TYPICAL,i), iCCI("AUDUSD",tf,16,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,17,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,18,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,19,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,20,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,21,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,22,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,24,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,25,PRICE_TYPICAL,i),iCCI("AUDUSD",tf,26,PRICE_TYPICAL,i),iStochastic("AUDUSD",tf,1,3,3,MODE_SMA,0,MODE_MAIN,i),
                    );
     // The above line writes the data to the file in the order: date, time, open, low, high, close, volume. Change the order to suit, if necessary      
     }
     FileClose(handle);
     LastActiontime=Time[0];
     Comment("History output complete");     // Display a comment in the upper left corner of the chart to advise that process is complete
    }
//----
   return(0);
  }

Solution

  • Step 0: Space-X "Just Read the Instructions" has some value:

    The MQL4 code-execution environment has several specific forms of code. You have chosen the second least-feasible and 've hacked the specific-purpose OnInit(){...} handler, so as to do the job you need via an immediate call to start( str, int ).

    The appropriate step to do this is to use an MQL4-script, where a plain start-stop sequence of operation does not destabilise other MetaTrader 4 Terminal real-time execution tuned facilites.

    Script is a program intended for a single execution of some actions. Unlike Expert Advisors, scripts do not process any actions, except for the start event ( this requires the OnStart(){...} handler function in a script ). Scripts are stored in terminal_directory\MQL4\Scripts


    Next: The "Just Read the Instructions" principle will show:

    FileWrite

    Parameters

    file_handle
    

    [in] File descriptor returned by FileOpen().

    ...

    [in] The list of parameters separated by commas, to write to the file. The number of written parameters can be up to 63.


    Solution: Again, "Just Read the Instructions" is well enough:

    StringFormat will not work either:

    Total number of parameters can't exceed 64 including the format string.

    Your way is to ( yes, read the documentation :o) and ... ) use a trivial composition step:

    StringConcatenate(  a, //  1.
                        b, //  2.
                        c,
                        ..
                        zz // 63.
                        );
    

    Once I needed to have more parameters assembled, so 've used:

    StringConcatenate( StringConcatenate( a_1, b_1, c_1, ..., zz_1 ),
                       StringConcatenate( a_2, b_2, c_2, ..., zz_2 ),
                       StringConcatenate( a_3, b_3, c_3, ..., zz_3 ),
                       ...
                       StringConcatenate( a63, b63, c63, ..., zz63 )
                       );
    

    Deeper nesting still possible, so 63*63*63 ... *63 may grow, until the RAM remains to suffice.


    Epilogue:

    It should be also noted, that initialising an MQL4-Script on a GBPUSD-graph will make accessible the GBPUSD-section of the MetaTrader4 Terminal. More care is needed, if one wants to read the graph-non-local currency TOHLCV-records, the more, if the MetaTrader4 Terminal [ History Centre ] has not yet such records collected from some previous interactions with the MetaTrader4 Server-side repository.