Warrior_EA/Variables/Inputs.mqh
AnimateDread e372ce60a9 fix(vote): "0 fired" on USDJPY meant the threshold is above the highest vote the ensemble can cast
USDJPY has taken no trades in 66 eras and its highest vote ever seen is 13
against a 25% threshold. Not a bug and not undertrained models - arithmetic.

Direction() divides the summed contributions by the CAPABLE weight, so a
unanimous vote returns the capability-weighted mean of the tier weights, which
is roughly the pooled holdout win rate. USDJPY's members pool at 15.6-19.4%
(its label base rate is 14.0% against SP500's 25.4%, because its derived
geometry resolves far fewer bars directionally: Buy 10.3% Sell 11.2% Neutral
78.6%). So the ensemble's CEILING is ~19 and the threshold is 25. Coverage can
never leave 0, and no amount of training moves it, because the ceiling IS the
win rate.

The report now computes that ceiling - every member voting at its best tier -
and says so when the threshold sits above it, instead of printing "0 fired at
vote>=25%" which reads as "the models are unsure".

Same class as the excursion head's disjoint gate (ee4d459) and the reason
ReportDetectability exists: a configuration that cannot reach its own bar has
to say that, not report a number that looks like evidence.

Also: VerboseMode and Run_Alglib_Baselines back to false. The per-era cadence
was for reading the horizon break-even and the excursion sigmas; both are
settled, and TrainLogDue still prints them every 25 eras. The baselines cost a
45 s single-threaded freeze at every attach and their forest row turned out to
be one deterministic observation that does not survive overlap deflation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 08:16:11 -04:00

334 lines
24 KiB
MQL5

//+------------------------------------------------------------------+
//| Inputs.mqh |
//| AnimateDread |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "AnimateDread"
#property link "https://www.mql5.com"
#include "..\Enumerations\InputEnums.mqh"
//--- Each `input string *_Settings` is a GUI-only section divider: MetaTrader renders an input string
//--- whose value equals its comment as a header. Never read by code.
//--- NN Optimizer / Performance must stay LAST - AI\Network.mqh's Adam/Sgd inputs render after it.
//==================================================================================================
// GENERAL
//==================================================================================================
input string Expert_Settings = "General"; // General
input ulong Expert_MagicNumber = 2024; // Magic number (unique EA id)
input bool Expert_EveryTick = false; // Calculate on every tick
//--- Also throttles the per-era training journal: false prints each diagnostic on the first eras and
//--- then every TRAIN_LOG_EVERY_ERAS-th (state CHANGES always print). true is the full firehose.
input bool VerboseMode = false; // Verbose journal + detailed panel (full per-era logs)
//--- Dev diagnostics to the Experts journal (plateau stage, deploy gate, selection internals).
const bool DebuggingMode = false;
//--- Pins the dense-taper depth instead of deriving it (ComputeHiddenLayerCount). 0 = derived, the only
//--- value that should ship. Compile-time, so two forced depths cannot run from one .ex5.
const int ForceHiddenLayers = 0;
//==================================================================================================
// MONEY MANAGEMENT
//==================================================================================================
input string MM_Settings = "Money Management"; // Money Management
input MONEY_MANAGEMENT_STRATEGY MM_STRATEGY = FIXED_RISK; // MM strategy
input MONEY_RISK_PERCENT_PRESET Money_Risk_Percent = RISK_PCT_1; // Risk % of balance per trade
input double Money_FixLot_Lots = 0.01; // Fixed lot size [0.01-10]
//==================================================================================================
// TRADE MANAGEMENT (entry / stop / target / trailing / exit)
//==================================================================================================
input string Entry_Settings = "Trade Management"; // Trade Management
//--- INTELLIGENT measures the drift from the label cache's own Buy/Sell shares and trades only the
//--- side(s) it supports. Fails open to BOTH unless the gap clears 2 SEs AND the weaker side is below
//--- break-even. Trade policy, not label definition - it is in no fingerprint or DB key.
input TRADING_DIRECTION tradingdirection = DIRECTION_INTELLIGENT; // Trade direction
//--- Entry is pinned to MARKET: a pending entry cannot be honestly simulated by this codebase's fill
//--- model, which is what manufactured the retracted "retail fade" result.
const ENTRY_MULTIPLIER Entry_Multiplier = MARKET; // Entry type/offset (fixed - see above)
//--- STARTING geometry only - ReportBarrierGeometryScan may replace the pair at era 0 on a fresh
//--- model and pins it in the .cfg thereafter.
const STOP_LOSS_MODE SL_Mode = SL_ATR_x2; // Stop-loss mode (measured - see above)
const TAKE_PROFIT_MODE TP_Mode = TP_ATR_x6; // Take-profit mode (measured - see above)
input TRAILING_STRATEGY TrailingStrategy = TRAILING_STRATEGY_NONE; // Trailing stop
input BARS_EXPIRATION Signal_Expiration = BARS_X3; // Pending order expiry (bars)
input CONFIDENCE_SOURCE Confidence_Source = CONF_AI; // AI confidence source (SL/TP/trail/exit/MM)
//--- CExpertSignal::m_threshold_open / m_threshold_close, on the library's own 0-100 scale: the
//--- vote is a WEIGHTED MEAN of the firing patterns' weights, which cannot exceed 100.
input PERCENTAGE_PRESETS Signal_ThresholdOpen = PCT_25; // Signal threshold to open
//--- Disabled turns the vote exit off by arithmetic (the mean cannot reach 101); any percentage arms it.
//--- Classic route only - an AI-certified position holds to the barrier its deploy gate measured.
input SIGNAL_CLOSE_PRESETS Signal_ThresholdClose = CLOSE_DISABLED; // Signal threshold to close
//--- OFF = the filtered view, one arrow per position the EA would open (vote + ranking + threshold
//--- applied). ON = every model's raw opinion, per model - the diagnostic view that shows a collapsed
//--- member the filtered view cannot, because a collapsed member simply stops appearing in it.
input bool DrawUnfilteredSignals = false; // Draw raw per-model signals (bypass vote/ranking/threshold)
//==================================================================================================
// CLASSIC SIGNALS (rule-based votes - trade alongside or instead of the neural network)
//==================================================================================================
input string Classic_Settings = "Classic Signals"; // Classic Signals
input bool EnableMA = false; // MA classic vote
input bool EnableRSI = false; // RSI classic vote
input bool EnableMACD = false; // MACD classic vote
input bool EnableIchimoku = false; // Ichimoku classic vote
//--- Which bar the classic votes read: 0 = the forming bar, 1 = the last closed one. Classic votes only;
//--- the AI signals follow Expert_EveryTick, because their feature windows are aligned to it.
input int Classic_Shift = 1; // Classic vote bar (0=forming, 1=last closed)
//--- SEEDS ONLY. All indicator parameters are tuner-owned: the auto-tuner searches from these under a
//--- family-wise gate and persists winners in TunedPeriods_{SYM}_{TF}.cfg, which both the classic votes
//--- and the AI features read - so the two can never run different periods for the same concept.
//--- Hand-setting means editing these constants, which deliberately bypasses that gate.
const MA_PERIOD_PRESETS PeriodMA = MA_PERIOD_50; // MA period seed
const MA_TYPE_PRESETS MA_Type = MA_TYPE_SMA; // MA type seed
const RSI_PERIOD_PRESETS PeriodRSI = RSI_PERIOD_14; // RSI period seed
const MACD_FAST_PRESETS MACD_PeriodFast = MACD_FAST_12;
const MACD_SLOW_PRESETS MACD_PeriodSlow = MACD_SLOW_26;
const MACD_SIGNAL_PRESETS MACD_PeriodSignal = MACD_SIGNAL_9;
const ICHIMOKU_TENKAN_PRESETS Ichimoku_PeriodTenkan = ICHI_TENKAN_9;
const ICHIMOKU_KIJUN_PRESETS Ichimoku_PeriodKijun = ICHI_KIJUN_26;
const ICHIMOKU_SENKOU_PRESETS Ichimoku_PeriodSenkou = ICHI_SENKOU_52;
//==================================================================================================
// NEURAL NETWORK (training)
//==================================================================================================
input string NNetworks_Settings = "Neural Networks"; // Neural Networks
//--- Two or more enabled = an ensemble (|ENS1 fingerprint token + joint vote-level deploy gate);
//--- exactly one = solo, same fingerprint and files as the old preset; none = classic only. Every
//--- enabled NN trains a net per chart, so prefer fewer members on sub-daily timeframes.
#ifdef WARRIOR_MARKET_BUILD
input bool Use_MLP = false; // NN vote: MLP (dense)
input bool Use_CONV = false; // NN vote: CONV (convolutional)
input bool Use_LSTM = false; // NN vote: LSTM (recurrent)
input bool Use_CONVLSTM = false; // NN vote: CONVLSTM (conv front-end + LSTM)
#else
input bool Use_MLP = true; // NN vote: MLP (dense)
input bool Use_CONV = true; // NN vote: CONV (convolutional)
input bool Use_LSTM = true; // NN vote: LSTM (recurrent)
input bool Use_CONVLSTM = true; // NN vote: CONVLSTM (conv front-end + LSTM)
#endif
//--- Runs beside the direction NNs and VETOES vote-cleared ENTRIES whose predicted win probability is
//--- below cost-adjusted break-even. Never votes a direction, never blocks an exit, fails open loudly.
//--- Needs candidates: enable a classic vote or supply a journaled signal DB or the gate never arms.
input bool Use_MetaLabeling = false; // Meta-labeling gate on NN vote entries
//--- One-shot measurement: an Alglib forest, MLP and OLS fit on the net's OWN windows, labels, split and
//--- gate arithmetic. Answers whether a flat result is the architecture or the matrix. Nothing trades on
//--- it and no model is saved. See Expert\AIBase\Baselines.mqh.
input bool Run_Alglib_Baselines = false; // Diagnostic: forest + linear on the NN's own matrix
//+------------------------------------------------------------------+
//| Roster string for logs and the journal's filterID column. Lives |
//| here because TradeJournalManager.mqh is included before |
//| Variables.mqh's globals and needs it too. |
//+------------------------------------------------------------------+
string EnabledNNSummary()
{
string s = "";
if(Use_MLP)
s += (StringLen(s) > 0 ? "+MLP" : "MLP");
if(Use_CONV)
s += (StringLen(s) > 0 ? "+CONV" : "CONV");
if(Use_LSTM)
s += (StringLen(s) > 0 ? "+LSTM" : "LSTM");
if(Use_CONVLSTM)
s += (StringLen(s) > 0 ? "+CONVLSTM" : "CONVLSTM");
if(StringLen(s) <= 0)
s = "Classic";
if(Use_MetaLabeling)
s += "+metaGate";
return s;
}
//--- The training target is unconditionally the triple barrier. TARGET_FRACTAL was adjudicated dead
//--- 2026-08-16 (5,700 model-eras flat at -2pp, best-of-243 p=0.17) and its input was withdrawn
//--- rather than re-defaulted.
input ENUM_OPTIMIZATION TrainingOptimizer = ADAM; // Weight optimizer
//--- The target is an EVENT ("does a trade opened here reach target before stop"), so the head is a
//--- 3-class softmax. The regression path stays implemented but is no longer selectable.
const OUTPUT_NEURONS_COUNT OutputNeuronsCount = OUTPUT_CLASSIFICATION;
//--- First-layer width, LSTM hidden size, conv filter count, taper depth and reduction are all
//--- DERIVED from the post-selection input width and the in-sample bar count - see
//--- ComputeFirstLayerWidth(), ComputeConvFilterCount(), ComputeLstmHiddenSize().
const bool EnableBatchNorm = true; // AI: batch normalization
//--- EMA window for the running mean/variance, in training SAMPLES (there is no mini-batch to average
//--- over). <=1 silently disables the layer, which is the only other meaningful setting.
const int BatchNormWindow = 1000; // AI: batch-norm window (samples)
//--- Training starts at the earliest available bar (floored by MinTrainYear); the honest generalisation
//--- read comes from this holdout, not from withholding history.
input OOS_SPLIT_PRESET OOSSplit = OOS_30; // Out-of-sample holdout
//--- There is no "target accuracy" input: training runs until it stops improving and deploys its
//--- own best checkpoint (see the PLATEAU_* ladder).
const PERCENTAGE_PRESETS MinRecall = PCT_40;
//==================================================================================================
// CLASS IMBALANCE - ONE MECHANISM, ONE KNOB
//==================================================================================================
//--- LOGIT-ADJUSTED LOSS (Menon et al. 2021): add tau*log(prior_c) to each class logit inside the
//--- TRAINING gradient only, so the raw argmax at inference is already balanced-error-optimal. 0 =
//--- off.
input LOGIT_PRIOR_STRENGTH_PRESETS LogitAdjustTau = LOGIT_PRIOR_100; // AI: class-imbalance correction (tau, 0=off)
//--- Freeze the measured class priors after the first measurement. Letting them track is correct since
//--- the barrier relabel; freezing is a diagnostic for a genuinely shifting distribution.
const bool FreezePriorCalibration = false;
//--- Repainting embargo for the swing-context FEATURES (not the labels - that lookahead is the measured
//--- barrier horizon). ZigZag revises its recent legs, so a raw read would be straight lookahead.
const SWING_CONFIRMATION_PRESET SwingConfirmationBars = SC_100;
//--- Keep adapting a deployed model on a LIVE chart to newly-RESOLVED bars. The blend FREEZES if a
//--- rolling-accuracy guardrail decays, so drift cannot reach the account. No effect in the tester.
const bool EnableOnlineLearning = true;
//--- Non-max suppression window for arrows and emissions, display only - the raw per-bar metrics are
//--- never declustered. 10 bars is about a third of an H1 session.
const int SignalClusterWindow = 10;
//--- A second small net predicting how FAR price travels within the horizon - never which way. Stage 1
//--- is a MEASUREMENT: it prints a Brier skill score and places no orders. Not in the fingerprint.
const bool UseExcursionHead = true;
//--- Runaway backstop, not a training control - the plateau ladder decides when a run ends.
const MAX_ERAS_PRESET MaxErasPerRun = ME_10000;
//==================================================================================================
// AI INPUT FEATURES (the data the neural network sees each bar)
//==================================================================================================
input string AISignals = "AI Input Features"; // AI Input Features
//--- Bars per input sequence is DERIVED (DeriveHistoryBars) and pinned in the .cfg. The ATR feature
//--- period is deliberately decoupled and fixed: the indicator is created before the .cfg is adopted,
//--- so deriving it would let init ordering change the unit the pinned SL/TP multiples are expressed in.
#define ATR_FEATURE_PERIOD 20
input ENUM_APPLIED_VOLUME VolumeData = VOLUME_TICK; // Volume data type (tick / real)
input bool EnableVolume = true; // Feature: volume
input bool EnableTime = true; // Feature: time
input bool EnableATR = true; // Feature: volatility (ATR)
//--- Independent of the classic votes above - a feature can be fed without voting, and vice versa.
input bool EnableMAFeature = true; // Feature: Moving Average
input bool EnableRSIFeature = false; // Feature: RSI
//--- Widths are per BAR, so each is multiplied by the sequence length: Ichimoku's 8 is 160 extra inputs
//--- at 20 bars. Enable deliberately.
input bool EnableMACDFeature = false; // Feature: MACD
input bool EnableIchimokuFeature = false; // Feature: Ichimoku
input bool EnableSwingContext = true; // Feature: ZigZag swing context
//--- Order-flow / Wyckoff, 28-36 features per bar. Opt-in per chart since the alt-data campaign made
//--- externally-measured features the default diet.
input bool EnableADCumulativeDelta = false; // Feature: Cumulative Delta
input bool EnableADShorteningOfThrust = false; // Feature: Shortening of Thrust
input bool EnableADWyckoffEventStream = false; // Feature: Wyckoff Events
input bool EnableADWyckoffFailedStructure = false; // Feature: Wyckoff Failed Structure
input bool EnableADWyckoffSignificantBarInversion = false; // Feature: Wyckoff Bar Inversion
//==================================================================================================
// AD / WYCKOFF INDICATOR PARAMETERS
//==================================================================================================
//--- Tuner seeds, one per CONCEPT rather than per indicator (volClimax/volHigh/rangeClimax/... were
//--- restated verbatim across four indicators). The auto-tuner is the operator path to these values;
//--- editing a _DEF is a deliberate speed bump, because hand-set values bypass its family-wise gate.
#define WYK_VOL_CLIMAX_DEF 2.5
#define WYK_VOL_HIGH_DEF 1.5
#define WYK_RANGE_CLIMAX_DEF 1.8
#define WYK_RANGE_SIGNIF_DEF 1.2
#define WYK_ST_VOL_RATIO_DEF 0.6
#define WYK_ATR_MULT_DEF 0.5
#define ADCD_LOOKBACK_DEF 50
#define SOT_THRUST_LOOKBACK_DEF 30
#define SOT_MIN_IMPULSES_DEF 3
#define SOT_THRESHOLD_DEF 0.30
#define WES_LOOKBACK_DEF 50
#define WES_ZIGZAG_DEF 3
#define WES_TOUCH_ATR_DEF 0.5
#define WES_AR_MIN_ATR_DEF 1.0
#define WES_MAX_RANGE_BARS_DEF 200
#define WFS_LOOKBACK_DEF 50
#define WFS_ZIGZAG_STRENGTH_DEF 3
#define WSBI_LOOKBACK_DEF 50
//--- Aliases keeping every consumer (CADIndicatorTuner seeds, ConfigFingerprint's ADP token) untouched.
#define Wyk_VolClimaxMult WYK_VOL_CLIMAX_DEF
#define Wyk_VolHighMult WYK_VOL_HIGH_DEF
#define Wyk_RangeClimaxMult WYK_RANGE_CLIMAX_DEF
#define Wyk_RangeSignificantMult WYK_RANGE_SIGNIF_DEF
#define Wyk_ShortTermVolRatio WYK_ST_VOL_RATIO_DEF
#define Wyk_AtrMult WYK_ATR_MULT_DEF
#define ADCD_Lookback ADCD_LOOKBACK_DEF
#define SOT_ThrustLookback SOT_THRUST_LOOKBACK_DEF
#define SOT_MinImpulses SOT_MIN_IMPULSES_DEF
#define SOT_Threshold SOT_THRESHOLD_DEF
#define WES_Lookback WES_LOOKBACK_DEF
#define WES_ZigZag WES_ZIGZAG_DEF
#define WES_TouchATR WES_TOUCH_ATR_DEF
#define WES_ARMinATR WES_AR_MIN_ATR_DEF
#define WES_MaxRangeBars WES_MAX_RANGE_BARS_DEF
#define WFS_Lookback WFS_LOOKBACK_DEF
#define WFS_ZigZagStrength WFS_ZIGZAG_STRENGTH_DEF
#define WSBI_Lookback WSBI_LOOKBACK_DEF
//--- Proximity/impact only, never actual-vs-forecast, which is not knowable ahead of the release.
input bool EnableNews = false; // Feature: news proximity
input NF_LOOKBACK_PRESETS NewsFeatureWindowMinutes = M60; // News feature window
//--- Currency-strength panel built from the FX pairs in Market Watch. Needs >= 2 usable pairs; degrades
//--- to a neutral 0-fill with one logged line rather than blocking training.
input bool EnableCrossAsset = true; // Feature: cross-asset currency strength
//--- The only microstructure channel that is both FX-available and genuinely historical in the tester.
//--- Encodes a volatility REGIME; unsigned, like volume, so it can never pick a side.
input bool EnableSpreadFeature = true; // Feature: spread / volatility regime
//--- Gates CONSUMPTION only. With no file for this symbol the block contributes 0 features and the
//--- topology is unchanged, so it is safe ON everywhere. Turning it OFF on a model trained WITH alt
//--- features shrinks the input width and correctly starts a fresh model.
input bool EnableAltData = true; // Feature: alternative data (COT / VIX / macro)
//--- Keys travel as input defaults so wiping Common\Files\Warrior_EA cannot silently kill a source.
//--- A keys.txt in the AltData folder is consulted only if an input is blanked. COT needs no key.
input string FredApiKey = "9640c07ff6574c1c23a17393b735fd36"; // FRED API key (VIX/USD features)
input string EiaApiKey = "oeSZu7EaZxG5Icjm6q78yUIXaH2EKGhIwVsdTj76"; // EIA API key (petroleum features)
//--- Searches the per-bar parameters of every ENABLED feature under a family-wise gate; the trial
//--- budget is derived, not configured (ComputeTuneTrialBudget).
input bool AutoTuneIndicators = true; // Auto-tune indicator params (gated, era 0)
//==================================================================================================
// FILTERS
//==================================================================================================
input string SF_Settings = "Session Filter"; // Session Filter
input bool EnableSessionFilter = false; // Signal: Session filter
//--- All three ON spans 00:00-22:00 GMT. The filter is evaluated once per BAR, so on D1 there is exactly
//--- one evaluation and a narrow default can starve the EA of entries entirely.
input bool SF_trade_LondonSession = true; // Trade London session
input bool SF_trade_TokyoSession = true; // Trade Tokyo session
input bool SF_trade_NewYorkSession = true; // Trade New York session
//--- Its own group because CExpertCustom::OnTick() evaluates this schedule unconditionally - it fires
//--- whether EnableSessionFilter is on or off. Set Close-all day = Disabled to switch it off.
input string CA_Settings = "Scheduled Close-All"; // Scheduled Close-All
input CLOSE_DAY_OF_WEEK targetDayOfWeek = CLOSE_FRIDAY; // Close-all day
//--- CH_MARKET_CLOSE resolves per day from the symbol's own session table and backs off by the
//--- minute setting, so it is right on every symbol and both sides of DST with no number to
//--- maintain.
input CLOSE_HOUR_OF_DAY targetHour = CH_MARKET_CLOSE; // Close-all hour
input CLOSE_MINUTE_OF_HOUR targetMinutes = CM_5; // Close-all minute
input string NF_Settings = "News Filter"; // News Filter
input bool EnableNewsFilter = true; // Signal: News filter
input NF_LOOKBACK_PRESETS NF_LookMinutes = M60; // News avoid window (min)
input NF_IMPACT_PRESETS NF_MinImpact = HOLIDAYS; // Min news impact to avoid
input string RiskGuard_Settings = "Risk Guard"; // Risk Guard
input bool EnableRiskGuard = true; // Signal: Risk Guard
//--- Free entry rather than a preset ladder, because prop limits are not always integers. Enter the
//--- limits from YOUR account agreement, slightly tighter if you want margin for slippage past a stop.
//--- 0 disables a rule. Enforced at quote frequency by Variables\RiskBudget.mqh, not once per bar.
input double MaxDailyLossPct = 4.0; // Daily loss limit % (0 = off)
input double MaxDrawdownPct = 8.0; // Max total drawdown % (0 = off)
//--- TRUE: measured down from the highest equity ever reached. FALSE: from the equity first seen. Use
//--- whichever your programme uses - a trailing rule on a static challenge halts far too early.
input bool MaxDrawdownIsTrailing = true; // Max DD trails the equity peak
//--- Broker-server hour, NOT local time. A misaligned window hands the allowance back early or late.
input int RiskDayResetHour = 0; // Risk day reset hour (broker time, 0-23)
//--- Share of the allowance genuinely LEFT after every open position's remaining loss-to-stop. Without
//--- it a trade at 3.2% into a 4% day still sized for a full risk unit and a routine stop-out breached.
input double RiskPerTradeOfBudget = 50.0; // Max % of remaining budget per trade
//--- Declining new entries cannot stop an ALREADY-OPEN position running through the limit, which is how
//--- a hard daily rule is actually breached. OFF means the limits above are advisory, not enforced.
input bool RiskGuardFlatten = false; // Close own positions on breach
//--- EXPECTANCY STOP. The limits above bound how FAST the account loses, never WHETHER. 0 = off.
//--- The halt is LATCHED and survives a restart; clearing it means deleting the risk state file.
input int ExpectancyMinTrades = 40; // Halt if losing: min closed trades first (0 = off)
input double ExpectancySigma = 2.0; // ...and mean must be this many std errors below zero
//==================================================================================================
// TRADE JOURNAL / PATTERN RANKING
//==================================================================================================
input string Journal_Settings = "Trade Journal / Ranking"; // Trade Journal / Ranking
//--- Scales each signal's vote by its historical win rate, records every trade, and powers the Export
//--- Trade Journal Report button.
input bool UseDatabaseRanking = true; // Weight filters by DB win-rate
//--- Oldest row pruned past the cap. A META corpus build needs it high so a long backtest is not pruned
//--- away; a high cap costs nothing until the rows exist.
input int DB_MaxRowsPerTable = 1000000; // Max rows kept per pattern table
//--- Writes every resolved candidate's feature window + descriptor + label to
//--- Common\Files\Warrior_EA\MetaExport\<sym>_<period>.f32 once per attach, for OFFLINE pooled
//--- training across symbols. Costs one pass-1-sized sweep at attach.
#ifdef WARRIOR_MARKET_BUILD
input bool Meta_ExportDataset = false; // META: export training dataset at attach
#else
input bool Meta_ExportDataset = true; // META: export training dataset at attach
#endif
//--- Header only - AI\Network.mqh's Adam*/Sgd* inputs render immediately after this divider.
input string NNPerf_Settings = "NN Optimizer / Performance"; // NN Optimizer / Performance
//--- Guarded, so the explicit include in Warrior_EA.mq5 stays harmless: every unit that sees the seed
//--- constants above also sees the g_Tuned* globals that supersede them.
#include "TunedPeriods.mqh"