//+------------------------------------------------------------------+ //| Warrior_EA | //| AnimateDread | //| | //| Indicator lifecycle for the price/time/ATR/ZigZag series that | //| stay signal-owned - genuinely shared with Labels.mqh/AutoTune.mqh/| //| Training.mqh, which read them directly, so their Create/ | //| BufferResize/Refresh lifecycle would need a pure-relay wrapper per| //| operation per indicator to move with no coupling benefit (same | //| judgment as Topology.mqh's InitNeuralNetwork boot sequence). The | //| per-bar input feature vector, the 10 feature-only indicator | //| handles and everything else that used to live here is now in | //| Expert\Features\FeatureBuilder.mqh (CFeatureBuilder, m_featureBuilder). | //| ResizeBuffers()/RefreshData() size/refresh CFeatureBuilder's owned| //| indicators too, through the Feature*BufferResize()/Feature*Refresh() | //| forwards it publishes for exactly that purpose. | //+------------------------------------------------------------------+ #ifndef WARRIOR_AIBASE_FEATURES_MQH #define WARRIOR_AIBASE_FEATURES_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::ResizeBuffers(int barIndex) { //--- barIndex for all four now. The Ichimoku feature was the only consumer reaching further back //--- than the rest (its Chikou term read m_Close at idx + ichiKijun); it was removed 2026-08-24, //--- so the close series no longer needs the extra depth. if(!m_Open.BufferResize(barIndex) || !m_Close.BufferResize(barIndex) || !m_High.BufferResize(barIndex) || !m_Low.BufferResize(barIndex)) return false; if(m_useVolumes) { if(!FeatureVolumesBufferResize(barIndex)) return false; } // Unconditional - see InitTime()'s call site in InitIndicators() for why m_Time must always be live. if(!m_Time.BufferResize(barIndex)) return false; if(m_useMA) { //--- NOT barIndex + 1, though the MA block does read GetData(idx) AND GetData(idx + 1) for //--- its bar-over-bar change. The read at the OLDEST bar is SUPPOSED to fail: there is no //--- older bar to difference against. if(!FeatureMaBufferResize(barIndex)) return false; } // Unconditional (not gated by m_useATR): the ATR-normalization in BufferTempData() reads // m_ATR.Main() regardless of whether ATR is enabled as an explicit extra input feature - // m_useATR only controls that feature-count opt-in (see InitIndicators()'s "already init in the // base class" comment), not whether ATR data itself needs to be kept live. if(!m_ATR.BufferResize(barIndex)) return false; // Unconditional, same reasoning as m_ATR above - m_zigZag drives the swing-context features AND // ComputeBarrierHorizonBars()'s measurement, not an opt-in feature, so it's never gated by an // m_use* flag. (It was also the training-label source until the 2026-08-01 triple-barrier relabel.) if(!m_zigZag.BufferResize(barIndex)) return false; return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::RefreshData() { //--- CSeries/CIndicator::Refresh() is void - there is no per-call success/failure signal to //--- propagate here. m_Open.Refresh(OBJ_ALL_PERIODS); m_Close.Refresh(OBJ_ALL_PERIODS); m_High.Refresh(OBJ_ALL_PERIODS); m_Low.Refresh(OBJ_ALL_PERIODS); if(m_useVolumes) { FeatureVolumesRefresh(); } // Unconditional - see InitTime()'s call site in InitIndicators() for why m_Time must always be live. m_Time.Refresh(OBJ_ALL_PERIODS); if(m_useMA) { FeatureMaRefresh(); } // Unconditional - see the matching BufferResize() comment above. m_ATR.Refresh(OBJ_ALL_PERIODS); m_zigZag.Refresh(OBJ_ALL_PERIODS); return true; } //+------------------------------------------------------------------+ //| Initialize Open indicators. | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::InitOpen(CIndicators * indicators) { //--- check pointer if(indicators == NULL) return (false); //--- add object to collection if(!indicators.Add(GetPointer(m_Open))) { printf(__FUNCTION__ + ": error adding object"); return (false); } //--- initialize object if(!m_Open.Create(m_symbol.Name(), m_period)) { printf(__FUNCTION__ + ": error initializing object"); return (false); } //--- ok return (true); } //+------------------------------------------------------------------+ //| Initialize Close indicators. | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::InitClose(CIndicators * indicators) { //--- check pointer if(indicators == NULL) return (false); //--- add object to collection if(!indicators.Add(GetPointer(m_Close))) { printf(__FUNCTION__ + ": error adding object"); return (false); } //--- initialize object if(!m_Close.Create(m_symbol.Name(), m_period)) { printf(__FUNCTION__ + ": error initializing object"); return (false); } //--- ok return (true); } //+------------------------------------------------------------------+ //| Initialize High indicators. | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::InitHigh(CIndicators * indicators) { //--- check pointer if(indicators == NULL) return (false); //--- add object to collection if(!indicators.Add(GetPointer(m_High))) { printf(__FUNCTION__ + ": error adding object"); return (false); } //--- initialize object if(!m_High.Create(m_symbol.Name(), m_period)) { printf(__FUNCTION__ + ": error initializing object"); return (false); } //--- ok return (true); } //+------------------------------------------------------------------+ //| Initialize Low indicators. | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::InitLow(CIndicators * indicators) { //--- check pointer if(indicators == NULL) return (false); //--- add object to collection if(!indicators.Add(GetPointer(m_Low))) { printf(__FUNCTION__ + ": error adding object"); return (false); } //--- initialize object if(!m_Low.Create(m_symbol.Name(), m_period)) { printf(__FUNCTION__ + ": error initializing object"); return (false); } //--- ok return (true); } //+------------------------------------------------------------------+ //| Initialize Time indicators. | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::InitTime(CIndicators * indicators) { //--- check pointer if(indicators == NULL) return (false); //--- add object to collection if(!indicators.Add(GetPointer(m_Time))) { printf(__FUNCTION__ + ": error adding object"); return (false); } //--- initialize object if(!m_Time.Create(m_symbol.Name(), m_period)) { printf(__FUNCTION__ + ": error initializing object"); return (false); } //--- ok return (true); } //+------------------------------------------------------------------+ //| Initialize the ZigZag - the training-label source (see | //| m_zigZag's declaration comment). Always run at its stock | //| defaults (Depth=12, Deviation=5, Backstep=3) - unlike the AD* | //| feature indicators above, this has no tunable-param struct and is | //| never touched by AutoTuneIndicators. | //+------------------------------------------------------------------+ bool CExpertSignalAIBase::InitZigZag(CIndicators * indicators, bool addToCollection) { //--- check pointer if(indicators == NULL) return (false); //--- add object to collection if(addToCollection && !indicators.Add(GetPointer(m_zigZag))) { printf(__FUNCTION__ + ": error adding object"); return (false); } //--- params[1..] mirror ZigZag.mq5's own input order exactly - stock defaults, intentionally not //--- sourced from a tunable params struct (see this function's declaration comment) MqlParam params[4]; params[0].type = TYPE_STRING; params[0].string_value = WARRIOR_STOCK_ZIGZAG; params[1].type = TYPE_INT; params[1].integer_value = 12; // InpDepth params[2].type = TYPE_INT; params[2].integer_value = 5; // InpDeviation params[3].type = TYPE_INT; params[3].integer_value = 3; // InpBackstep if(!m_zigZag.Create(m_symbol.Name(), m_period, IND_CUSTOM, 4, params)) { printf(__FUNCTION__ + ": error initializing object"); return (false); } // Must match ZigZag.mq5's #property indicator_buffers exactly (3: main ZigZag buffer + 2 // internal INDICATOR_CALCULATIONS buffers), even though only buffer 0 is ever read via // GetData() - see the working AD Wyckoff indicators' InitAD*() for the same pattern. m_zigZag.NumBuffers(3); //--- ok return (true); } #endif // WARRIOR_AIBASE_FEATURES_MQH