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 - declarations only, bodies in |
|
|
|
|
|
//| AIBaseTopologyViewImpl.mqh (needs the full signal declared). |
|
|
|
|
|
//| Same shape as Persistence\AIBasePersistenceView.mqh. |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#ifndef WARRIOR_TOPOLOGY_AIBASETOPOLOGYVIEW_MQH
|
|
|
|
|
#define WARRIOR_TOPOLOGY_AIBASETOPOLOGYVIEW_MQH
|
|
|
|
|
#include "ITopologyView.mqh"
|
|
|
|
|
class CExpertSignalAIBase;
|
|
|
|
|
class CAIBaseTopologyView : public CTopologyView
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
CExpertSignalAIBase *m_owner;
|
|
|
|
|
public:
|
|
|
|
|
CAIBaseTopologyView(void) : m_owner(NULL) { }
|
|
|
|
|
void Bind(CExpertSignalAIBase *owner) { m_owner = owner; }
|
|
|
|
|
|
|
|
|
|
virtual string Id(void) override;
|
|
|
|
|
virtual string SymbolName(void) override;
|
|
|
|
|
virtual ENUM_TIMEFRAMES Timeframe(void) override;
|
|
|
|
|
virtual int OptimizationAlgo(void) override;
|
|
|
|
|
virtual int OutputNeuronsCount(void) override;
|
|
|
|
|
virtual int NeuronsCount(void) override;
|
|
|
|
|
virtual int HistoryBars(void) override;
|
|
|
|
|
virtual int InitialNeuronsCount(void) override;
|
|
|
|
|
virtual int HiddenLayersCount(void) override;
|
|
|
|
|
virtual int ConvFilterCount(void) override;
|
|
|
|
|
virtual int LstmHiddenSize(void) override;
|
|
|
|
|
virtual int MinTrainYear(void) override;
|
|
|
|
|
virtual int FractalPeriods(void) override;
|
|
|
|
|
virtual int OosSplitPct(void) override;
|
|
|
|
|
virtual int SwingConfirmationBars(void) override;
|
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
|
|
|
virtual int ZigZagHandle(void) override;
|
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
|
|
|
|
|
|
|
|
virtual bool UseVolumes(void) override;
|
|
|
|
|
virtual bool UseTime(void) override;
|
|
|
|
|
virtual bool UseATR(void) override;
|
|
|
|
|
virtual bool UseSwingContext(void) override;
|
|
|
|
|
virtual bool UseNews(void) override;
|
|
|
|
|
virtual int NewsFeatureWindowMinutes(void) override;
|
|
|
|
|
virtual bool UseMA(void) override;
|
|
|
|
|
virtual bool UseCrossAsset(void) override;
|
|
|
|
|
virtual bool UseSpreadFeature(void) override;
|
|
|
|
|
virtual bool UseAltData(void) override;
|
|
|
|
|
virtual bool IsEnsembleMember(void) override;
|
2026-08-25 22:51:50 -04:00
|
|
|
virtual double PooledIndependentBars(void) override;
|
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
|
|
|
|
|
|
|
|
virtual bool UsesConvStage(void) override;
|
|
|
|
|
virtual bool UsesLstmStage(void) override;
|
|
|
|
|
virtual bool HasConvBeforeLstm(void) override;
|
|
|
|
|
virtual bool AddCustomLayers(CArrayObj *topology) override;
|
|
|
|
|
virtual ENUM_ACTIVATION HiddenLayerActivation(void) override;
|
|
|
|
|
virtual ENUM_ACTIVATION OutputLayerActivation(void) override;
|
|
|
|
|
virtual int NetInputWidth(void) override;
|
|
|
|
|
|
|
|
|
|
virtual bool ReplaceNetFromTopology(CArrayObj *topology) override;
|
|
|
|
|
virtual void ResetOnlineLearningForFreshTopology(void) override;
|
|
|
|
|
};
|
|
|
|
|
#endif // WARRIOR_TOPOLOGY_AIBASETOPOLOGYVIEW_MQH
|
|
|
|
|
//+------------------------------------------------------------------+
|