//+------------------------------------------------------------------+ //| Warrior_EA | //| AnimateDread | //| | //+------------------------------------------------------------------+ #include "..\Expert\ExpertSignalAIBase.mqh" // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Signals of indicator 'LSTM AI' | //| Type=SignalAdvanced | //| Name=LSTM AI | //| ShortName=LSTM | //| Class=CSignalLSTM | //| Page=signal_lstm | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CSignalLSTM. | //| Purpose: Class of generator of trade signals based on | //| the 'LSTM AI' indicator. | //| Is derived from the CExpertSignalAIBase class. | //| Only the network topology differs from the other AI signals: an | //| input layer feeds a single LSTM layer before the common tapering | //| hidden-layer stack (see AddCustomLayers). | //+------------------------------------------------------------------+ class CSignalLSTM : public CExpertSignalAIBase { protected: virtual bool AddCustomLayers(CArrayObj *topology) override; //--- keep the tapering Dense stack TANH-bounded, matching the LSTM layer's own bounded //--- output, instead of the base class's default PRELU (see the base declaration's comment) virtual ENUM_ACTIVATION HiddenLayerActivation(void) override { return TANH; } public: CSignalLSTM(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators) override; }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CSignalLSTM::CSignalLSTM(void) { SetIdentity("Recurrent", "LSTM"); } //+------------------------------------------------------------------+ //| Create indicators and bootstrap/load the network. | //+------------------------------------------------------------------+ bool CSignalLSTM::InitIndicators(CIndicators *indicators) { return InitNeuralNetwork(indicators); } //+------------------------------------------------------------------+ //| LSTM layer inserted between the input layer and the common | //| tapering hidden-layer stack. | //+------------------------------------------------------------------+ bool CSignalLSTM::AddCustomLayers(CArrayObj *topology) { CLayerDescription *desc = new CLayerDescription(); if(CheckPointer(desc) == POINTER_INVALID) return false; desc.count = m_hiddenLayersCount; desc.type = defNeuronLSTM; desc.activation = TANH; //--- CNeuronLSTMOCL now has an accelerated SGD+momentum kernel (LSTM_UpdateWeightsMomentum, //--- AI\Network.mqh/Network.cl/DirectML\WarriorCPU.cpp/WarriorDML.cpp) alongside the original //--- Adam one, so this layer honors the same TrainingOptimizer input as PAI/CONV - see //--- m_optimizationAlgo's declaration comment in ExpertSignalAIBase.mqh. desc.optimization = (ENUM_OPTIMIZATION)m_optimizationAlgo; desc.window = (int)m_historyBars * m_neuronsCount; desc.step = (int)m_historyBars / 2; return topology.Add(desc); } //+------------------------------------------------------------------+