- Moves CLayer neuron construction to AI/Impl/Layer.mqh to keep Network.mqh clean - Unifies four previously duplicated architecture initialisation blocks (MLP/CONV/LSTM/HYBRID) into a single shared function - Eliminates risk of behavioural drift where one architecture missed a setter, causing mismatched feature sets or targets
5.7 KiB
AI/ — neural network subsystem
The engine behind the four AI signal modules (CSignalPAI, CSignalCONV,
CSignalLSTM, CSignalHYBRID). It is a from-scratch MQL5 network — no external
ML runtime — with four interchangeable compute tiers behind one interface.
File layout
AI\Network.mqh is the entry point and the only file anything outside AI\
includes. It holds declarations only: the nine core classes, the compile-time
constants, and the nested include chain that orders them. Each nested #include
sits exactly where its base class becomes visible, so that order is a dependency
graph, not a preference — do not reorder it.
| file | holds |
|---|---|
Network.mqh |
class declarations, tuning constants, include chain |
Network.cl |
OpenCL kernels (see below) |
NeuronPrimitives.mqh |
CConnection / CArrayCon — weight storage |
NeuronCPU.mqh |
CNeuron — pure-MQL5 dense neuron |
NeuronDirectML.mqh |
CDirectMLMy — DirectML + CPU-DLL bridge (#imported DLLs) |
ArrayLayer.mqh |
CArrayLayer — the layer collection |
LayerDescription.mqh |
CLayerDescription — the topology descriptor |
BufferDouble.mqh |
CBufferDouble — host/device buffer |
NeuronOCLConvPool.mqh |
CNeuronConvOCL, CNeuronPoolOCL |
NeuronBatchNorm.mqh |
CNeuronBatchNormOCL — host-side batch norm, all tiers |
Method bodies live in AI\Impl\, included at the bottom of Network.mqh
after every declaration. This is a pure relocation — a body cannot run during
compilation, and every declaration it could reference is already visible above it.
AI\Impl\ |
holds |
|---|---|
NeuronBase.mqh |
CNeuronBase — init, forward, gradients, activation, persistence |
NeuronConvPool.mqh |
CNeuronConv, CNeuronPool |
NeuronLSTM.mqh |
CNeuronLSTM — gate layers, BPTT |
Layer.mqh |
CLayer — element construction from a descriptor or a .nnw stream |
NetBuild.mqh |
CNet lifecycle: topology construction, OpenCL/DirectML init |
NetForward.mqh |
feedForward, backProp, getResults, logit adjustment |
NetPersistence.mqh |
CNet::Save / CNet::Load — the .nnw format |
NetWeights.mqh |
EMA blend, in-memory snapshot/restore, per-layer learning report |
NeuronOCLBase.mqh |
CNeuronBaseOCL |
NeuronOCLLSTM.mqh |
CNeuronLSTMOCL — sequence LSTM, fused kernels, BPTT caches |
Compute tiers
Selected once at construction and logged; each layer runs entirely on one tier.
- OpenCL —
Network.cl, compiled from the#resourceat startup. - DirectML —
WarriorDML.dll(D3D12 compute). - CPU DLL —
WarriorCPU.dll, a threaded fallback. Thread count is fixed atCPU_THREADS_PER_NETWORKper net rather than a share of the machine; see the comment on that constant for why a machine-wide budget was wrong. - Pure MQL5 — no DLL, no GPU. Single backtests run here so a Market build
(which strips every
#import) is still able to infer.
A Market build (WARRIOR_MARKET_BUILD) compiles tiers 2 and 3 out entirely.
Classes
CNet— owns the layer stack, the forward/backward passes and.nnwpersistence. Note that a.nnwpins the architecture, not just the weights:Savewrites each layer's activation andLoadrestores it, so a head activation changed in source only ever reaches a brand-new topology.EnforceOutputActivation()re-asserts it after every load.CLayer/CArrayLayer— neuron containers;CreateElementScaled()is the single construction point for every neuron type, from a descriptor or from a file stream.CNeuronBase→CNeuron/CNeuronPool/CNeuronConv/CNeuronLSTM— the pure-MQL5 family.CNeuronBaseOCL→CNeuronLSTMOCL/CNeuronConvOCL/CNeuronPoolOCL/CNeuronBatchNormOCL— the accelerated family. Despite theOCLsuffix these also drive the DirectML and CPU-DLL tiers.
ENUM_ACTIVATION is NONE, TANH, SIGMOID, PRELU; ENUM_OPTIMIZATION is
SGD, ADAM. NativeActivationCode() translates to the int code the backends
share — and deliberately makes NONE fall through every backend switch.
Network.cl
22 kernels in four groups: dense (FeedForward, CaclOutputGradient,
CaclHiddenGradient, UpdateWeightsMomentum/Adam), conv/pool (FeedForwardConv,
FeedForwardProof, CalcHiddenGradientConv, CalcInputGradientProof,
UpdateWeightsConv*), single-step LSTM (LSTM_Gates, LSTM_State,
LSTM_*Gradient) and sequence LSTM (LSTM_SeqStep*, LSTM_UpdateWeights*).
Two invariants worth knowing before touching them:
MIN_ACTIVATION_DERIVATIVE(1.0e-3f) floors every LSTM gate derivative in both gradient kernels. It is already there — do not "add" it.- Kernel math is mirrored in
DirectML\WarriorCPU.cppandWarriorDML.cpp. A change to one is a change to all three, or the tiers silently diverge.
Usage
CNet *net = new CNet(topology); // CArrayObj of CLayerDescription
net.feedForward(inputs); // CArrayDouble
net.backProp(targets, weight);
net.getResults(out);
net.Save(path, ...); net.Load(path, ...);
The 3-output classification case is special-cased in backProp/backPropOCL:
it computes a joint softmax + cross-entropy gradient across all three neurons
rather than three independent per-neuron deltas.
Known gaps
- No unit tests. Changes are validated by compile + a live era's
dW/Wline (CNet::LayerLearningReport), which is the only reliable check that a layer is actually receiving gradient in the assembled net. - No dedicated SoftMax layer; the head is
Dense(SIGMOID)with the gradient short-circuited. SeeREFACTOR_NOTES.md§G for why, and for what would have to move together to change it.