Warrior_EA/Expert/Topology/AIBaseTopologyViewImpl.mqh

89 lines
6.1 KiB
MQL5
Raw Permalink Normal View History

refactor(topology): split shape derivation into CTopology, leave the boot sequence in place Expert/AIBase/Topology.mqh (1191 lines) held two genuinely different jobs: the fingerprint/derived-shape/BuildFreshTopology math, and InitNeuralNetwork/ InitFeatureIndicators - the network boot sequence (config-lock, tester-cache seeding, load/save the .cfg, net-load backend fallback, chart/persistence/ online-learning orchestration). Extracted the first job to Expert/Topology/ as CTopology + CTopologyView/ CAIBaseTopologyView (20 methods: BuildModelFingerprint, the Estimated*/Compute* budget math, the Conv*/Lstm* shape helpers, Add*Stage, BuildFreshTopology). STATELESS, like ModelPersistence - grep-verified zero exclusive fields, every member these methods touch is shared elsewhere in the signal. Reused ~15 existing Data*/Chart*/Persist*/Exc* getters per the established convention; added ~20 new getter overloads next to their existing setters (UseVolumes(), MinDirectionalRecall(), etc. - same pattern as SignalClusterWindow) and ~16 new Topology*() wrappers for fields with no prior accessor. The Net-pointer swap in BuildFreshTopology is one consolidated view call (TopologyReplaceNetFromTopology), same doctrine as Persistence's RunCpuInferenceSelfCheck - irreducible pointer work, not signal state. Deliberately did NOT extract InitNeuralNetwork/InitFeatureIndicators: they orchestrate nearly every other collaborator (chart, persistence, online- learning, cross-asset, config-lock) rather than deriving a shape, so moving them would just relocate a hub, not reduce coupling - same judgment call as Inference.mqh (assessed, not extracted). They stay in the AIBase/Topology.mqh partial, byte-identical to before (diffed against git HEAD to confirm), and now call the extracted math through the same public forwards every other caller already used. Verified: string- and numeric-literal diff of the old file's 20 method bodies against the new CTopology methods (0 differences), InitNeuralNetwork/ InitFeatureIndicators byte-identical, self-compiled 0 errors/0 warnings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 23:23:00 -04:00
//+------------------------------------------------------------------+
//| Warrior_EA |
//| AnimateDread |
//| |
//| CAIBaseTopologyView bodies - needs the full signal declaration. |
//| Same doctrine as Persistence\AIBasePersistenceViewImpl.mqh - |
//| every method is a forward, borrowed pointer checked on every |
//| call. |
//+------------------------------------------------------------------+
#ifndef WARRIOR_TOPOLOGY_AIBASETOPOLOGYVIEWIMPL_MQH
#define WARRIOR_TOPOLOGY_AIBASETOPOLOGYVIEWIMPL_MQH
string CAIBaseTopologyView::Id(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataId() : ""; }
string CAIBaseTopologyView::SymbolName(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartSymbolName() : _Symbol; }
ENUM_TIMEFRAMES CAIBaseTopologyView::Timeframe(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartTimeframe() : PERIOD_CURRENT; }
int CAIBaseTopologyView::OptimizationAlgo(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyOptimizationAlgo() : 0; }
int CAIBaseTopologyView::OutputNeuronsCount(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartOutputNeuronsCount() : 0; }
int CAIBaseTopologyView::NeuronsCount(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataFeaturesPerBar() : 0; }
int CAIBaseTopologyView::HistoryBars(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataHistoryBars() : 0; }
int CAIBaseTopologyView::InitialNeuronsCount(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyInitialNeuronsCount() : 0; }
int CAIBaseTopologyView::HiddenLayersCount(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyHiddenLayersCount() : 0; }
int CAIBaseTopologyView::ConvFilterCount(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyConvFilterCount() : 0; }
int CAIBaseTopologyView::LstmHiddenSize(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyLstmHiddenSize() : 0; }
int CAIBaseTopologyView::MinTrainYear(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyMinTrainYear() : 0; }
int CAIBaseTopologyView::FractalPeriods(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyFractalPeriods() : 0; }
int CAIBaseTopologyView::OosSplitPct(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartOosSplitPct() : 0; }
int CAIBaseTopologyView::SwingConfirmationBars(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.SwingConfirmationBars() : 0; }
fix(topology): size the network against observations, not bars The capacity budget is stated in weights per INDEPENDENT observation and divides by the mean label lifespan to get there. It never once did: EstimatedInSampleBars() deflates via m_labelOverlap, but it is only ever called from InitNeuralNetwork, where the label cache does not exist yet (that same function sets m_labelCachePrebuilt = false a few lines below), so MeanLifespan() returned its "nothing measured" default of 1.0 at every call. Every fresh model was sized as though its labels did not overlap - over-budgeting the first dense layer by a factor of L, which is several rungs of a power-of-two ladder. The "expect overfitting, reduce the feature set or pool instruments" warning is the branch that should fire on H1 and structurally could not. Fixed at the source rather than by reordering the boot sequence (the prebuild is chunked across Train() calls and cannot complete inside init): MeasureSwingGeometry() walks the ZigZag ONCE at init and answers both questions from it - the median leg gives the window, and the leg series gives the mean label lifespan analytically. SwingPivotDirectionLabel resolves bar i when the SECOND pivot after it commits, so a bar d bars before pivot P waits d + (the leg leaving P); summed over every bar of every leg that is exactly the mean the label walk accumulates. That also closes the coherence gap the swing target opened: the window was measured with a private +/-12-bar fractal while the label aimed at ZigZag(12,5,3) pivots, so it was sized against a leg distribution the label never used. One pivot source now, the label's. Also: - ResetWeights() re-derives the shape. It rebuilt from the members a history-starved init had pinned and re-saved them - so the "let history download, then reset from the panel" advice in both fallback warnings did nothing at all. - The CAPACITY line prints the measured lifespan beside the one the topology was sized for, and warns when they differ by more than a ladder rung. That is the check that makes the estimator falsifiable. - Topology reads the view's symbol, not _Symbol (latent for pooling). - Unmeasured geometry defaults to HISTORY_BARS_FALLBACK, never 1.0: under-sizing is recoverable, over-sizing silently is not. Compile: 0 errors, 0 warnings (stage). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 21:21:05 -04:00
int CAIBaseTopologyView::ZigZagHandle(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyZigZagHandle() : INVALID_HANDLE; }
refactor(topology): split shape derivation into CTopology, leave the boot sequence in place Expert/AIBase/Topology.mqh (1191 lines) held two genuinely different jobs: the fingerprint/derived-shape/BuildFreshTopology math, and InitNeuralNetwork/ InitFeatureIndicators - the network boot sequence (config-lock, tester-cache seeding, load/save the .cfg, net-load backend fallback, chart/persistence/ online-learning orchestration). Extracted the first job to Expert/Topology/ as CTopology + CTopologyView/ CAIBaseTopologyView (20 methods: BuildModelFingerprint, the Estimated*/Compute* budget math, the Conv*/Lstm* shape helpers, Add*Stage, BuildFreshTopology). STATELESS, like ModelPersistence - grep-verified zero exclusive fields, every member these methods touch is shared elsewhere in the signal. Reused ~15 existing Data*/Chart*/Persist*/Exc* getters per the established convention; added ~20 new getter overloads next to their existing setters (UseVolumes(), MinDirectionalRecall(), etc. - same pattern as SignalClusterWindow) and ~16 new Topology*() wrappers for fields with no prior accessor. The Net-pointer swap in BuildFreshTopology is one consolidated view call (TopologyReplaceNetFromTopology), same doctrine as Persistence's RunCpuInferenceSelfCheck - irreducible pointer work, not signal state. Deliberately did NOT extract InitNeuralNetwork/InitFeatureIndicators: they orchestrate nearly every other collaborator (chart, persistence, online- learning, cross-asset, config-lock) rather than deriving a shape, so moving them would just relocate a hub, not reduce coupling - same judgment call as Inference.mqh (assessed, not extracted). They stay in the AIBase/Topology.mqh partial, byte-identical to before (diffed against git HEAD to confirm), and now call the extracted math through the same public forwards every other caller already used. Verified: string- and numeric-literal diff of the old file's 20 method bodies against the new CTopology methods (0 differences), InitNeuralNetwork/ InitFeatureIndicators byte-identical, self-compiled 0 errors/0 warnings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 23:23:00 -04:00
bool CAIBaseTopologyView::UseVolumes(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseVolumes() : false; }
bool CAIBaseTopologyView::UseTime(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseTime() : false; }
bool CAIBaseTopologyView::UseATR(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseATR() : false; }
bool CAIBaseTopologyView::UseSwingContext(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseSwingContext() : false; }
bool CAIBaseTopologyView::UseNews(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseNews() : false; }
int CAIBaseTopologyView::NewsFeatureWindowMinutes(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.NewsFeatureWindowMinutes() : 0; }
bool CAIBaseTopologyView::UseMA(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseMA() : false; }
bool CAIBaseTopologyView::UseCrossAsset(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseCrossAsset() : false; }
bool CAIBaseTopologyView::UseSpreadFeature(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseSpreadFeature() : false; }
bool CAIBaseTopologyView::UseAltData(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyUseAltData() : false; }
bool CAIBaseTopologyView::IsEnsembleMember(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataIsEnsembleMember() : false; }
double CAIBaseTopologyView::PooledIndependentBars(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyPooledIndependentBars() : 0.0; }
refactor(topology): split shape derivation into CTopology, leave the boot sequence in place Expert/AIBase/Topology.mqh (1191 lines) held two genuinely different jobs: the fingerprint/derived-shape/BuildFreshTopology math, and InitNeuralNetwork/ InitFeatureIndicators - the network boot sequence (config-lock, tester-cache seeding, load/save the .cfg, net-load backend fallback, chart/persistence/ online-learning orchestration). Extracted the first job to Expert/Topology/ as CTopology + CTopologyView/ CAIBaseTopologyView (20 methods: BuildModelFingerprint, the Estimated*/Compute* budget math, the Conv*/Lstm* shape helpers, Add*Stage, BuildFreshTopology). STATELESS, like ModelPersistence - grep-verified zero exclusive fields, every member these methods touch is shared elsewhere in the signal. Reused ~15 existing Data*/Chart*/Persist*/Exc* getters per the established convention; added ~20 new getter overloads next to their existing setters (UseVolumes(), MinDirectionalRecall(), etc. - same pattern as SignalClusterWindow) and ~16 new Topology*() wrappers for fields with no prior accessor. The Net-pointer swap in BuildFreshTopology is one consolidated view call (TopologyReplaceNetFromTopology), same doctrine as Persistence's RunCpuInferenceSelfCheck - irreducible pointer work, not signal state. Deliberately did NOT extract InitNeuralNetwork/InitFeatureIndicators: they orchestrate nearly every other collaborator (chart, persistence, online- learning, cross-asset, config-lock) rather than deriving a shape, so moving them would just relocate a hub, not reduce coupling - same judgment call as Inference.mqh (assessed, not extracted). They stay in the AIBase/Topology.mqh partial, byte-identical to before (diffed against git HEAD to confirm), and now call the extracted math through the same public forwards every other caller already used. Verified: string- and numeric-literal diff of the old file's 20 method bodies against the new CTopology methods (0 differences), InitNeuralNetwork/ InitFeatureIndicators byte-identical, self-compiled 0 errors/0 warnings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 23:23:00 -04:00
bool CAIBaseTopologyView::UsesConvStage(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.PersistUsesConvStage() : false; }
bool CAIBaseTopologyView::UsesLstmStage(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyUsesLstmStage() : false; }
bool CAIBaseTopologyView::HasConvBeforeLstm(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyHasConvBeforeLstm() : false; }
bool CAIBaseTopologyView::AddCustomLayers(CArrayObj *topology)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyAddCustomLayers(topology) : false; }
ENUM_ACTIVATION CAIBaseTopologyView::HiddenLayerActivation(void)
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
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataHiddenLayerActivation() : PRELU; }
refactor(topology): split shape derivation into CTopology, leave the boot sequence in place Expert/AIBase/Topology.mqh (1191 lines) held two genuinely different jobs: the fingerprint/derived-shape/BuildFreshTopology math, and InitNeuralNetwork/ InitFeatureIndicators - the network boot sequence (config-lock, tester-cache seeding, load/save the .cfg, net-load backend fallback, chart/persistence/ online-learning orchestration). Extracted the first job to Expert/Topology/ as CTopology + CTopologyView/ CAIBaseTopologyView (20 methods: BuildModelFingerprint, the Estimated*/Compute* budget math, the Conv*/Lstm* shape helpers, Add*Stage, BuildFreshTopology). STATELESS, like ModelPersistence - grep-verified zero exclusive fields, every member these methods touch is shared elsewhere in the signal. Reused ~15 existing Data*/Chart*/Persist*/Exc* getters per the established convention; added ~20 new getter overloads next to their existing setters (UseVolumes(), MinDirectionalRecall(), etc. - same pattern as SignalClusterWindow) and ~16 new Topology*() wrappers for fields with no prior accessor. The Net-pointer swap in BuildFreshTopology is one consolidated view call (TopologyReplaceNetFromTopology), same doctrine as Persistence's RunCpuInferenceSelfCheck - irreducible pointer work, not signal state. Deliberately did NOT extract InitNeuralNetwork/InitFeatureIndicators: they orchestrate nearly every other collaborator (chart, persistence, online- learning, cross-asset, config-lock) rather than deriving a shape, so moving them would just relocate a hub, not reduce coupling - same judgment call as Inference.mqh (assessed, not extracted). They stay in the AIBase/Topology.mqh partial, byte-identical to before (diffed against git HEAD to confirm), and now call the extracted math through the same public forwards every other caller already used. Verified: string- and numeric-literal diff of the old file's 20 method bodies against the new CTopology methods (0 differences), InitNeuralNetwork/ InitFeatureIndicators byte-identical, self-compiled 0 errors/0 warnings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 23:23:00 -04:00
ENUM_ACTIVATION CAIBaseTopologyView::OutputLayerActivation(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.PersistOutputLayerActivation() : TANH; }
int CAIBaseTopologyView::NetInputWidth(void)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyNetInputWidth() : 0; }
bool CAIBaseTopologyView::ReplaceNetFromTopology(CArrayObj *topology)
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyReplaceNetFromTopology(topology) : false; }
void CAIBaseTopologyView::ResetOnlineLearningForFreshTopology(void)
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.TopologyResetOnlineLearningForFreshTopology(); }
#endif // WARRIOR_TOPOLOGY_AIBASETOPOLOGYVIEWIMPL_MQH
//+------------------------------------------------------------------+