Commit graph

196 commits

Author SHA1 Message Date
AnimateDread
9ac161a4ac chore(project): remove unused Wyckoff indicator references 2026-07-23 15:44:55 -04:00
AnimateDread
ec6c87c9b5 cleanup 2026-07-23 15:29:26 -04:00
AnimateDread
aee542bc2f refactor(indicator-resources): centralize indicator embedding in main EA file
Moved #resource directives for all custom indicators from IndicatorResources.mqh to Warrior_EA.mq5 to keep embedding logic in a single location and simplify build configuration. Updated comments to clarify MARKET vs. private build behaviour and path resolution.
2026-07-23 15:28:04 -04:00
AnimateDread
4bc196d5d4 feat: add unified MA type support to indicator tuner
Add `MA_TYPE_PRESETS` enum covering advanced (ALMA, DEMA, ZLEMA, T3, Kalman) and standard (SMA, EMA, SMMA, LWMA) moving averages. Integrate `maType` and `bestMaType` into `CADIndicatorTuner` struct, update flatten/unflatten routines, and bump `AD_TUNE_PARAM_COUNT` to 33. This allows the auto-tuner to search over MA type alongside period, improving feature discovery.
2026-07-23 15:02:09 -04:00
AnimateDread
af74bf9121 feat: add confirmation dialogs for destructive actions and reorder panel buttons
- Added ConfirmDestructiveAction() function that shows a warning MessageBox before executing destructive reset/delete operations.
- Used confirmation for "Reset" (AI weights) and "ResetDB" (database) actions to prevent accidental data loss.
- Moved "Report" button creation before the "Signals" button so that the two red (destructive) buttons appear adjacent at the bottom of the panel.
2026-07-23 08:48:44 -04:00
AnimateDread
6c396862c9 fix: split AI model weight into 4 confidence tiers to fix quadratic derating
Replace single `m_pattern_0` weight with four confidence-tier weights (`m_pattern_0` through `m_pattern_3`) so that `UpdateSignalsWeights()` blends across multiple patterns like classic indicators. Previously, a single pattern caused the same win rate to be written to both the pattern weight and module weight, resulting in a quadratic derating (e.g., 70% win rate scored as 49 instead of 70). The new tiers bucket confidence into four equal bands between the minimum AI confidence and 1.0, with defaults 80/87/93/100. Added `ConfidenceTier()` and `PatternWeightForTier()` helpers, and changed default pattern count from 1 to 4.
2026-07-23 08:21:41 -04:00
AnimateDread
771c9b58ec feat: add weight scaling parameter to neuron initialization for improved training stability
- Added optional `weighScale` parameter (default -1.0) to `CNeuronBase::Init` and `CLayer::CreateElement`.
- Updated `CNeuronPool::Init` to use LeCun-uniform scaling (1/sqrt(window+1)) for its base initialization.
- Updated `CNet::CNet` to use He-scaled initialization (sqrt(2/neurons)) for dense layers.
- These changes enable more flexible and statistically sound weight initialization, matching the rationale used in OCL-based implementations, leading to better training stability and convergence.
2026-07-22 22:51:04 -04:00
AnimateDread
89e1e3c414 feat: expand Market_Description with detailed EA features and AI explanation
The description now thoroughly covers the two signal paths (classic and AI),
risk management options (position sizing, stop loss, trailing), and the AI's
self-learning and adaptability. This provides users with a clearer
understanding of the EA's capabilities and configuration choices.
2026-07-22 17:40:56 -04:00
AnimateDread
d667896457 refactor(AI): clean up comments and add conditional compilation guards
Remove verbose book references from input parameter comments in
Network.mqh for clarity. Add #ifndef guard around ENUM_OPTIMIZATION
to allow inclusion from multiple headers without redefinition.
Document the MQL5 Market DLL restriction in NeuronDirectML.mqh and
introduce WARRIOR_MARKET_BUILD macro to conditionally compile out
DirectML DLL imports for Market-compliant builds.
2026-07-22 17:17:23 -04:00
AnimateDread
0f0958856c feat: restructure input enums with intelligent SL/TP and AI exit
Replace old ATR_MULTIPLIER, THRESHOLDS_PRESET enums with new
STOP_LOSS_MODE, TAKE_PROFIT_MODE, AI_EXIT_MODE enums that support
ATR-based, intelligent confidence-scaled, and swing-anchored modes.
Also fix LSTM signal identity string.
2026-07-22 13:33:56 -04:00
AnimateDread
e2df5cfdc5 fix: improve OOS accuracy regression logging to include balanced accuracy and blended values 2026-07-21 14:23:13 -04:00
AnimateDread
3d5475ebcb refactor: defer arrow drawing to era-end sweep when NMS enabled
When `m_signalClusterWindow > 0`, training passes (1,2,3) now only record signal scores into `m_arrowSignalCache[]` and skip drawing arrows. The end-of-era `PruneDirectionalClusters()` sweep handles all rendering, preventing raw mid-era clusters from appearing and decoupling NMS from pass 2’s shuffled draw order.
2026-07-21 13:18:35 -04:00
AnimateDread
3f83bf192c fix: improve NMS clustering and cross-direction resolution in signal AI base
Change the non-maximum suppression algorithm so that same-direction
contiguous runs collapse to a single arrow by tracking the last SEEN
bar (instead of the last KEPT bar), preventing re-emission every
window+1 bars inside a long run.  Add confidence-based resolution
between opposite signals within the cluster window: only the higher-
confidence side is kept, reducing flicker around genuine turn zones.

Introduce new state variables (`m_nmsLiveBuyAccept`,
`m_nmsLiveSellAccept`, `m_nmsLiveKeptTime`, `m_nmsLiveKeptDir`,
`m_nmsLiveKeptConf`) to support idempotent re-evaluation of the same
live bar and cross-direction filtering.  Update `NmsLiveAccept` and
`PruneDirectionalClusters` to apply the same logic consistently for
both historical and live paths.
2026-07-21 12:30:29 -04:00
AnimateDread
c024e8dede feat: add non-max suppression and balanced accuracy for signal clustering and checkpoint ranking
Implement non-max suppression (NMS) to declutter signal visualizations by keeping only the first bar of each same-direction run, controlled by m_signalClusterWindow. Also replace blended accuracy with balanced accuracy (macro-recall) for checkpoint selection to avoid neutral bias, tracked via m_bestBalancedOos. This improves signal clarity and model deployment quality.
2026-07-21 00:03:45 -04:00
AnimateDread
7aec5c4916 feat(ExpertSignalAIBase): extend swing context with recent price-action features
Increase the swing context neuron count from 5 to 9 by adding four fresh, non-repainting features: Donchian range position at 20 and 50 bars, 20-bar return, and 20-bar SMA extension. These are computed from closed bars only, eliminating lookahead. They provide immediate trend/position context that the stale (~100-bar-old) confirmed pivot anchor cannot, enabling the network to differentiate genuine reversals at range extremes from mid-trend bars that resemble pivot shapes.
2026-07-20 19:17:23 -04:00
AnimateDread
e13ee77c94 feat(signal): add oversampling parity fraction and min signal confidence threshold
Introduce OVERSAMPLE_PARITY_FRACTION (0.7) to control minority class oversampling scaling, reducing low-quality directional calls by not fully replicating to parity. Add m_minSignalConfidence (0.5) to require a minimum softmax probability for live Buy/Sell orders, preventing firing on bare plurality (~0.34) and improving signal quality.
2026-07-20 15:55:21 -04:00
AnimateDread
9f6e2b3b34 refactor: set MAX_OVERSAMPLE to 100 and revert to exact labels
- Increased MAX_OVERSAMPLE_REPLICAS from 5 to 100 to serve only as an absolute sanity ceiling against degenerate tallies, not a binding limit – oversampling rate is now measurement-driven per era.
- Reverted LABEL_WINDOW_BARS to 0 (exact reversal candle only), as the earlier low recall motivating widening was observed on a flawed training stack that has since been fixed; exact labels get a clean re-test.
- Removed ArrayResize calls in Train that preallocated queues using MAX_OVERSAMPLE_REPLICAS, consistent with the shift to dynamic, measurement-based allocation.
2026-07-19 22:40:56 -04:00
AnimateDread
3ceb4c6431 fix: prevent silent mislabeling and false convergence after label cache wipe
When a new candle closes mid-run (e.g., after weekend market reopen), the label cache is
wiped and the fallback per-bar computation labels everything Neutral. Without this fix,
the rest of the training run silently trains and scores against an all-Neutral world,
causing false convergence (e.g., 84.9% accuracy with 100% Neutral truth). Now the
prebuild is re-armed after cache invalidation to defer the era until relabeling completes,
and convergence finalization requires directional recall to be actually measured (not n/a),
preventing a Neutral-only model from being certified.

Also improves logging to distinguish era 0 seeding from mid-run rebuilds.
2026-07-19 18:22:46 -04:00
AnimateDread
afee4cc4c1 fix: lower WEIGHT_DECAY to 0.001 to prevent argmax degeneration to Neutral
Reduce weight decay from 0.01 to 0.001 across all backends (Network.cl, Network.mqh, WarriorCPU.cpp) to fix a training collapse issue. The original 0.01 AdamW default caused discriminative weights to decay below the calibration-capped class-prior offsets, resulting in a monotonically shrinking per-bar logit spread and eventual constant Neutral predictions (argmax degenerated once evidence tilt dropped under the prior tilt). The new value 0.001 lifts the evidence ceiling 10× while still bounding long-run weight growth, restoring effective discrimination. Note: this change must remain in sync across all four backends.
2026-07-19 17:05:58 -04:00
AnimateDread
36345540ca fix: correct Adam optimizer weight update and hidden gradient calculation
- Adam: replace raw neuron gradient with per-weight gradient `g = gradient * outputVal` so that each input weight receives its own mt/vt, fixing a bug where all weights of a neuron were updated identically (uniform scaling).
- `calcHiddenGradients`: compute `gradient = sumDOW * activationDerivative` directly instead of routing through `calcOutputGradients` with a clamped pseudo-target, which corrupted hidden-layer error signals (especially for PRELU activations).
2026-07-19 14:55:45 -04:00
AnimateDread
96a9b414b4 feat: remove sign-agreement gate from Adam weight updates in OpenCL kernels
The sign-agreement gate in `UpdateWeightsAdam`, `UpdateWeightsConvAdam`, and `LSTM_UpdateWeightsAdam` caused a gradient ratchet effect under one-hot softmax with categorical cross-entropy, leading to an all-Neutral collapse. Removing this gate aligns all four backends (CPU, GPU, OpenCL, MQL) and restores correct gradient flow.
2026-07-19 14:50:52 -04:00
AnimateDread
e8452913c0 feat: add swing-context feature with confirmed zigzag pivot
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.
2026-07-19 11:04:38 -04:00
AnimateDread
3fbe16127e docs: simplify comments and enum descriptions across AI and Enums
Remove overly verbose explanations in Network.mqh comments and InputEnums.mqh enum values. Shorten descriptions to improve readability without losing essential information.
2026-07-18 23:59:40 -04:00
AnimateDread
6f95a402f4 refactor: replace class-balance loss weighting with data-level oversampling
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.
2026-07-18 23:25:54 -04:00
AnimateDread
39d785b0de fix: prevent oversampling weight compounding and fix era display lag
- Clarify MAX_OVERSAMPLE_REPLICAS comment: it is an outer safety cap; actual repCount is derived from m_maxClassSampleWeight.
- Introduce m_isTrainQueueWeightScale array to scale per-occurrence class-balance weight by repCount, avoiding independent compounding of frequency and magnitude.
- Add forceRefresh flag to UpdateTrainingStatusLabel to force panel update at era end, fixing one-era-behind display of era number.
2026-07-18 23:03:51 -04:00
AnimateDread
20f32306f3 feat(ml): add data-level oversampling for minority classes in training queue
Introduce MAX_OVERSAMPLE_REPLICAS=3 to duplicate minority-class (Buy/Sell) bars in the training queue, complementing the existing loss-level reweighting. Adam's update rule largely cancels gradient scaling, so pure loss weighting was insufficient to overcome class imbalance. Duplicating bars ensures Adam's moment estimates see minority gradients more frequently, preventing the Neutral-only collapse observed in practice.
2026-07-18 22:27:34 -04:00
AnimateDread
8ce30f39c3 . 2026-07-18 17:43:29 -04:00
AnimateDread
d91cabc114 refactor(MoneyIntelligent): replace streak-chasing lot sizing with fractional-Kelly criterion
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.
2026-07-18 17:39:58 -04:00
AnimateDread
31b2711c8f feat: add daily-loss and max-drawdown risk circuit breakers
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>
2026-07-18 17:29:38 -04:00
AnimateDread
d75bd6d6a8 feat: add configurable news event proximity/impact as an NN input feature
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>
2026-07-18 17:26:04 -04:00
AnimateDread
d0e89a6fc7 fix(SignalNewsFilter): scope calendar veto to the traded symbol's own currencies
CalendarValueHistory() was called with no country filter at all, so
ANY country's economic calendar event vetoed a trade regardless of
relevance - a JPY release blocked a EURUSD trade just as readily as a
USD one, making NF_MinImpact's fine-tuning far noisier than intended.

Adds System/NewsRelevance.mqh (GetRelevantCountryCodes/
ImpactWeightedProximity), a shared utility that cross-references
CalendarCountries() against the symbol's base/quote currency to get
the actually-relevant ISO country codes, then uses
CalendarValueHistory()'s country_code-filtering overload. Shared so
the upcoming NN news-input feature reuses the same relevance logic
rather than duplicating it.

Compiled clean (MetaEditor, 0 errors/0 warnings).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 17:22:33 -04:00
AnimateDread
4c0afd682b refactor(ExpertSignalAIBase): extract AutoTune param state into CADIndicatorTuner
CExpertSignalAIBase (4,326 lines, one class) carried 5 struct
definitions, 10 member fields, and 3 methods (Flatten/Unflatten/
PerturbRandom) purely for the AutoTuneIndicators search-space state -
entirely self-contained (never touches Net, Train()'s resumable state
machine, or anything else in the class). Extracted into a new
Expert/ADIndicatorTuner.mqh (CADIndicatorTuner), held as a single
m_indicatorTuner member.

TuneIndicatorsAndTrain() itself - the outer loop that actually
orchestrates Train()/Net/checkpointing around this tuner - turned out
to be exactly as tightly coupled to Train()'s resumable state machine
as Train() itself, so per the same caution already applied to Train()
in this refactor pass, it stays in CExpertSignalAIBase rather than
being pulled into the collaborator; it now calls the tuner's public
Flatten()/Unflatten()/PerturbRandom()/SaveAsBest()/RestoreBest()
instead of manipulating the structs inline.

All internal field-access renames (m_adCumDeltaParams.lookback ->
m_indicatorTuner.adCumDelta.lookback, etc., ~40 sites across the 5
InitAD*() indicator-setup methods) verified against a full grep sweep
- no leftover references to the old field/method names. Compiled
clean (MetaEditor, 0 errors/0 warnings).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 16:22:09 -04:00
AnimateDread
e4a154aa5e refactor(AI): split 8 self-contained classes out of the Network.mqh god-file
AI/Network.mqh was 5,805 lines / 18 classes in one file. Investigation
found method implementations for several classes (CNeuronBase/Pool/Conv,
CNeuronBaseOCL) hand-interleaved across thousands of lines - not safe to
split without risky manual reassembly. But 8 classes turned out to be
genuinely self-contained (declaration + every method body physically
contiguous, and only ever depended upon, never depending on anything
declared later): CConnection/CArrayCon, CNeuron, CDirectMLMy (+ its
WarriorDML.dll/WarriorCPU.dll #import blocks), CArrayLayer,
CLayerDescription, CBufferDouble, and CNeuronConvOCL/CNeuronPoolOCL.

Extracted each verbatim, via exact line-range extraction (not manual
retyping) to eliminate transcription risk, into its own AI/*.mqh file,
included from Network.mqh at the exact point each class used to sit -
preserving original declaration order exactly. Mathematically verified
byte-for-byte: reconstructing the original file from the 7 new files'
bodies + Network.mqh's remaining segments is line-for-line identical to
the pre-split git history. Compiled clean (MetaEditor, 0 errors/0
warnings) both before and after.

The remaining tangled classes (CNeuronBase, CNeuronPool, CNeuronConv,
CNet, CNeuronLSTM, CNeuronBaseOCL, CNeuronConvOCL/PoolOCL's shared base,
CNeuronLSTMOCL, COpenCLMy) stay in Network.mqh (now ~4,450 lines) -
splitting those safely needs deliberate per-method surgery, deferred to
a future dedicated pass rather than rushed into this one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 16:13:03 -04:00
AnimateDread
e6ff2506a8 refactor(Money): extract CMoneyRiskBase to remove FixedRisk/Intelligent duplication
CMoneyFixedRisk and CMoneyIntelligent both derived independently from
CExpertMoneyCustom and carried near-identical CalculatePotentialLoss()/
CheckOpenLong()/CheckOpenShort()/CalculateLotSize() bodies, maintained
in two places. New Money/MoneyRiskBase.mqh (CMoneyRiskBase) houses the
shared core, with two virtual hooks - AdjustRiskAmount()/AdjustLotSize()
- at the exact two points CMoneyIntelligent's confidence-scaling and
trade-history Optimize() step used to diverge. CMoneyFixedRisk now has
an empty body (the base's defaults are exactly its old behavior);
CMoneyIntelligent overrides only the two hooks. CMoneyFixedLot is
untouched - it doesn't do risk-based sizing.

Pure reorganization, no behavior change; compiled clean (MetaEditor,
0 errors/0 warnings).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 15:53:04 -04:00
AnimateDread
97cf7be556 chore: cleanup pass - dead code, stale wizard scaffolding, one edge-case guard
- 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>
2026-07-18 15:49:59 -04:00
AnimateDread
a9b497f615 fix(Inputs): shorten input comments that overflowed MQL5's 255-char identifier=value limit
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>
2026-07-18 15:44:57 -04:00
AnimateDread
7e27ad8729 fix(ExpertSignalAIBase): stop pass-3 resume from replaying pass 2 forever
m_isPass2Active going false was ambiguous between "pass 2 hasn't
started yet" and "pass 2 already finished" - both look identical to
a plain if(!m_isPass2Active) check. Once pass 3 (OOS scoring) needed
more than one chunk to finish, every resume into it fell through that
ambiguity on both the pass-1 and pass-2 gates and re-shuffled/replayed
the entire IS training queue from scratch, on top of never-reset
predicted-class counters - observed as era 0 looping the shuffle phase
forever with predicted Buy/Sell collapsing to 0 and predicted Neutral
climbing past the real bar count.

Adds a distinct m_isPass2Done flag so a resume can tell "not started"
apart from "already done" and correctly skip straight into pass 3.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 15:44:48 -04:00
AnimateDread
6a687cda41 feat: add SGD+momentum optimizer and input-driven hyperparameters
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.
2026-07-18 14:56:41 -04:00
AnimateDread
86cb37595d feat: introduce Pass 3 for OOS scoring and extract status label
Add a new post-training pass (m_isPass3Active) that scores the OOS region chronologically after pass 2 has trained the IS data. This fixes the previous stale scoring (which used pre-era weights) and ensures OOS metrics reflect the trained model.

New member variables track the OOS cursor and start index; UpdateTrainingStatusLabel extracts the inline formatting into a dedicated method to keep the panel updating during all three passes, eliminating the "stuck" appearance during pass 2/3.

Reset m_isPass3Active at era start and remove redundant inline formatting code from Train().
2026-07-18 12:10:37 -04:00
AnimateDread
379db0827c fix(ExpertSignalAIBase): add shuffled backprop pass 2 to prevent training instability
Adam's momentum (b=0.9) has an effective memory of ~1/(1-b)=10 steps, which closely matches the typical 5-bar contiguous same-class label runs around ZigZag pivots. Replaying these runs in the same chronological order every era allowed momentum to lock onto whichever run it was currently passing through, causing the network's end-of-era state to disproportionately reflect the most recent run (recency bias). This led to IS error climbing era-over-era (0.16→0.55+ over 25 eras) and OOS Buy/Sell recall whipsawing between near-0% and 70-100% despite near-equal label counts.

The fix implements a second pass within the resumable-chunk training loop: after pass 1 (sequential feedforward/scoring) queues all IS-eligible bars into an array, pass 2 trains on those bars in a freshly shuffled order – the standard SGD solution to break momentum’s lock on repeating patterns. New member variables `m_isTrainQueue`, `m_isTrainCursor`, and `m_isPass2Active` manage the queue and state transitions between passes, preserving the existing `TRAIN_TIME_BUDGET_MS` chunk-yield mechanism.
2026-07-18 11:33:21 -04:00
AnimateDread
87ca08f21b refactor: tune optimizer momentum and integrate focal loss to reduce multi-era bias
- 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.
2026-07-18 10:03:21 -04:00
AnimateDread
1a804fce28 feat: make class-balance oversampling multiplier configurable via input enum
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.
2026-07-18 02:01:06 -04:00
AnimateDread
457ae4acac refactor: Remove test holdout slice, add live signal alternation gate
- 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.
2026-07-17 23:55:10 -04:00
AnimateDread
5e97bded86 chore: update DirectML binaries (CPU and DML) with new compiled output 2026-07-17 23:23:15 -04:00
AnimateDread
e62c710d6f fix: correct array orientation and PReLU gradient backprop in hidden layers
- 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.
2026-07-17 23:21:12 -04:00
AnimateDread
e50f7d6c3b refactor: improve status label formatting in training schedule
Replace the raw debug dump (event call, prevSignal, studied time) in the status label with a clean, user-friendly summary showing era count, training state, and forecast. This provides clearer on-screen feedback when training stops, pauses, or completes.
2026-07-17 22:05:52 -04:00
AnimateDread
58049461c0 feat: show in-sample training percentage in progress log
The training progress display now includes the in-sample split percentage (100 - oosSplitPct) next to the accuracy, replacing the previously generic "IS Acc" label. This makes it clearer what proportion of data is used for in-sample training.
2026-07-17 21:56:25 -04:00
AnimateDread
ef95e19d1d fix: correct metric label in training output and improve status panel comments 2026-07-17 21:53:09 -04:00
AnimateDread
fe4c93cf71 refactor: simplify on-chart status text and remove verbose metrics
The training status panel was too tall and wordy, displaying detailed recall, precision, and continual-learning OOS simulation metrics that are not needed for at-a-glance monitoring. These metrics are still tracked internally for convergence gating, but removed from the on-chart display to keep the panel compact. Also shortened label names (e.g., "[IS] Accuracy" -> "IS Acc") to save space without reducing clarity.
2026-07-17 21:49:30 -04:00
AnimateDread
6f3daf23a3 fix(System/StatusLabel): correct type mismatches in TextGetSize usage
TextGetSize returns uint values, so dummyW, dummyH, textW, and textH
changed to uint. Added explicit casts to int where used in comparisons
or arithmetic to prevent signed/unsigned mismatch warnings.
2026-07-17 21:37:52 -04:00