//+------------------------------------------------------------------+ //| Warrior_EA | //| AnimateDread | //| | //+------------------------------------------------------------------+ #include "..\Expert\ExpertSignalAIBase.mqh" // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Signals of indicator 'Convolutional AI' | //| Type=SignalAdvanced | //| Name=Convolutional AI | //| ShortName=CONV | //| Class=CSignalCONV | //| Page=signal_conv | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CSignalCONV. | //| Purpose: Class of generator of trade signals based on | //| the 'Convolutional AI Neural Network. | //| Is derived from the CExpertSignalAIBase class. | //| Only the network topology differs from the other AI signals: an | //| input layer feeds a Conv+Pool stage before the common tapering | //| hidden-layer stack (see AddCustomLayers). | //+------------------------------------------------------------------+ class CSignalCONV : public CExpertSignalAIBase { protected: virtual bool AddCustomLayers(CArrayObj *topology) override; public: CSignalCONV(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators) override; }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CSignalCONV::CSignalCONV(void) { SetIdentity("Convolutional", "CONV"); } //+------------------------------------------------------------------+ //| Create indicators and bootstrap/load the network. | //+------------------------------------------------------------------+ bool CSignalCONV::InitIndicators(CIndicators *indicators) { return InitNeuralNetwork(indicators); } //+------------------------------------------------------------------+ //| Conv + Pool layers inserted between the input layer and the | //| common tapering hidden-layer stack. | //+------------------------------------------------------------------+ bool CSignalCONV::AddCustomLayers(CArrayObj *topology) { //--- Convolutional Layer CLayerDescription *desc = new CLayerDescription(); if(CheckPointer(desc) == POINTER_INVALID) return false; desc.count = m_hiddenLayersCount; desc.type = defNeuronConv; // PRELU, not TANH: matches what CNeuronConv's CPU path (Network.mqh) has always hardcoded // regardless of this setting (its activationFunction() override ignores `activation` entirely) - // this used to silently diverge from the GPU/DirectML tier, which DOES honor this field and was // therefore actually running tanh instead of the intended PReLU whenever hardware accel was active. desc.activation = PRELU; desc.optimization = (ENUM_OPTIMIZATION)m_optimizationAlgo; desc.window = m_neuronsCount; desc.step = m_neuronsCount; if(!topology.Add(desc)) return false; //--- Pooling Layer desc = new CLayerDescription(); if(CheckPointer(desc) == POINTER_INVALID) return false; desc.count = m_hiddenLayersCount; desc.type = defNeuronPool; // Unused either way - CNeuronPool::feedForward (CPU) does plain average pooling and never calls // activationFunction() at all, and the GPU FeedForwardProof kernel (max pooling) doesn't even take // an activation argument. NONE documents that accurately instead of implying an activation applies. desc.activation = NONE; desc.optimization = (ENUM_OPTIMIZATION)m_optimizationAlgo; desc.window = 3; desc.step = 2; return topology.Add(desc); } //+------------------------------------------------------------------+