forked from animatedread/Warrior_EA
87 lines
3.8 KiB
MQL5
87 lines
3.8 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| ExportAll.mq5 - bars (per timeframe list) to Common\Files |
| |||
//| Throwaway research tool. Opens no trades. |
| |||
//| |
| |||
//| Run via the strategy tester with an ini whose tested symbol has |
| |||
//| the DEEPEST history (EURUSD D1 from 1995): the tester only |
| |||
//| serves history from ~1 year before FromDate, so the tested |
| |||
//| symbol's range sets the ceiling for every CopyRates below. |
| |||
//| |
| |||
//| NOTE: H4 requests for symbols other than the tested one failed |
| |||
//| with err=4401 (history not ready) on a D1 pass. Export H4 in a |
| |||
//| SEPARATE H4 pass rather than expecting one run to do both. |
| |||
//| The calendar is NOT exportable here at all - see ExportCalendar. |
| |||
//+------------------------------------------------------------------+
| |||
#property copyright "claude"
| |||
#property version "1.10"
| |||
| |||
input string ExportTag = "bars";
| |||
input string SymbolsD1 = "SP500,NAS100,US30,DAX40,UK100,ESXEUR,F40EUR,JPN225,ASXAUD,HSIHKD,IBXEUR,EURUSD,GBPUSD,USDJPY,USDCHF,USDCAD,AUDUSD,NZDUSD,EURJPY,EURGBP,GBPJPY,AUDJPY,XAUUSD,XAGUSD,XTIUSD,XBRUSD,BTCUSD,ETHUSD";
| |||
input string SymbolsH4 = "";
| |||
input bool DoCalendar = false;
| |||
| |||
bool DumpBars(const string sym, const ENUM_TIMEFRAMES tf)
| |||
{
| |||
MqlRates r[];
| |||
ArraySetAsSeries(r, false); // oldest -> newest, matches numpy
| |||
int got = CopyRates(sym, tf, 0, 500000, r);
| |||
if(got <= 0)
| |||
{
| |||
PrintFormat("ExportAll: %s %s CopyRates failed (err=%d)", sym, EnumToString(tf), GetLastError());
| |||
return false;
| |||
}
| |||
string name = StringFormat("%s_%s_%s.csv", ExportTag, sym, EnumToString(tf));
| |||
int h = FileOpen(name, FILE_WRITE | FILE_CSV | FILE_ANSI | FILE_COMMON, ',');
| |||
if(h == INVALID_HANDLE)
| |||
return false;
| |||
FileWrite(h, "time", "open", "high", "low", "close", "tick_volume", "spread");
| |||
int digits = (int)SymbolInfoInteger(sym, SYMBOL_DIGITS);
| |||
if(digits <= 0)
| |||
digits = 5;
| |||
for(int i = 0; i < got; i++)
| |||
FileWrite(h, TimeToString(r[i].time, TIME_DATE | TIME_MINUTES),
| |||
DoubleToString(r[i].open, digits), DoubleToString(r[i].high, digits),
| |||
DoubleToString(r[i].low, digits), DoubleToString(r[i].close, digits),
| |||
(string)r[i].tick_volume, (string)r[i].spread);
| |||
FileClose(h);
| |||
PrintFormat("ExportAll: %s %s -> %d bars (%s .. %s)", sym, EnumToString(tf), got,
| |||
TimeToString(r[0].time, TIME_DATE), TimeToString(r[got - 1].time, TIME_DATE));
| |||
return true;
| |||
}
| |||
| |||
void DumpList(const string list, const ENUM_TIMEFRAMES tf, int &ok, int &fail)
| |||
{
| |||
string syms[];
| |||
int n = StringSplit(list, ',', syms);
| |||
for(int i = 0; i < n; i++)
| |||
{
| |||
string s = syms[i];
| |||
StringTrimLeft(s);
| |||
StringTrimRight(s);
| |||
if(StringLen(s) == 0)
| |||
continue;
| |||
//--- without SymbolSelect an unlisted symbol reads back as zero bars and
| |||
//--- looks like missing history rather than an unselected symbol.
| |||
if(!SymbolSelect(s, true))
| |||
PrintFormat("ExportAll: SymbolSelect(%s) failed (err=%d)", s, GetLastError());
| |||
if(DumpBars(s, tf))
| |||
ok++;
| |||
else
| |||
fail++;
| |||
}
| |||
}
| |||
| |||
//--- OnDeinit, not OnInit: by then the tester has walked the whole range, so
| |||
//--- CopyRates returns every bar of the pass rather than only the warm-up.
| |||
void OnDeinit(const int reason)
| |||
{
| |||
int ok = 0, fail = 0;
| |||
if(StringLen(SymbolsD1) > 0)
| |||
DumpList(SymbolsD1, PERIOD_D1, ok, fail);
| |||
if(StringLen(SymbolsH4) > 0)
| |||
DumpList(SymbolsH4, PERIOD_H4, ok, fail);
| |||
PrintFormat("ExportAll: DONE bars ok=%d fail=%d", ok, fail);
| |||
}
| |||
| |||
int OnInit(void) { return(INIT_SUCCEEDED); }
| |||
void OnTick(void) { }
|