Commit graph Warrior_EA/Expert/Training/DeployGate.mqh
Author SHA1 Message Date
AnimateDread
0fddaeea12 fix: correct edge floor percentage calculation and logging for model training 2026-08-25 23:16:05 -04:00
AnimateDread
b2784b5a4d Enhance Feature and Topology Interfaces with Bulk Operations and Cache Management
- Added bulk read/write methods for feature caches in IFeaturesView and its implementations to optimize performance.
- Introduced LabelCacheInvalidateAll method to manage label cache invalidation alongside feature cache.
- Implemented PooledIndependentBars method in topology interfaces to account for additional independent observations.
- Enhanced risk budget management with throttling for peak-equity updates to reduce unnecessary file operations.
- Improved error handling and logging for ATR trailing stops to ensure better visibility of issues.
- Updated alt-data handling to prevent unnecessary operations during testing and optimization phases.
2026-08-25 22:51:50 -04:00
AnimateDread
8f2164698b feat(target): delete the barrier/geometry stack - the label is the verdict
Step 3 of the swing-pivot plan, whole-hog. The swing label is now the ONE
target and the era verdict is precision + recall per class against the
label's own base rate - no win rate, no break-even, no expectancy, no
geometry anywhere in training.

DELETED
- Expert/Excursion/ (4), Expert/BarrierHorizon/ (4), GeometrySweep,
  FirstPassageLadder, Labeling/TripleBarrier.mqh (CLabelOverlap survives
  in Labeling/LabelOverlap.mqh), 3 test EAs.
- TripleBarrierLabel + walk, fractal label, geometry derivation/scan/
  adoption, exit-policy replay, excursion MI targets, the drift verdict
  (DIRECTION_INTELLIGENT), the recall floor, balanced-accuracy telemetry,
  the barrier defines, the .cfg geometry adopt (slots kept as zeros for
  the positional layout), the derived-geometry live-order override.
- TRAINING_TARGET input/enum: direction models are always swing; META2
  re-keys the meta head onto label agreement (descriptor loses its two
  geometry slots).

REWORKED
- Labels.mqh (1795 -> ~370 lines): AdvanceSwingLabelState with
  FINALITY-GATED CACHING - an unresolved bar (pivot pair uncommitted) is
  never cached, so it can never freeze as a false Neutral; training,
  calibration, OOS scoring and online learning all skip unresolved bars.
- SDeployVerdict: significance-only; SOosTally chance = larger
  directional class share; pooled gate poolability = timeframe (record v2).
- Purge/embargo/declustering gaps: the measured mean label resolution
  lag (LabelResolutionBars), not a barrier horizon.
- Pool purge key + backfill DB rows: marked at the bar the label
  resolved on (m_labelResolveAge), not a fabricated barrier touch.
- Online learning frontier: finality, not a horizon delay.
- m_bestBalancedOos -> m_bestSelectionScore, m_erasSinceBestBalanced ->
  m_erasSinceBest, ensemble vote outcome arrays -> label arrays.

STEP 4 folded in: Entry_Multiplier / SL_Mode / TP_Mode / tradingdirection
are inputs again - trade management is the tester GA's search space.

Fingerprints: every direction model re-keys (TGT:SWG1 now unconditional,
CUT token gone); META1 -> META2. Full retrain, as planned.

Compile-verified in _claude_stage: Warrior_EA + both surviving test EAs,
0 errors, 0 warnings each.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 20:42:31 -04:00
AnimateDread
d12b742a40 fix(deploy): print the selection score in the unit it is actually in
selectionScore used to be a win rate in percentage points and printed at one
decimal everywhere. Under DeployOnExpectancy it is expected value in R, so
"%.1f" rendered every real score as "0.0" - era 2's +0.05R and a genuine zero
looked identical, which makes the journal useless for watching the ranking the
plateau ladder is doing.

One formatter, DeployScoreText(), next to the score it formats: "%.3fR" under
expectancy, "%.1f%%" under significance. Routed all nine print sites through it
(ensemble era line, best-so-far, panel, regression, new-best, era-cap prompts,
the convergence line, the deploy dialog) and dropped the "%" suffixes they had
hardcoded. No new prints, no new log lines.

Compile-verified in the staging copy: 0 errors, 0 warnings.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 17:21:57 -04:00
AnimateDread
9883b209c7 feat(deploy): ship on positive EXPECTANCY, and let the chart draw before convergence
TWO CHANGES, both of which turn a permanent "nothing happens" into a decision.

1. THE DEPLOY GATE ASKS THE WRONG QUESTION. tradeable required the win rate to
   clear chance by EDGE_MIN_SIGMAS - "can I PROVE an edge exists" from one OOS
   window. On H4 that asks ~66% against a market supplying ~53%, so it is
   unreachable by construction and no run has ever deployed through it.

   SDeployVerdict now also carries the economics of the geometry actually being
   traded - cost-adjusted break-even and reward:risk, both from the new
   CostAdjustedGeometry() so a spread convention cannot be applied to one and
   missed on the other - and derives

       E[R] = (p - p*) * (1 + RR)

   which is exactly zero at break-even by construction, so "profitable" and
   "beats break-even" can never disagree. Under DeployOnExpectancy (new input,
   default ON) tradeable becomes E[R] > 0 and selectionScore ranks eras by
   expectancy instead of precision. Coverage and both-sides-live still gate
   both: an expectancy over a handful of one-sided calls is not tradeable.

   The struct also publishes scoreSE - the SE of selectionScore IN THE SCORE'S
   OWN UNITS - because the score changes units with the objective (win-rate
   points vs R). Both plateau bands now read it instead of precSE, which was
   right for one objective and dimensionally wrong for the other.

   Setting DeployOnExpectancy=false restores the previous behaviour exactly.

2. THE FILTERED VIEW COULD NOT DRAW WHILE ANY MODEL WAS TRAINING.
   HistoricalNetVote built its divisor from VoteCapableWeight(), which answers
   "may this member move real money" and returns 0.0 for an AI member until the
   whole run converges. So the reconstruction's divisor was zero on EVERY bar,
   every bar was skipped as "nobody looked", and the chart drew nothing at all -
   for the entire training run, which before the plateau noise band was forever.
   Reported as "no signals drawn since the refactor".

   New ReconstructionWeight(): the same weight WITHOUT the converged-run
   requirement, overridden on the AI member to ModuleWeight() gated on
   SelfRanked() only. The overlay is a picture of what the vote WOULD have
   shown, which a mid-training model can answer - the chart HUD already says so
   with its "(trn)" marker. Live Direction() still uses VoteCapableWeight(), so
   no untrained model gains a say in an order.

Compile-verified in the staging copy: 0 errors, 0 warnings.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 16:15:06 -04:00
AnimateDread
3ea2bbc015 refactor(gate): the member gate and the ensemble gate were one rule written twice
SDeployVerdict::EvaluateRates() is now the deploy arithmetic - coverage
floor, chance + EDGE_MIN_SIGMAS x SE, tradeability, and the coverage-
discounted ranking score - and both gates call it.

The duplicate was self-documenting. The ensemble copy carried three comments
asking a reader to keep it in step with the member copy by hand: "same
intent as the member gate's coverage floor + bothSidesLive", "the two gates
have to apply the identical correction or the ensemble becomes the easier
one to clear", "same lexicographic ordering as isBetterEra". They had
already fallen out of step once - 2c443ba found the ensemble certifying a
vote the EA never casts, in the wrong currency and against the wrong
denominator.

THE TWO REAL DIFFERENCES ARE NOW ARGUMENTS, not branches:
  chancePct  - the ensemble filters its zero-skill reference by the
               direction policy, because with shorts blocked "always short"
               is not a book anyone could run.
  twoSided   - a member reads per-side RECALL against a floor; the vote
               reads whether it actually fired both ways.
Everything else was identical and is now literally identical.

effN stays an argument so the label-overlap deflation lives where it is
measured - and so the remaining inconsistency stays visible rather than
buried: the two FAMILY-WISE selection gates still take their SE from RAW n.
Recorded in the header, deliberately not changed; tightening them is a
policy call, not a refactor.

The decision now reads no chart, holds no net, prints nothing and opens no
file, so it can be exercised against a made-up tally.

BEHAVIOUR UNCHANGED: every expression keeps its formula, its guard and its
-1 sentinel; the ensemble's chance-reference and two-sidedness rules are
passed through untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 14:19:44 -04:00