ответвлён от animatedread/Warrior_EA
Recovered live config (z20 <= -1.5, exit SMA20 / 10 bars, 3xATR) plus a Garman-Klass vol-regime gate. Expectancy is monotone in the vol regime in IS, OOS and full sample, 4/4 indices; the gate reverses on USDJPY/XAUUSD. D1 2008-2026 survives 2008/2020/2022 (maxDD 2.8%, ret/DD 7.74); the gate halves trades, so it belongs on H4, never D1. reconcile.py matches the EA to the backtest trade by trade; combine_charts.py rebuilds the account curve from per-chart tester runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 строки
3,2 КиБ
MQL5
70 строки
3,2 КиБ
MQL5
//+------------------------------------------------------------------+
|
|
//| ExportCalendar.mq5 - dump the economic calendar to Common\Files |
|
|
//| |
|
|
//| MUST RUN ON A LIVE CHART, not in the tester: |
|
|
//| tester -> CalendarValueHistory() returns -1, err=4014 |
|
|
//| ("function not allowed") |
|
|
//| live chart -> works, BUT on this install it returned 0 with |
|
|
//| err=0: the terminal has NO calendar database |
|
|
//| (there is no bases/*/calendar directory). |
|
|
//| Open the Calendar tab in MT5 once so the terminal downloads it, |
|
|
//| then re-attach this. |
|
|
//| |
|
|
//| Auto-attach without touching the GUI via an ini [StartUp] block: |
|
|
//| [StartUp] |
|
|
//| Expert=_claude_build\ExportCalendar |
|
|
//| Symbol=EURUSD |
|
|
//| Period=H1 |
|
|
//| Work is done in OnInit so a single attach is enough. |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "claude"
|
|
#property version "1.00"
|
|
|
|
int OnInit(void)
|
|
{
|
|
MqlCalendarValue vals[];
|
|
datetime from = D'1998.01.01';
|
|
datetime to = D'2027.01.01';
|
|
int got = CalendarValueHistory(vals, from, to, NULL, NULL);
|
|
if(got <= 0)
|
|
{
|
|
PrintFormat("ExportCalendar: CalendarValueHistory returned %d (err=%d)",
|
|
got, GetLastError());
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
int h = FileOpen("calendar.csv", FILE_WRITE | FILE_CSV | FILE_ANSI | FILE_COMMON, ',');
|
|
if(h == INVALID_HANDLE)
|
|
{
|
|
PrintFormat("ExportCalendar: FileOpen failed (err=%d)", GetLastError());
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
FileWrite(h, "time", "currency", "importance", "event_id", "name",
|
|
"actual", "forecast", "previous");
|
|
int written = 0;
|
|
for(int i = 0; i < got; i++)
|
|
{
|
|
MqlCalendarEvent ev;
|
|
if(!CalendarEventById(vals[i].event_id, ev))
|
|
continue;
|
|
MqlCalendarCountry cty;
|
|
string cur = "";
|
|
if(CalendarCountryById(ev.country_id, cty))
|
|
cur = cty.currency;
|
|
//--- the name is the one free-text column, so it is sanitised rather
|
|
//--- than trusted not to contain the delimiter.
|
|
string nm = ev.name;
|
|
StringReplace(nm, ",", ";");
|
|
FileWrite(h, TimeToString(vals[i].time, TIME_DATE | TIME_MINUTES),
|
|
cur, (string)(int)ev.importance, (string)vals[i].event_id, nm,
|
|
(vals[i].HasActualValue() ? DoubleToString(vals[i].GetActualValue(), 4) : ""),
|
|
(vals[i].HasForecastValue() ? DoubleToString(vals[i].GetForecastValue(), 4) : ""),
|
|
(vals[i].HasPreviousValue() ? DoubleToString(vals[i].GetPreviousValue(), 4) : ""));
|
|
written++;
|
|
}
|
|
FileClose(h);
|
|
PrintFormat("ExportCalendar: wrote %d of %d values", written, got);
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
void OnTick(void) { }
|
|
void OnDeinit(const int reason) { }
|