forked from animatedread/Warrior_EA
TARGET_SWING: the direction models learn which way the next CONFIRMED SWING PIVOT lies from the current close. Geometry-free - the label owes nothing to a stop, target or horizon - which is what lets trade management be tuned separately instead of being baked into what the net learns. SwingPivotDirectionLabel reuses the ZigZag pivot the horizon and leg-size measurement already walk, so there is ONE notion of "pivot" in the codebase. It walks forward in time and stops at m_swingConfirmationBars: a pivot nearer than that is still repainting, so its label is not knowable yet and the bar stays Neutral. That boundary is the whole lookahead control for this target. TrainingTarget input is back (TARGET_BARRIER default, unchanged behaviour) with TARGET_FRACTAL and TARGET_SWING beside it; |TGT:SWG1 joins the fingerprint so switching trains a separate model rather than relabelling an existing one. ADZigZag was renamed to ZigZag throughout (30 identifiers). It has loaded MetaTrader's stock Examples\ZigZag at its stock defaults for some time - the migration was done, only the name was left behind, and a name that says "AD" about a stock indicator is exactly the legacy pointer this codebase should not carry. No behaviour change: same #resource, same params. Compile-verified in the staging copy: 0 errors, 0 warnings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
241 lines
9.6 KiB
MQL5
241 lines
9.6 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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
|