Warrior_EA/Signals/SignalHYBRID.mqh
AnimateDread 4eae763849 fix(ai): report the metric actually compared; surface the derived front-end
The plateau/regression line printed balancedOosEra as the current value while
comparing against m_bestBalancedOos, which has held the SELECTION score since
a142749. Two different metrics in one sentence, so HYBRID logged "regressed
from best 14.4% to 34.0%" a hundred times - a regression to a higher number,
which is not a thing. The comparison itself was right (selectionScore, coverage
weighted, genuinely below best); only the print was wrong. 1039ad9 relabelled
these strings but missed that this site passes the wrong variable.

The startup config line had the same shape of gap: it printed the dense taper
and called itself self-verifying while the DERIVED conv and recurrent stages -
the ones that dominate CONV/LSTM/HYBRID - were invisible. It now shows the
width into and out of each front-end stage, and flags the case where the dense
stack is wider than the vector reaching it (a linear fan-out cannot recover
what the bottleneck discarded; it only adds parameters). Flagged, not silently
reshaped - that would re-key trained topologies mid-comparison.

UsesConvStage()/UsesLstmStage() replace HasConvBeforeLstm() as the primitive,
so each subclass declares its composition once and both the capacity budget and
the config line derive from it rather than restating it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 15:20:30 -04:00

63 行
无行尾
3.6 KiB
MQL5

//+------------------------------------------------------------------+
//| Warrior_EA |
//| AnimateDread |
//| |
//+------------------------------------------------------------------+
#include "..\Expert\ExpertSignalAIBase.mqh"
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Signals of indicator 'CNN-LSTM AI' |
//| Type=SignalAdvanced |
//| Name=CNN-LSTM AI |
//| ShortName=HYB |
//| Class=CSignalHYBRID |
//| Page=signal_hybrid |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSignalHYBRID. |
//| Purpose: a single fused CNN-LSTM signal that stacks Conv+Pool |
//| layers before the LSTM layer, then the shared dense taper. |
//| The base AI voting path still applies, so this module trades as |
//| one coherent signal instead of three loosely synchronized ones. |
//+------------------------------------------------------------------+
class CSignalHYBRID : public CExpertSignalAIBase
{
protected:
virtual bool AddCustomLayers(CArrayObj *topology) override;
//--- AddCustomLayers below appends BOTH stages, conv first - so this topology's LSTM is fed the conv
//--- feature map rather than the raw input. Keep these in step with AddCustomLayers: they are what let
//--- the capacity budget size the recurrent block against its REAL fan-in (see LstmFanIn()).
virtual bool UsesConvStage(void) const override { return true; }
virtual bool UsesLstmStage(void) const override { return true; }
virtual ENUM_ACTIVATION HiddenLayerActivation(void) override { return TANH; }
public:
CSignalHYBRID(void);
virtual bool InitIndicators(CIndicators *indicators) override;
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSignalHYBRID::CSignalHYBRID(void)
{
SetIdentity("Hybrid", "HYB");
}
//+------------------------------------------------------------------+
//| Create indicators and bootstrap/load the network. |
//+------------------------------------------------------------------+
bool CSignalHYBRID::InitIndicators(CIndicators *indicators)
{
return InitNeuralNetwork(indicators);
}
//+------------------------------------------------------------------+
//| Conv + Pool front-end followed by an LSTM sequence layer. This |
//| matches the standalone CONV front-end exactly, then adds LSTM. |
//+------------------------------------------------------------------+
bool CSignalHYBRID::AddCustomLayers(CArrayObj *topology)
{
//--- "the standalone CONV front-end exactly, then adds LSTM" is now enforced by construction:
//--- both stages are the same code CSignalCONV and CSignalLSTM run.
return AddConvStage(topology) && AddLstmStage(topology);
}
//+------------------------------------------------------------------+