forked from animatedread/Warrior_EA
TunedPeriodsFileName() inlined the same 9-line StringReplace sanitizer AltData.mqh already defines once as AltDataFileSymbol(), whose own comment said it was meant for exactly this. Gave AltData.mqh a proper include guard (it had none) and included it directly from TunedPeriods.mqh so the call is safe regardless of include order. Compile-verified 0 errors/0 warnings.
103 lines
5.6 KiB
MQL5
103 lines
5.6 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| TunedPeriods.mqh |
|
|
//| AnimateDread |
|
|
//| every consumer of "what period does this indicator run at". |
|
|
//+------------------------------------------------------------------+
|
|
#ifndef WARRIOR_TUNED_PERIODS_MQH
|
|
#define WARRIOR_TUNED_PERIODS_MQH
|
|
//--- AltDataFileSymbol() is the one shared broker-symbol -> safe-file-name-token sanitizer.
|
|
#include "..\System\AltData.mqh"
|
|
//--- Record format version, written as the 10th field. Bumped whenever a field's MEANING changes
|
|
//--- rather than its value; "2" marks MA type as ENUM_MA_METHOD codes. A file without it is v1.
|
|
#define TUNED_PERIODS_VERSION "2"
|
|
//--- Defaults are the seed constants; LoadTunedPeriods() overwrites from the chart's file if present.
|
|
int g_TunedMaPeriod = (int)PeriodMA;
|
|
int g_TunedMaType = (int)MA_Type;
|
|
int g_TunedRsiPeriod = (int)PeriodRSI;
|
|
int g_TunedMacdFast = (int)MACD_PeriodFast;
|
|
int g_TunedMacdSlow = (int)MACD_PeriodSlow;
|
|
int g_TunedMacdSignal = (int)MACD_PeriodSignal;
|
|
int g_TunedIchiTenkan = (int)Ichimoku_PeriodTenkan;
|
|
int g_TunedIchiKijun = (int)Ichimoku_PeriodKijun;
|
|
int g_TunedIchiSenkou = (int)Ichimoku_PeriodSenkou;
|
|
|
|
string TunedPeriodsFileName(void)
|
|
{
|
|
//--- broker symbols can carry path-hostile characters ("EUR/USD"); writing through
|
|
//--- them fails or lands in an unintended subfolder - AltDataFileSymbol() (System\AltData.mqh)
|
|
//--- is the one shared sanitizer for every consumer that builds a path from a broker symbol.
|
|
string sym = AltDataFileSymbol(_Symbol);
|
|
return "Warrior_EA\\TunedPeriods_" + sym + "_" +
|
|
StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period), 7) + ".cfg";
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Read the chart's adopted periods, if any. Call at the TOP of |
|
|
//| OnInit - before ComputeDbConfigFingerprint() and before the |
|
|
//| classic signals are configured. Missing file = seeds stand. |
|
|
//+------------------------------------------------------------------+
|
|
void LoadTunedPeriods(void)
|
|
{
|
|
string name = TunedPeriodsFileName();
|
|
if(!FileIsExist(name, FILE_COMMON))
|
|
return;
|
|
int h = FileOpen(name, FILE_READ | FILE_TXT | FILE_ANSI | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_COMMON);
|
|
if(h == INVALID_HANDLE)
|
|
return;
|
|
string line = FileReadString(h);
|
|
FileClose(h);
|
|
string f[];
|
|
int fields = StringSplit(line, ';', f);
|
|
if(fields < 9)
|
|
{
|
|
Print("TunedPeriods: " + name + " is malformed ('" + line + "') - keeping the seed defaults.");
|
|
return;
|
|
}
|
|
//--- Field 9 is the format version, absent in files written before the ADMovingAverage removal. Those
|
|
//--- store MA type in the retired 0..8 scheme, where the four surviving types sat at 5..8 - see
|
|
//--- SanitizeMaType(). Everything else in the record is unaffected and carries over.
|
|
bool legacy = (fields < 10 || f[9] != TUNED_PERIODS_VERSION);
|
|
g_TunedMaPeriod = (int)StringToInteger(f[0]);
|
|
g_TunedMaType = SanitizeMaType((int)StringToInteger(f[1]), legacy);
|
|
if(legacy)
|
|
PrintFormat("TunedPeriods: %s predates the built-in-MA switch - MA type %d remapped to %d. "
|
|
"The five advanced types (ALMA/DEMA/ZLEMA/T3/Kalman) no longer exist; a file that "
|
|
"stored one falls back to SMA.", name, (int)StringToInteger(f[1]), g_TunedMaType);
|
|
g_TunedRsiPeriod = (int)StringToInteger(f[2]);
|
|
g_TunedMacdFast = (int)StringToInteger(f[3]);
|
|
g_TunedMacdSlow = (int)StringToInteger(f[4]);
|
|
g_TunedMacdSignal = (int)StringToInteger(f[5]);
|
|
g_TunedIchiTenkan = (int)StringToInteger(f[6]);
|
|
g_TunedIchiKijun = (int)StringToInteger(f[7]);
|
|
g_TunedIchiSenkou = (int)StringToInteger(f[8]);
|
|
PrintFormat("TunedPeriods: adopted from %s - MA %d/type %d, RSI %d, MACD %d/%d/%d, Ichimoku %d/%d/%d "
|
|
"(classic votes, DB key and tuner seeds all use these).",
|
|
name, g_TunedMaPeriod, g_TunedMaType, g_TunedRsiPeriod,
|
|
g_TunedMacdFast, g_TunedMacdSlow, g_TunedMacdSignal,
|
|
g_TunedIchiTenkan, g_TunedIchiKijun, g_TunedIchiSenkou);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Persist a gated tuner install's winning periods. Called from |
|
|
//| TuneIndicatorsByFilter on INSTALL only - never for a rejected |
|
|
//| winner, never per trial. Last install wins across ensemble |
|
|
//| members; the values take chart-wide effect on the next attach. |
|
|
//+------------------------------------------------------------------+
|
|
void SaveTunedPeriods(int maPeriod, int maType, int rsiPeriod,
|
|
int macdFast, int macdSlow, int macdSignal,
|
|
int ichiTenkan, int ichiKijun, int ichiSenkou)
|
|
{
|
|
string name = TunedPeriodsFileName();
|
|
int h = FileOpen(name, FILE_WRITE | FILE_TXT | FILE_ANSI | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_COMMON);
|
|
if(h == INVALID_HANDLE)
|
|
{
|
|
PrintFormat("TunedPeriods: cannot write %s (%d) - install still applies to this model's "
|
|
"features; classic votes keep their current periods.", name, GetLastError());
|
|
return;
|
|
}
|
|
FileWriteString(h, StringFormat("%d;%d;%d;%d;%d;%d;%d;%d;%d;%s\n",
|
|
maPeriod, maType, rsiPeriod, macdFast, macdSlow, macdSignal,
|
|
ichiTenkan, ichiKijun, ichiSenkou, TUNED_PERIODS_VERSION));
|
|
FileClose(h);
|
|
PrintFormat("TunedPeriods: install persisted to %s - classic votes and the signal-DB key adopt "
|
|
"these on the next attach (restart-grained by design).", name);
|
|
}
|
|
#endif // WARRIOR_TUNED_PERIODS_MQH
|