Warrior_EA/Signals
Repository files (latest commit first)
Filename Latest commit message Latest commit date
AnimateDread 1baa13c5b4 refactor(meta): remove meta-labeling entirely - RETRAIN-NEUTRAL
~2,300 lines. META had real, repeatedly measured ranking skill and ZERO
operating points that ever cleared break-even (0/350 H1 eras, 1/999 H4
pre-2-sigma, 0/8 pooled fitted points). The clinching arithmetic was edge x
width = 0.095 ATR/trade against spread 0.099 ATR/trade, and the
dose-response showed the high-conviction tail is temporally unstable -
the precision-vs-threshold slope flips sign between calib and test on 3 of
4 symbols, so no ex-ante threshold rule exists. It shipped default-off and
never gated a live entry. The self-measured tier weights are what actually
rank the vote, and all six H4 instruments converged on them alone.

RETRAIN-NEUTRAL, and that is the property that made this safe:

  - The weights fingerprint emitted "|TGT:META2" or "|TGT:SWG1" from an
    if/else. Every direction model already took the SWG1 arm, so
    collapsing it to an unconditional append is byte-identical. No .nnw or
    .cfg is orphaned or re-keyed.
  - NetInputWidth() lost its "+ MetaDescWidth()" term. MetaDescWidth()
    returned 0 for every direction model, so the input layer is unchanged.
  - DbLegacyAiSlot()'s slot 5 was reachable only with all four Use_* NNs
    off AND meta on - a config that never shipped. Every existing .db keeps
    its filename.

Deleted outright: Signals/SignalMETA.mqh, Expert/Trading/MetaGate.mqh (the
directory is now empty), Expert/Training/{MetaCorpus,MetaCandidateStore,
MetaFamilies}.mqh, Tests/Test_MetaFamilies.mq5, Meta_Labeling_Design.md.

Unwound in place, the delicate part: Training.mqh carried four
IsMetaTarget() branches whose else-arm WRAPPED the direction body (pass 1
queueing, pass 2 backprop, pass 2.5 calibration, pass 3 OOS scoring). Each
wrapper is removed and the direction body promoted back to its original
nesting - the bodies were never re-indented when the wrappers were added,
so the promoted code is byte-identical to what ran before META existed.
Also gone: the ensemble verdict's meta-veto replay and its
approved/vetoed/unscored counters, the per-family/per-side OOS
decomposition arrays, the m_isTrainQueueCand parallel queue and its
lockstep shuffle, and the S2 era report.

Also removed: the CMetaGate abstraction and the live CheckOpenPosition
veto; m_gates plus AddFilter's non-voter routing and IsVotingSignal()
(META was the only non-voting child, so m_gates was always empty);
m_parentSignal/SetParentSignal (existed only to reach the root's gate);
SweepPrepare/SweepPrepareIndicator (only caller was the corpus sweep);
IsMetaTarget() from all four view interfaces and their adapters;
Use_MetaLabeling, EnableMETA, Meta_ExportDataset, m_trainTarget.

EvalShift is KEPT - HistoricalNetVote() uses it for the filtered overlay,
not just the corpus sweep; only its comment changed. The 2-output softmax
arm in NetForward.mqh is kept too: it costs nothing and is the reusable
binary-head path, now commented as unclaimed rather than as META's.

Compile-verified in _claude_stage: 0 errors, 0 warnings, matching the
pre-edit baseline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 09:44:52 -04:00
..
README.md docs(signals): README described a folder that no longer existed 2026-08-24 09:21:49 -04:00
SignalCONV.mqh refactor(signals): AI signal files are identity + topology, nothing else 2026-08-20 08:57:54 -04:00
SignalHYBRID.mqh refactor(signals): AI signal files are identity + topology, nothing else 2026-08-20 08:57:54 -04:00
SignalLSTM.mqh refactor(signals): AI signal files are identity + topology, nothing else 2026-08-20 08:57:54 -04:00
SignalNewsFilter.mqh fix: add error logging for buffer failures and reject trades on invalid stop loss 2026-07-26 12:12:14 -04:00
SignalPAI.mqh refactor(signals): AI signal files are identity + topology, nothing else 2026-08-20 08:57:54 -04:00
SignalRiskGuard.mqh Add new research scripts for trading strategy analysis 2026-08-02 12:25:20 -04:00
Signals.mqh refactor(meta): remove meta-labeling entirely - RETRAIN-NEUTRAL 2026-08-25 09:44:52 -04:00
SignalSessionFilter.mqh refactor(signals): dedupe SignalSessionFilter's per-session window computation 2026-08-24 02:18:46 -04:00

Signals Subsystem (Signals/)

Every trade-signal class the EA can construct. Each is a CExpertSignalCustom (rule-based) or a CExpertSignalAIBase (neural), and each is gated by its own Enable* input in Variables/Inputs.mqh — so this directory is the roster, not the running configuration.

Signals.mqh is the only file the EA includes; it pulls in the rest.

What is here

Neural votes — CExpertSignalAIBase

File Class Role
SignalPAI.mqh CSignalPAI Dense MLP direction vote.
SignalCONV.mqh CSignalCONV Convolutional front end.
SignalLSTM.mqh CSignalLSTM Recurrent, sequence over the input window.
SignalHYBRID.mqh CSignalHYBRID Conv front end feeding an LSTM.
SignalMETA.mqh CSignalMETA Not a voter. A GATE — see below.

Two or more enabled makes an ensemble; exactly one is a solo model. The roster is chosen with Use_MLP / Use_CONV / Use_LSTM / Use_CONVLSTM, not with per-class inputs, and it is reported by EnabledNNSummary().

Filters — CExpertSignalCustom

File Class Role
SignalNewsFilter.mqh CSignalNewsFilter Blocks around calendar events, by impact and lookback.
SignalSessionFilter.mqh CSignalSessionFilter London / New York / Tokyo session gating.
SignalRiskGuard.mqh CSignalRiskGuard Takes no parameters: thresholds, anchors and state file all live on g_riskBudget, evaluated per tick rather than per bar.

CSignalMETA is routed, not voted

AddFilter inspects IsVotingSignal(), which is false for a meta head, so META is adopted as a gate rather than a voter: it vetoes vote-cleared entries whose predicted win probability is below cost-adjusted break-even. It never votes a direction, never blocks an exit, and fails open loudly. It still receives indicators, ticks, panel commands and traits, because the administrative walks cover the whole tree — it is simply absent from every consumer of the voting list, and it is added last so no other filter's m_ignore/m_invert bit index moves.

Its candidate corpus comes from CMetaCorpus::LoadLargestOnDisk (a tester-built DB). The on-chart ladder sweep is still implemented (BuildCorpusBySweep) but has no wired sources — see below.

What was removed, and why it is not coming back

Deleting these is the only way to stop re-deriving the same negative result, so the reasons are recorded here rather than in a commit nobody re-reads.

  • SignalMA / SignalRSI / SignalMACD / SignalIchimoku (2026-08-24). All 26 shipped vote patterns were transcribed with their constructor weights and tested as entries on 178k-bar histories, four instruments × three barrier geometries. Nothing separated from chance — not individually, not by vote threshold, not by 2/3/4-module quorum, not as event plus confirmation. Residual E[R] was −0.01 to −0.08 R everywhere, which is approximately the spread. The +4σ reading that once justified the set was two bars of lookahead; closing it took MACD pattern 4 on EURUSD from +5.05pp to −0.02pp. All four inputs had shipped false long before removal.
    • Consequence: these were CSignalMETA's only wired AddCandidateSource calls, so a META chart is no longer self-contained. AddCandidateSource() survives as the extension point; the DB fallback is the supported route.
    • META_ONE_HOT_SLOTS stays at 26 regardless. A tester-built corpus on disk still encodes those pattern ids, and narrowing the descriptor would invalidate every stored corpus.
  • OscillatorDivergence.mqh (2026-08-24). Shared extremum/divergence detector; RSI and MACD were its only users.
  • SignalITF / SignalMarketDepth (2026-08-01). A bitmask-configured time filter, and a DOM module with no way to test it. See the removal notes in Variables/Inputs.mqh.
  • SignalAC / SignalAO / SignalCCI / SignalDTDB / SignalEB / SignalIB / SignalPB / SignalRVI / SignalSAR / SignalStoch / SignalWPR — earlier wizard-derived votes, removed before the classic-pattern study.

Conventions worth knowing before editing

  • Weights, patterns and thresholds are stock CExpertSignal, not project additions: m_pattern_0..N, m_weight, m_patterns_usage, m_threshold_open/_close and the weighted-average Direction() all ship with MQL5. "Going back to stock" removes none of them. What is ours is CExpertSignalCustom's Direction() override, and every one of its six divergences from the library is a documented fix — most importantly dividing by the sum of CAPABLE weight rather than by the voter count, which the library's own divisor turned into a mean of products of two win rates.
  • Direction() is a transaction. It journals DB rows, draws arrows and consumes one-shot vote state, which is why callers must not invoke it speculatively.