Commit graph

86 commits

Author SHA1 Message Date
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
AnimateDread
a2ed4e3682 fix: word-wrap status labels via TextGetSize() to fix clipping and background overflow
Replace the static per-character width approximation with dynamic word-wrapping using
`TextGetSize()` to measure actual rendered pixel widths. This prevents status label text
from being clipped at the chart edge while its oversized background rectangle extended
beyond. Each line is now greedily wrapped to fit within the chart pane minus margins,
ensuring the measured string matches what is drawn. Also extracts font constant and adds
`WrapLineInto()` helper for reuse.
2026-07-17 21:36:44 -04:00
AnimateDread
bb9edfc119 fix(status-label): handle multi-line status text with per-line labels
OBJ_LABEL does not render embedded '\n' as line breaks, causing multi-line status text to appear as one truncated line. This commit splits the input text by newlines, creates a separate OBJ_LABEL and tightly-fit OBJ_RECTANGLE_LABEL background for each line, ensuring every line remains legible regardless of chart background.
2026-07-17 21:32:55 -04:00
AnimateDread
2c0cdf5e2b refactor(ai): replace Comment() with StatusLabel for training status display
Migrate all per-era classification counts, OOS confusion metrics, and training progress output from the legacy Comment() function to a dedicated StatusLabel object. This provides cleaner UI integration and avoids blocking the chart's normal info line during prolonged training cycles. A new include for StatusLabel.mqh has been added, and all related documentation comments updated accordingly.
2026-07-17 21:28:59 -04:00
AnimateDread
f5fa5b3fcc fix: always prebuild label cache to prevent silent neutral labels on checkpoint restart
Previously, on a successful checkpoint load (`netLoaded == true`), `m_labelCachePrebuilt` was set to `true`, skipping the eager prebuild scan. This caused every bar to fall back to `ComputeLabelForBar()`, a dead stub returning `buy=false/sell=false`, effectively labeling the entire era Neutral. Now we unconditionally set `m_labelCachePrebuilt = false`, ensuring the real ZigZag-based labeling logic runs via `AdvanceZigZagLabelState()` during the prebuild, regardless of checkpoint state.
2026-07-17 21:18:25 -04:00
AnimateDread
55ff1c40c4 perf: improve small layer dispatch and UI responsiveness
- Add inline threshold (512) in WarriorCPU to avoid thread-pool overhead for small dispatches; run small workloads inline on the calling thread.
- Reduce training time budget from 500ms to 120ms in ExpertSignalAIBase to keep the UI reactive while training.
2026-07-17 19:30:10 -04:00
AnimateDread
5e9e2f4136 perf: switch OpenCL kernels to float32 for consumer GPU compatibility
All __global buffers, local vectors, and constants (MAX_WEIGHT, MIN_ACTIVATION_DERIVATIVE, WEIGHT_DECAY, MAX_WEIGHT_DELTA) now use `float` instead of `double`. This avoids the 1/16th throughput penalty on consumer GPUs (e.g. AMD Polaris/RX 580) while remaining numerically safe: weight/delta clamps stay within ±100, gradients and activations fit float32, and the Adam epsilon guard is not sensitive to underflow. The removed `cl_khr_fp64` directive now causes an explicit compile failure if any double slips back in.
2026-07-17 19:04:56 -04:00
AnimateDread
b034430ed5 feat: switch weight initialization from LeCun-uniform to He-uniform
The network uses PReLU (leaky ReLU) activations for all hidden layers, but the previous initialization used LeCun-uniform scaling (1/sqrt(fan_in+1)), which is tuned for saturating activations like tanh/sigmoid. The new He-uniform scaling (sqrt(2/fan_in)) better accounts for the half-zeroing effect of ReLU variants, reducing the risk of early saturation and improving gradient flow during training. Applied uniformly across all layers via the shared Init() method, as the output layer (3 neurons) is negligibly affected and the more precise alternative would require risky threading of activation awareness through every neuron subtype.
2026-07-17 14:51:47 -04:00
AnimateDread
5a25771d20 fix: handle additional OCL neuron types and increase indicator period for swing detection
- 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.
2026-07-17 14:34:00 -04:00
AnimateDread
3faba25fbe 2026-07-17 09:29:45 -04:00
AnimateDread
80a53d5b04 feat: cap class sample weight and increase training time budget
- 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.
2026-07-17 09:11:42 -04:00