refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Warrior_EA |
|
|
|
|
|
//| AnimateDread |
|
|
|
|
|
//| |
|
|
|
|
|
//| CAIBaseFeaturesView bodies - needs the full signal declaration. |
|
|
|
|
|
//| Same doctrine as Topology\AIBaseTopologyViewImpl.mqh - every |
|
|
|
|
|
//| method is a forward, borrowed pointer checked on every call. |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#ifndef WARRIOR_FEATURES_AIBASEFEATURESVIEWIMPL_MQH
|
|
|
|
|
#define WARRIOR_FEATURES_AIBASEFEATURESVIEWIMPL_MQH
|
|
|
|
|
string CAIBaseFeaturesView::Id(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataId() : ""; }
|
|
|
|
|
string CAIBaseFeaturesView::SymbolName(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartSymbolName() : _Symbol; }
|
|
|
|
|
ENUM_TIMEFRAMES CAIBaseFeaturesView::Timeframe(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartTimeframe() : PERIOD_CURRENT; }
|
|
|
|
|
int CAIBaseFeaturesView::HistoryBars(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataHistoryBars() : 0; }
|
|
|
|
|
int CAIBaseFeaturesView::NeuronsCount(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataFeaturesPerBar() : 0; }
|
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
|
|
|
int CAIBaseFeaturesView::LabelResolutionBars(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataLabelResolutionBars() : 1; }
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
double CAIBaseFeaturesView::EffectiveSampleSize(const double rawN)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.DataEffectiveSampleSize(rawN) : rawN; }
|
|
|
|
|
double CAIBaseFeaturesView::MeanLabelLifespan(void)
|
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
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureMeanLabelLifespan() : 1.0; }
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
int CAIBaseFeaturesView::FirstLayerFanIn(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureFirstLayerFanIn() : 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
|
|
|
double CAIBaseFeaturesView::SwingLifespanEstimate(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureSwingLifespanEstimate() : 1.0; }
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
double CAIBaseFeaturesView::EstimatedInSampleBarsRaw(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureEstimatedInSampleBarsRaw() : 0.0; }
|
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
|
|
|
double CAIBaseFeaturesView::ChanceRatePct(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureChanceRatePct() : -1.0; }
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
bool CAIBaseFeaturesView::UseAltData(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyUseAltData() : false; }
|
|
|
|
|
int CAIBaseFeaturesView::SwingConfirmationBars(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.SwingConfirmationBars() : 0; }
|
|
|
|
|
int CAIBaseFeaturesView::NewsFeatureWindowMinutes(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.NewsFeatureWindowMinutes() : 0; }
|
|
|
|
|
int CAIBaseFeaturesView::InitialNeuronsCount(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.TopologyInitialNeuronsCount() : 0; }
|
|
|
|
|
string CAIBaseFeaturesView::ActiveFileName(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.OnlineActiveFileName() : ""; }
|
|
|
|
|
|
|
|
|
|
bool CAIBaseFeaturesView::UseVolumes(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseVolumes() : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::UseMA(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseMA() : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::UseATR(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseATR() : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::UseTime(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseTime() : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::UseSwingContext(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseSwingContext() : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::UseNews(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseNews() : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::UseSpreadFeature(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseSpreadFeature() : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::UseCrossAsset(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.UseCrossAsset() : false; }
|
|
|
|
|
|
|
|
|
|
double CAIBaseFeaturesView::OpenAt(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureOpenAt(idx) : EMPTY_VALUE; }
|
|
|
|
|
double CAIBaseFeaturesView::HighAt(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureHighAt(idx) : EMPTY_VALUE; }
|
|
|
|
|
double CAIBaseFeaturesView::LowAt(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureLowAt(idx) : EMPTY_VALUE; }
|
|
|
|
|
double CAIBaseFeaturesView::CloseAt(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartBarClose(idx) : EMPTY_VALUE; }
|
|
|
|
|
datetime CAIBaseFeaturesView::TimeAt(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.ChartBarTime(idx) : 0; }
|
|
|
|
|
double CAIBaseFeaturesView::AtrMain(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.OnlineAtrMain(idx) : EMPTY_VALUE; }
|
|
|
|
|
int CAIBaseFeaturesView::AtrBarsCalculated(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureAtrBarsCalculated() : -1; }
|
|
|
|
|
int CAIBaseFeaturesView::AtrHandle(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureAtrHandle() : INVALID_HANDLE; }
|
|
|
|
|
int CAIBaseFeaturesView::ZigZagBarsCalculated(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureZigZagBarsCalculated() : -1; }
|
|
|
|
|
int CAIBaseFeaturesView::ZigZagHandle(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureZigZagHandle() : INVALID_HANDLE; }
|
|
|
|
|
bool CAIBaseFeaturesView::FindConfirmedZigZagPivot(const int fromIdx, int &pivotIdx, double &pivotPrice, bool &pivotIsLow)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureFindConfirmedZigZagPivot(fromIdx, pivotIdx, pivotPrice, pivotIsLow) : false; }
|
|
|
|
|
double CAIBaseFeaturesView::SymbolPoint(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureSymbolPoint() : 0.0; }
|
|
|
|
|
|
|
|
|
|
CIndicators *CAIBaseFeaturesView::IndicatorsPtr(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureIndicatorsPtr() : NULL; }
|
|
|
|
|
CADIndicatorTuner *CAIBaseFeaturesView::IndicatorTuner(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureIndicatorTuner() : NULL; }
|
|
|
|
|
CCrossAssetPanel *CAIBaseFeaturesView::CrossAsset(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureCrossAsset() : NULL; }
|
|
|
|
|
|
|
|
|
|
int CAIBaseFeaturesView::AltDataFeatureCount(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureAltDataFeatureCount() : 0; }
|
|
|
|
|
void CAIBaseFeaturesView::AltDataEnsureFresh(const datetime asOf)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureAltDataEnsureFresh(asOf); }
|
|
|
|
|
void CAIBaseFeaturesView::AltDataFeatures(const datetime t, double &out[])
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureAltDataFeatures(t, out); }
|
|
|
|
|
|
|
|
|
|
string CAIBaseFeaturesView::CrossAssetPairsPinned(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.PersistCrossAssetPairsPinned() : ""; }
|
|
|
|
|
void CAIBaseFeaturesView::SetCrossAssetPairsPinned(const string v)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.PersistSetCrossAssetPairsPinned(v); }
|
|
|
|
|
bool CAIBaseFeaturesView::CrossAssetCfgSaved(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.PersistCrossAssetCfgSaved() : false; }
|
|
|
|
|
void CAIBaseFeaturesView::SetCrossAssetCfgSaved(const bool v)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.PersistSetCrossAssetCfgSaved(v); }
|
|
|
|
|
bool CAIBaseFeaturesView::CommitCrossAssetPin(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureCommitCrossAssetPin() : false; }
|
|
|
|
|
|
|
|
|
|
int CAIBaseFeaturesView::FeatureCacheSize(void)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureCacheSize() : 0; }
|
|
|
|
|
bool CAIBaseFeaturesView::FeatureCacheHasValue(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureCacheHasValue(idx) : false; }
|
|
|
|
|
bool CAIBaseFeaturesView::FeatureCacheIsValid(const int idx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureCacheIsValid(idx) : false; }
|
|
|
|
|
double CAIBaseFeaturesView::FeatureCacheAt(const int flatIdx)
|
|
|
|
|
{ return (CheckPointer(m_owner) != POINTER_INVALID) ? m_owner.FeatureCacheAt(flatIdx) : 0.0; }
|
2026-08-25 22:51:50 -04:00
|
|
|
void CAIBaseFeaturesView::FeatureCacheBlock(const int base, const int count, double &out[])
|
|
|
|
|
{
|
|
|
|
|
if(CheckPointer(m_owner) != POINTER_INVALID)
|
|
|
|
|
m_owner.FeatureCacheBlock(base, count, out);
|
|
|
|
|
else
|
|
|
|
|
ArrayResize(out, 0);
|
|
|
|
|
}
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
void CAIBaseFeaturesView::FeatureCacheSetAt(const int flatIdx, const double v)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureCacheSetAt(flatIdx, v); }
|
2026-08-25 22:51:50 -04:00
|
|
|
void CAIBaseFeaturesView::FeatureCacheSetBlock(const int base, const int count, const double &values[])
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureCacheSetBlock(base, count, values); }
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
void CAIBaseFeaturesView::FeatureCacheMarkStored(const int idx)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureCacheMarkStored(idx); }
|
|
|
|
|
void CAIBaseFeaturesView::FeatureCacheInvalidateAll(void)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureCacheInvalidateAll(); }
|
2026-08-25 22:51:50 -04:00
|
|
|
void CAIBaseFeaturesView::LabelCacheInvalidateAll(void)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.LabelCacheInvalidateAll(); }
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
|
|
|
|
|
void CAIBaseFeaturesView::SetFailBlock(const string block)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureSetFailBlock(block); }
|
|
|
|
|
void CAIBaseFeaturesView::SetFailIdx(const int idx)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureSetFailIdx(idx); }
|
|
|
|
|
void CAIBaseFeaturesView::SetWindowFail(const int slot, const int total)
|
|
|
|
|
{ if(CheckPointer(m_owner) != POINTER_INVALID) m_owner.FeatureSetWindowFail(slot, total); }
|
|
|
|
|
|
|
|
|
|
CArrayDouble *CAIBaseFeaturesView::TempData(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.DataTempData() : NULL; }
|
refactor(features): FeatureBuilder is a real collaborator, not a raw-include partial
Expert/AIBase/Features.mqh (2017 lines, 38 methods) split by exclusivity grep
(whole-repo, not just Expert/): 30 methods -> Expert/Features/FeatureBuilder.mqh
(CFeatureBuilder + CFeaturesView/CAIBaseFeaturesView), 8 stay behind as a much
smaller raw partial.
CFeatureBuilder is STATEFUL, same shape as Excursion/OnlineLearning: owns the
10 feature-only indicator handles (m_Volumes/m_MA/m_RSI/m_MACDFeature/
m_Ichimoku/5 AD* CiCustom indicators - grep-verified touched nowhere else in
the repo, only their bare declarations) plus the depth-probe/handle-repair/
spread-series/detectability-latch scalars (exclusive, Lifecycle.mqh ctor-init
only elsewhere). m_Open/m_Close/m_High/m_Low/m_Time/m_ATR/m_ADZigZag stay
signal-owned - Labels.mqh/AutoTune.mqh/Training.mqh read them directly - and
are reached read-only through the view (FeatureOpenAt/FeatureHighAt/
FeatureLowAt/ChartBarClose/ChartBarTime/OnlineAtrMain, all reused where a
forward already existed).
Deliberately did NOT move InitOpen/InitClose/InitHigh/InitLow/InitTime/
InitADZigZag/ResizeBuffers/RefreshData: they manage the 7 shared indicators'
Create/BufferResize/Refresh lifecycle, which would need a pure-relay wrapper
per operation per indicator for zero coupling benefit - same judgment as
Topology's boot sequence. They stay in Expert/AIBase/Features.mqh and reach
CFeatureBuilder's 10 owned indicators through 20 new Feature*BufferResize()/
Feature*Refresh() forwards (signal calling into its own owned collaborator
directly, no view needed in that direction).
Whole-repo grep (not just Expert/) caught a real external miss the campaign's
own doctrine warns about: Signals/SignalMETA.mqh read m_spreadSeries/
m_spreadSeriesBars directly as an inherited protected field (a subclass, not
an AIBase/*.mqh partial) - fixed with two new FeatureSpreadSeriesBars()/
FeatureSpreadSeriesAt() forwards.
Verified: if(/for(/while( counts identical between the original file and the
new split (269/20/1); return-count delta (+12) fully accounted for by the 12
new trivial one-line forwards added (10 indicator BufferResize + 2 spread-
series getters); quoted-string-literal diff empty except two doc-comment
paraphrases. Self-compiled 0 errors, 0 warnings.
2026-08-24 00:00:31 -04:00
|
|
|
#endif // WARRIOR_FEATURES_AIBASEFEATURESVIEWIMPL_MQH
|
|
|
|
|
//+------------------------------------------------------------------+
|