| Filename | Latest commit message | Latest commit date |
|---|---|---|
~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>
|
||
| .. | ||
| README.md | ||
| SignalCONV.mqh | ||
| SignalHYBRID.mqh | ||
| SignalLSTM.mqh | ||
| SignalNewsFilter.mqh | ||
| SignalPAI.mqh | ||
| SignalRiskGuard.mqh | ||
| Signals.mqh | ||
| SignalSessionFilter.mqh | ||
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 shippedfalselong before removal.- Consequence: these were
CSignalMETA's only wiredAddCandidateSourcecalls, 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_SLOTSstays at 26 regardless. A tester-built corpus on disk still encodes those pattern ids, and narrowing the descriptor would invalidate every stored corpus.
- Consequence: these were
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 inVariables/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/_closeand the weighted-averageDirection()all ship with MQL5. "Going back to stock" removes none of them. What is ours isCExpertSignalCustom'sDirection()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.