2026-08-16 15:12:54 -04:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| TunedPeriods.mqh |
|
|
|
|
|
//| AnimateDread |
|
2026-08-22 00:30:14 -04:00
|
|
|
//| every consumer of "what period does this indicator run at". |
|
2026-08-16 15:12:54 -04:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#ifndef WARRIOR_TUNED_PERIODS_MQH
|
|
|
|
|
#define WARRIOR_TUNED_PERIODS_MQH
|
feat(indicators): run the built-in iMA and MetaTrader's ZigZag; add a classic-vote shift
MA: CustomIndicators\ADMovingAverage is replaced by the built-in iMA (CiMA) on
both consumers - the classic vote and the NN MA input feature. This drops the
five advanced types ALMA/DEMA/ZLEMA/T3/Kalman, which have no iMA equivalent;
MA_TYPE_PRESETS is now ENUM_MA_METHOD's own codes and the tuner searches all
four. It also removes a documented failure mode: a custom indicator's depth is
bounded by TERMINAL_MAXBARS, and m_MA was the one whose feature block REJECTS
the bar on a short read - the "feature 25 fails on every bar" incident of
2026-08-17. A built-in is served at any depth.
MIGRATION. SMA moves from code 5 to 0, so persisted type codes change meaning.
SanitizeMaType() is the single validity rule; TunedPeriods records now carry a
version field and a v1 record remaps 5..8 -> 0..3, falling back to SMA for a
stored advanced type (unrecoverable - old 0..4 are indistinguishable from valid
new codes). Existing .nnw files re-key on their own, because MA_Type is hashed
into the topology fingerprint, so models retrain rather than silently running
on different MA values. EXPECT A FULL RETRAIN.
ZigZag: ADZigZag was a byte-identical rename of MetaQuotes' Examples\ZigZag -
verified by normalising identifiers and stripping comments, 233 significant
lines each with only renamed symbols differing. It now loads the stock one, so
nothing is bundled and MetaQuotes' fixes arrive without a rebuild here. Both
#resource entries are gone.
Classic_Shift: a new input, the BAR the four classic votes evaluate on (0 =
forming, 1 = last closed, default 1). One implementation on CExpertSignalCustom,
inherited by all four rather than repeated per module. Defaults to a sentinel
meaning "unset", so the AI signals and the aggregate keep the stock every_tick
rule and their feature/label alignment is untouched. The META corpus sweep still
takes precedence. CExpertBase::StartIndex turns out to be virtual, so this is a
real override, not the name-hiding the old comment claimed.
Not compiled - MetaEditor compile pending.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:09:58 -04:00
|
|
|
//--- 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"
|
2026-08-16 15:12:54 -04:00
|
|
|
//--- 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)
|
|
|
|
|
{
|
fix(altdata): robustness pass for arbitrary symbol/timeframe - validation + error handling
Systematic audit of the alt-data stack against "any symbol, any timeframe",
prompted by the H4 surprise. Findings, each fixed:
CAPACITY: ALTDATA_MAX_FEATURES was 16 with FX symbols already at 15 - the next
added column would have been silently truncated by a MathMin. Raised to 32,
pin-chars 512 -> 1024.
SYMBOL NAMES: the panel reload path re-derived symbol/timeframe by splitting
the file path on its FIRST underscore - mis-parsing every symbol containing
one (OANDA-style EUR_USD and US_500 are in our own alias lists) and knowing
only three timeframes. It now stores the (symbol, period) Load() was called
with and reuses them verbatim. Path-hostile characters in broker symbols
("EUR/USD") are sanitized by a shared AltDataFileSymbol() used by the panel,
the fetcher and TunedPeriods, so a slash cannot route a write into an
unintended subfolder.
DOWNLOAD VALIDATION: every FRED-family fetch now enforces a per-series
plausibility band (VIX 1-200, yields -5..30, CPI index 20-1000, ...) -
StringToDouble on transport garbage returns 0.0, and one absurd value poisons
every change/percentile feature computed across it (the BatchNorm NaN-latch
incident came from exactly one huge-but-finite input). Rejected rows are
counted and reported, never dropped silently.
LOUD EMPTINESS: a successful response with zero observations on an empty
cache now says so - naming the series (wrong id / format drift) or the COT
predicate (the unverified like-clauses) instead of leaving 0-filled features
unexplained. GEX gains a truncation guard: a day-over-day contract-count
collapse >50% is the fingerprint of a partial 13 MB download, not of markets,
and is skipped rather than recorded as a plausible-but-wrong number.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 17:59:10 -04:00
|
|
|
//--- broker symbols can carry path-hostile characters ("EUR/USD"); writing through
|
|
|
|
|
//--- them fails or lands in an unintended subfolder (same rule as AltDataFileSymbol)
|
|
|
|
|
string sym = _Symbol;
|
|
|
|
|
StringReplace(sym, "/", "-");
|
|
|
|
|
StringReplace(sym, "\\", "-");
|
|
|
|
|
StringReplace(sym, ":", "-");
|
|
|
|
|
StringReplace(sym, "*", "-");
|
|
|
|
|
StringReplace(sym, "?", "-");
|
|
|
|
|
StringReplace(sym, "\"", "-");
|
|
|
|
|
StringReplace(sym, "<", "-");
|
|
|
|
|
StringReplace(sym, ">", "-");
|
|
|
|
|
StringReplace(sym, "|", "-");
|
|
|
|
|
return "Warrior_EA\\TunedPeriods_" + sym + "_" +
|
2026-08-16 15:12:54 -04:00
|
|
|
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[];
|
feat(indicators): run the built-in iMA and MetaTrader's ZigZag; add a classic-vote shift
MA: CustomIndicators\ADMovingAverage is replaced by the built-in iMA (CiMA) on
both consumers - the classic vote and the NN MA input feature. This drops the
five advanced types ALMA/DEMA/ZLEMA/T3/Kalman, which have no iMA equivalent;
MA_TYPE_PRESETS is now ENUM_MA_METHOD's own codes and the tuner searches all
four. It also removes a documented failure mode: a custom indicator's depth is
bounded by TERMINAL_MAXBARS, and m_MA was the one whose feature block REJECTS
the bar on a short read - the "feature 25 fails on every bar" incident of
2026-08-17. A built-in is served at any depth.
MIGRATION. SMA moves from code 5 to 0, so persisted type codes change meaning.
SanitizeMaType() is the single validity rule; TunedPeriods records now carry a
version field and a v1 record remaps 5..8 -> 0..3, falling back to SMA for a
stored advanced type (unrecoverable - old 0..4 are indistinguishable from valid
new codes). Existing .nnw files re-key on their own, because MA_Type is hashed
into the topology fingerprint, so models retrain rather than silently running
on different MA values. EXPECT A FULL RETRAIN.
ZigZag: ADZigZag was a byte-identical rename of MetaQuotes' Examples\ZigZag -
verified by normalising identifiers and stripping comments, 233 significant
lines each with only renamed symbols differing. It now loads the stock one, so
nothing is bundled and MetaQuotes' fixes arrive without a rebuild here. Both
#resource entries are gone.
Classic_Shift: a new input, the BAR the four classic votes evaluate on (0 =
forming, 1 = last closed, default 1). One implementation on CExpertSignalCustom,
inherited by all four rather than repeated per module. Defaults to a sentinel
meaning "unset", so the AI signals and the aggregate keep the stock every_tick
rule and their feature/label alignment is untouched. The META corpus sweep still
takes precedence. CExpertBase::StartIndex turns out to be virtual, so this is a
real override, not the name-hiding the old comment claimed.
Not compiled - MetaEditor compile pending.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:09:58 -04:00
|
|
|
int fields = StringSplit(line, ';', f);
|
|
|
|
|
if(fields < 9)
|
2026-08-16 15:12:54 -04:00
|
|
|
{
|
|
|
|
|
Print("TunedPeriods: " + name + " is malformed ('" + line + "') - keeping the seed defaults.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
feat(indicators): run the built-in iMA and MetaTrader's ZigZag; add a classic-vote shift
MA: CustomIndicators\ADMovingAverage is replaced by the built-in iMA (CiMA) on
both consumers - the classic vote and the NN MA input feature. This drops the
five advanced types ALMA/DEMA/ZLEMA/T3/Kalman, which have no iMA equivalent;
MA_TYPE_PRESETS is now ENUM_MA_METHOD's own codes and the tuner searches all
four. It also removes a documented failure mode: a custom indicator's depth is
bounded by TERMINAL_MAXBARS, and m_MA was the one whose feature block REJECTS
the bar on a short read - the "feature 25 fails on every bar" incident of
2026-08-17. A built-in is served at any depth.
MIGRATION. SMA moves from code 5 to 0, so persisted type codes change meaning.
SanitizeMaType() is the single validity rule; TunedPeriods records now carry a
version field and a v1 record remaps 5..8 -> 0..3, falling back to SMA for a
stored advanced type (unrecoverable - old 0..4 are indistinguishable from valid
new codes). Existing .nnw files re-key on their own, because MA_Type is hashed
into the topology fingerprint, so models retrain rather than silently running
on different MA values. EXPECT A FULL RETRAIN.
ZigZag: ADZigZag was a byte-identical rename of MetaQuotes' Examples\ZigZag -
verified by normalising identifiers and stripping comments, 233 significant
lines each with only renamed symbols differing. It now loads the stock one, so
nothing is bundled and MetaQuotes' fixes arrive without a rebuild here. Both
#resource entries are gone.
Classic_Shift: a new input, the BAR the four classic votes evaluate on (0 =
forming, 1 = last closed, default 1). One implementation on CExpertSignalCustom,
inherited by all four rather than repeated per module. Defaults to a sentinel
meaning "unset", so the AI signals and the aggregate keep the stock every_tick
rule and their feature/label alignment is untouched. The META corpus sweep still
takes precedence. CExpertBase::StartIndex turns out to be virtual, so this is a
real override, not the name-hiding the old comment claimed.
Not compiled - MetaEditor compile pending.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:09:58 -04:00
|
|
|
//--- 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);
|
2026-08-16 15:12:54 -04:00
|
|
|
g_TunedMaPeriod = (int)StringToInteger(f[0]);
|
feat(indicators): run the built-in iMA and MetaTrader's ZigZag; add a classic-vote shift
MA: CustomIndicators\ADMovingAverage is replaced by the built-in iMA (CiMA) on
both consumers - the classic vote and the NN MA input feature. This drops the
five advanced types ALMA/DEMA/ZLEMA/T3/Kalman, which have no iMA equivalent;
MA_TYPE_PRESETS is now ENUM_MA_METHOD's own codes and the tuner searches all
four. It also removes a documented failure mode: a custom indicator's depth is
bounded by TERMINAL_MAXBARS, and m_MA was the one whose feature block REJECTS
the bar on a short read - the "feature 25 fails on every bar" incident of
2026-08-17. A built-in is served at any depth.
MIGRATION. SMA moves from code 5 to 0, so persisted type codes change meaning.
SanitizeMaType() is the single validity rule; TunedPeriods records now carry a
version field and a v1 record remaps 5..8 -> 0..3, falling back to SMA for a
stored advanced type (unrecoverable - old 0..4 are indistinguishable from valid
new codes). Existing .nnw files re-key on their own, because MA_Type is hashed
into the topology fingerprint, so models retrain rather than silently running
on different MA values. EXPECT A FULL RETRAIN.
ZigZag: ADZigZag was a byte-identical rename of MetaQuotes' Examples\ZigZag -
verified by normalising identifiers and stripping comments, 233 significant
lines each with only renamed symbols differing. It now loads the stock one, so
nothing is bundled and MetaQuotes' fixes arrive without a rebuild here. Both
#resource entries are gone.
Classic_Shift: a new input, the BAR the four classic votes evaluate on (0 =
forming, 1 = last closed, default 1). One implementation on CExpertSignalCustom,
inherited by all four rather than repeated per module. Defaults to a sentinel
meaning "unset", so the AI signals and the aggregate keep the stock every_tick
rule and their feature/label alignment is untouched. The META corpus sweep still
takes precedence. CExpertBase::StartIndex turns out to be virtual, so this is a
real override, not the name-hiding the old comment claimed.
Not compiled - MetaEditor compile pending.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:09:58 -04:00
|
|
|
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);
|
2026-08-16 15:12:54 -04:00
|
|
|
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;
|
|
|
|
|
}
|
feat(indicators): run the built-in iMA and MetaTrader's ZigZag; add a classic-vote shift
MA: CustomIndicators\ADMovingAverage is replaced by the built-in iMA (CiMA) on
both consumers - the classic vote and the NN MA input feature. This drops the
five advanced types ALMA/DEMA/ZLEMA/T3/Kalman, which have no iMA equivalent;
MA_TYPE_PRESETS is now ENUM_MA_METHOD's own codes and the tuner searches all
four. It also removes a documented failure mode: a custom indicator's depth is
bounded by TERMINAL_MAXBARS, and m_MA was the one whose feature block REJECTS
the bar on a short read - the "feature 25 fails on every bar" incident of
2026-08-17. A built-in is served at any depth.
MIGRATION. SMA moves from code 5 to 0, so persisted type codes change meaning.
SanitizeMaType() is the single validity rule; TunedPeriods records now carry a
version field and a v1 record remaps 5..8 -> 0..3, falling back to SMA for a
stored advanced type (unrecoverable - old 0..4 are indistinguishable from valid
new codes). Existing .nnw files re-key on their own, because MA_Type is hashed
into the topology fingerprint, so models retrain rather than silently running
on different MA values. EXPECT A FULL RETRAIN.
ZigZag: ADZigZag was a byte-identical rename of MetaQuotes' Examples\ZigZag -
verified by normalising identifiers and stripping comments, 233 significant
lines each with only renamed symbols differing. It now loads the stock one, so
nothing is bundled and MetaQuotes' fixes arrive without a rebuild here. Both
#resource entries are gone.
Classic_Shift: a new input, the BAR the four classic votes evaluate on (0 =
forming, 1 = last closed, default 1). One implementation on CExpertSignalCustom,
inherited by all four rather than repeated per module. Defaults to a sentinel
meaning "unset", so the AI signals and the aggregate keep the stock every_tick
rule and their feature/label alignment is untouched. The META corpus sweep still
takes precedence. CExpertBase::StartIndex turns out to be virtual, so this is a
real override, not the name-hiding the old comment claimed.
Not compiled - MetaEditor compile pending.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:09:58 -04:00
|
|
|
FileWriteString(h, StringFormat("%d;%d;%d;%d;%d;%d;%d;%d;%d;%s\n",
|
2026-08-16 15:12:54 -04:00
|
|
|
maPeriod, maType, rsiPeriod, macdFast, macdSlow, macdSignal,
|
feat(indicators): run the built-in iMA and MetaTrader's ZigZag; add a classic-vote shift
MA: CustomIndicators\ADMovingAverage is replaced by the built-in iMA (CiMA) on
both consumers - the classic vote and the NN MA input feature. This drops the
five advanced types ALMA/DEMA/ZLEMA/T3/Kalman, which have no iMA equivalent;
MA_TYPE_PRESETS is now ENUM_MA_METHOD's own codes and the tuner searches all
four. It also removes a documented failure mode: a custom indicator's depth is
bounded by TERMINAL_MAXBARS, and m_MA was the one whose feature block REJECTS
the bar on a short read - the "feature 25 fails on every bar" incident of
2026-08-17. A built-in is served at any depth.
MIGRATION. SMA moves from code 5 to 0, so persisted type codes change meaning.
SanitizeMaType() is the single validity rule; TunedPeriods records now carry a
version field and a v1 record remaps 5..8 -> 0..3, falling back to SMA for a
stored advanced type (unrecoverable - old 0..4 are indistinguishable from valid
new codes). Existing .nnw files re-key on their own, because MA_Type is hashed
into the topology fingerprint, so models retrain rather than silently running
on different MA values. EXPECT A FULL RETRAIN.
ZigZag: ADZigZag was a byte-identical rename of MetaQuotes' Examples\ZigZag -
verified by normalising identifiers and stripping comments, 233 significant
lines each with only renamed symbols differing. It now loads the stock one, so
nothing is bundled and MetaQuotes' fixes arrive without a rebuild here. Both
#resource entries are gone.
Classic_Shift: a new input, the BAR the four classic votes evaluate on (0 =
forming, 1 = last closed, default 1). One implementation on CExpertSignalCustom,
inherited by all four rather than repeated per module. Defaults to a sentinel
meaning "unset", so the AI signals and the aggregate keep the stock every_tick
rule and their feature/label alignment is untouched. The META corpus sweep still
takes precedence. CExpertBase::StartIndex turns out to be virtual, so this is a
real override, not the name-hiding the old comment claimed.
Not compiled - MetaEditor compile pending.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:09:58 -04:00
|
|
|
ichiTenkan, ichiKijun, ichiSenkou, TUNED_PERIODS_VERSION));
|
2026-08-16 15:12:54 -04:00
|
|
|
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
|