Introduce m_useSwingContext flag and FindConfirmedZigZagPivot method to compute normalized swing direction/magnitude/age features from the existing ADZigZag indicator. Only pivots that are at least m_swingConfirmationBars old are trusted, preventing lookahead bias. The SWING_SCAN_CAP_BARS macro limits backward scan depth. Default is off.
Remove overly verbose explanations in Network.mqh comments and InputEnums.mqh enum values. Shorten descriptions to improve readability without losing essential information.
Class-balance correction is now performed entirely via data-level oversampling (duplicating minority-class bars) instead of using a per-occurrence loss-weight multiplier combined with oversampling. The loss-weight mechanism proved ineffective due to Adam's near-invariance to constant gradient rescaling (Kingma & Ba 2015). The CLASS_SAMPLE_WEIGHT_PRESET enum is retained for a possible future supplemental loss weight, but m_maxClassSampleWeight currently has no effect. The MAX_OVERSAMPLE_REPLICAS constant is now the sole bound on correction strength.
Updated comments in InputEnums.mqh and ExpertSignalAIBase.mqh to reflect this change.
Optimize() scaled lot size off account trade-history streaks with no Magic-number
filter (picked up other EAs'/manual trades) and an unconfigurable m_factor stuck at
1.0 (Factor() was never wired from an input), so a 3-trade streak could triple lot
size or send it negative. It was also entirely disconnected from what the AI model
actually knows about the current setup.
Replaced both AdjustRiskAmount()'s linear confidence-only scale and Optimize()'s
streak multiplier with one edge-based model: p from the empirically calibrated
AI/DB confidence magnitude, b from the trade's real reward:risk ratio (newly
bridged from OpenParams() via g_TradeRewardRiskRatio), quarter-Kelly applied and
clamped so risk% can only ever scale down from its configured ceiling, never above it.
Audit turned up a real gap for a prop-firm-portfolio-manager use
case: nothing in this codebase watched for account-level daily-loss
or max-drawdown breaches - the single most common way a prop-firm
evaluation actually gets failed.
New Signals/SignalRiskGuard.mqh (CSignalRiskGuard), wired into the
exact same filter-composition chain as SignalNewsFilter/
SignalSessionFilter (CreateSignalWithRetry/AddFilterToSignal, no new
architecture). Vetoes new entries only (never closes existing
positions - a materially bigger behavior change, left to the
trader/EA's own SL/TP handling) once either MaxDailyLossPct or
MaxDrawdownPct (new RISK_LIMIT_PCT_PRESET inputs, both default
disabled) is breached. Peak equity and the current broker day's
starting balance persist to a small local per-symbol-per-magic state
file - peak equity in particular must survive a restart to mean
anything, otherwise a restart would silently reset drawdown tracking.
New RISK_LIMIT_PCT_PRESET enum (2/3/4/5/8/10/15/20%) rather than
reusing PERCENTAGE_PRESETS, which steps by 10 starting at 10 - too
coarse for prop-firm-style limits (commonly single-digit daily loss,
~8-10% max drawdown). Compiled clean (MetaEditor, 0 errors/0
warnings).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Price, time, volume, and volatility were already trained-model input
features; the real economic calendar (already used for the live
NewsFilter veto) is now an optional one too, reusing
System/NewsRelevance.mqh's symbol-relevance logic from the prior fix.
New EnableNews/NewsFeatureWindowMinutes inputs gate two features per
bar: minutes-since and minutes-until the nearest symbol-relevant
calendar event, impact-weighted. Deliberately limited to proximity +
impact, not actual-vs-forecast deviation - release schedules are
public knowledge ahead of time (not lookahead bias to use for a
historical training bar), but a release's actual outcome is not.
Wired identically to the existing EnableVolume/EnableTime/EnableATR
toggles: InitIndicators() accounts for the +2 neuron count,
BufferTempDataCompute() appends the two feature values, PAI/CONV/LSTM
all wired in Warrior_EA.mq5. Compiled clean (MetaEditor, 0 errors/0
warnings).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Variables/Inputs.mqh: drop the dead commented-out HybridSignals input
line; add a one-line note above the section-header input strings
clarifying they're intentional MetaTrader GUI dividers (consumed by
the terminal, not any MQL5 statement) so a future audit doesn't
re-flag them as unwired.
- Signals/SignalSessionFilter.mqh: replace the never-filled-in MQL5
Wizard template header (ProjectName/CompanyName placeholders) with
this codebase's real header, matching every other Signals/*.mqh file.
- Signals/SignalNewsFilter.mqh: remove the stale NEWS_IMPACT template
macro - it was only ever used as the constructor default, immediately
overridden by the real NF_MinImpact input at wiring time.
- Expert/ExpertSignalAIBase.mqh: guard the SERIES_LASTBAR_DATE read in
ScheduleTrainingIfNeeded() so a failed lookup (0) can't silently be
read as "no new bar pending" and stall training/signal refresh.
Compiled clean (MetaEditor, 0 errors/0 warnings) after each change.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
trainingMode, ClassSampleWeight, FocalLossGamma, and SwingConfirmationBars'
inline display comments measured 214-306 chars combined with their
identifier - over MQL5's documented 255-char identifier=value ceiling for
the terminal/testing-agent exchange protocol, risking silent cropping in
the Inputs dialog. Trimmed to a max of 189 chars; full rationale for each
stays in the existing block comments above each input.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace hardcoded lr and momentum with new input variables for Adam and
SGD+momentum. Add OpenCL kernel LSTM_UpdateWeightsMomentum alongside the
existing Adam kernel. Update comments and revert beta1 to book default 0.9.
- Lowered Adam momentum parameter b1 from 0.9 to 0.8, shortening the effective memory window (~5 steps) to reduce multi-era bias streaks observed in training runs.
- Added FOCAL_GAMMA_PRESET enum and corresponding member variable m_focalGamma to apply focal loss modulation (Lin et al. 2017) on top of class-balance weighting, targeting the same streak issue by downweighting already-confident examples.
- Updated comments to document the rationale and experimental nature of both changes.
Replace the hardcoded `MAX_CLASS_SAMPLE_WEIGHT` (3.0) with a tunable member variable `m_maxClassSampleWeight`, controlled by the new `CLASS_SAMPLE_WEIGHT_PRESET` input enum. This allows adjusting the ceiling on rare-class sample weights to prevent the previously observed anti-correlated Buy/Sell recall whipsaw (where a high multiplier caused one era's gradients to overwrite another class's separability). Default is CSW_15 (1.5x), which is gentler than the old 3.0x; lower values down to 1.0x disable rebalancing to train on raw label distribution, while higher values (up to 3.0x) converge faster but risk instability. This tuning can now be done without recompiling.
- Removed TEST_HOLDOUT_PRESET enum and its associated member variables (m_testHoldoutPct, dTestForecast, m_testSamples) from ExpertSignalAIBase to simplify code and eliminate unused test slice logic.
- Added m_lastNonNeutralSignal member to track the last non-neutral signal during live inference, preventing LongCondition()/ShortCondition() from opening a second consecutive same-direction trade (which would be a false fire based on training patterns where valid reversals always alternate direction).
- This live-only mechanism does not affect historical training or backpropagation.
- Ensure `tick_volume` array is set as series in ADShorteningOfThrust.mq5 to prevent future-data leak in volume calculations.
- Ensure `open` array is set as series in ADWyckoffFailedStructure.mq5 to prevent future-data leak in structure detection.
- Add missing PReLU gradient scaling (multiply by 0.01 for negative outputs) in CPU_CalcHiddenGradient and DirectML shader to match expected derivative behavior across all backends.
- Extend `CNet::getResults` and `CLayer::Load` to support `defNeuronConvOCL`, `defNeuronPoolOCL`, and `defNeuronLSTMOCL` types (previously only `defNeuronBaseOCL` was handled), preventing potential crashes or incorrect outputs with those neuron types.
- Increase `ind_Periods` default from `PERIOD_5` to `PERIOD_20` because `PERIOD_5` was smaller than ADZigZag's `InpDepth=12`, making it structurally impossible for the model to see enough bars to recognize swing pivots, likely causing the erratic Buy/Sell OOS recall observed during training runs.
- Added MAX_CLASS_SAMPLE_WEIGHT (3.0) to cap the sample weight multiplier, preventing anti-correlated Buy/Sell recall whipsaw observed when per-era ratio overwrites previous separability.
- Added MIN_OOS_CLASS_SAMPLES_FOR_GATE (10) to require a minimum number of true OOS samples before trusting class recall, avoiding degenerate false-convergence cases.
- Increased TRAIN_TIME_BUDGET_MS from 80 to 500 to improve throughput under MT5's custom event dispatch model (which determines actual pacing); trades UI responsiveness (~500ms lag) for roughly 6× more bars processed per event.
- Replace the hand-rolled fractal/deviation-%/ATR-trend-context ZigZag
approximation with the actual MQL5 ZigZag indicator (rebranded as
CustomIndicators/ADZigZag.mq5, logic untouched) as the training label
source; bump the settle/confirmation window from 20 to 100 bars so a
proper leg can form before being trusted, and drop the now-dead
ZigZagDeviationPct/MinTrendATRMultiple/TrendContextBars inputs.
- Rebrand the stock Volumes indicator the same way (ADVolume.mq5).
- Fix HYBRID mode (AIType=HYBRID) oversubscribing the CPU fallback tier:
every concurrent CNet instance was independently sizing its worker
pool off the same global TargetCPULoad input. g_netPeerCount/
PeerNetworkCount() now split it across however many CNet instances
(live+shadow x active signals) are actually sharing the CPU.
- Fix NEURONS_REDUCTION_FACTOR's confusing retention-vs-reduction
semantics so RF_70 means an actual 70% reduction; default to 4 hidden
layers / RF_70.
- Migrate remaining free-form training/indicator inputs to enums for UI
consistency; default news filter lookback to 1h, disable every-tick.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Tighten MAX_WEIGHT from 1.0e6 to 100.0 to prevent unbounded weight growth.
- Add MIN_ACTIVATION_DERIVATIVE (1e-4) to avoid zero gradients for saturated units.
- Introduce WEIGHT_DECAY (0.01) to decouple decay from Adam updates.
- Add MAX_WEIGHT_DELTA (0.1) to clamp per-step Adam updates and prevent overshoot.
- Apply sign-agreement gate on weight updates in Adam kernel to only apply steps aligned with current gradient direction.
- Fix tanh/sigmoid derivative calculations to use the new floor instead of hard-coded edge-case values.
Warrior_EA.mq5: clear Comment() and destroy the control panel before
Expert.Deinit()'s object-purge cascade runs out from under it; stop
re-registering the same signal filters on every DB retry (was causing a
double-delete of the same pointer on shutdown).
DirectML/WarriorCPU.cpp: bound the worker-thread join in ThreadPool::Stop()
instead of blocking forever - CPU_Shutdown() held g_mutex across an unbounded
join, so a watchdog-killed calling thread could leave it locked forever,
poisoning every future call into the DLL (matches reports of the EA getting
stuck on "initializing" after being removed and re-added to a chart).
Also includes prior era-0 label-cache prebuild and pullback/reversal
label-quality work in AI/Network.mqh, Expert/ExpertSignalAIBase.mqh, and
Variables/Inputs.mqh.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the absolute thread count input (CpuDllThreads) with a percentage-based CPU_LOAD_PRESET enum (TargetCPULoad). This allows users to specify a percentage of detected cores to use when the CPU DLL fallback is active, improving flexibility and preventing issues when multiple instances share the same CPU DLL pool. Also adds CPU_GetHardwareConcurrency() for accurate core detection.
Changed default HiddenLayersCount from LAYERS_5 to LAYERS_3 and NeuronsReduction from RF_80 to RF_60 to improve model generalization and reduce overfitting.
Add #resource directives for WarriorDML.dll and WarriorCPU.dll, and ExtractComputeDlls() to extract them on first run, enabling MQL Cloud Protector builds to ship DLLs without manual copy. Extend CNet::Save and Load with trainingComplete and indicatorParams arrays to persist AutoTune indicator param values.
- Define MAX_WEIGHT constant (1.0e6) for weight limits in clusters
- Remove redundant barrier from FeedForward kernel (prevents sync issues)
- Port FeedForwardProof and CalcInputGradientProof kernels for max-pooling (no weights, sliding max)
- Port FeedForwardConv kernel for convolution layers (shared weights, multiple output channels)
- Remove unused code and refactor signal condition logic (CSignalPAI)
- Updated README.md with project overview, key features, directory structure, getting started guide, and modernization roadmap.
- Added AI_NETWORK.md detailing the neural network and AI/ML infrastructure, including architecture, components, usage patterns, and next steps.
- Introduced DATABASE.md for the Database module, outlining key components, design highlights, usage patterns, and future enhancements.
- Created README.md files for Enumerations, Expert, Money, Signals, Structures, System, Trailing, Variables directories, detailing their purpose, key components, and integration notes.
- Documented the Signals subsystem, emphasizing modularity, extensibility, and AI/ML readiness.
- Added comprehensive descriptions for individual signal modules in Signals/ directory.
- Established clear integration notes and recommendations for future improvements across all modules.