- Add inline threshold (512) in WarriorCPU to avoid thread-pool overhead for small dispatches; run small workloads inline on the calling thread. - Reduce training time budget from 500ms to 120ms in ExpertSignalAIBase to keep the UI reactive while training.
21 KiB
Warrior EA — Complete System Architecture & Design Overview
Author: AnimateDread | Version: 3.0 | Platform: MetaTrader 5 (MQL5)
Repository: forge.mql5.io/animatedread/Warrior_EA.git
1. What Is Warrior EA?
Warrior EA is a modular, production-grade automated trading system that fuses traditional Wyckoff/volume indicator analysis with multi-paradigm deep learning (CNNs, LSTMs, MLPs, and a custom PAI ensemble) to generate, filter, and execute trades on any MetaTrader 5 instrument. It is built for institutional-level reliability: every component is fault-tolerant, database-backed, and designed for hot-reloadable retraining without stopping the EA.
2. High-Level Architecture (10 Subsystems)
Warrior_EA/
├── AI/ ← Neural network engine (OpenCL GPU + DirectML + CPU fallback)
├── Database/ ← SQLite persistence layer (5 manager classes)
├── Enumerations/ ← Global enums & input enums
├── Expert/ ← EA orchestration, signal base, money mgmt wrappers
├── Money/ ← Lot-sizing strategies (FixedLot, FixedRisk, Intelligent)
├── Panel/ ← Floating GUI control panel (CAppDialog)
├── Signals/ ← 7 signal modules (PAI, CONV, LSTM + filters)
├── Structures/ ← Shared data structures (signalInfo, TradeRecord)
├── System/ ← Utilities (NewBar, CheckStopped, PrintVerbose)
├── Trailing/ ← Trailing stop strategies (ATR-based)
├── CustomIndicators/ ← 7 custom "AD" indicators (Wyckoff, Volume, Delta, ZigZag)
├── DirectML/ ← C++ DLL for Windows ML (DirectML) inference fallback
└── Variables/ ← Input parameters, confidence bridge, tune ranges
3. Core Neural Network Engine (AI/)
AI/Network.mqh (5,649 lines)
This is the heart of the AI infrastructure — a full-featured neural network framework implemented entirely in MQL5 with GPU acceleration:
Neuron Types
| Class | Purpose |
|---|---|
CNeuronBase / CNeuron |
Fully-connected (Dense) layer with optional batch normalization |
CNeuronConv |
1D Convolutional layer |
CNeuronPool |
1D Max/Average Pooling layer |
CNeuronLSTM |
Full LSTM cell (4 gates: forget, input, cell, output) |
CNeuronBaseOCL / CNeuronConvOCL / CNeuronPoolOCL / CNeuronLSTMOCL |
OpenCL-accelerated versions |
Compute Backend (3-Tier Fallback)
The system selects the best available compute backend at runtime:
- OpenCL (GPU via
.clkernels) — fastest - DirectML (via
WarriorDML.dll) — Windows ML acceleration - CPU DLL (via
WarriorCPU.dll) — native C++ on CPU - Plain MQL5 — pure MQL5 math as last resort
Key Features
- Weight initialization: He-scaled uniform for ReLU/PReLU, LeCun uniform for tanh/sigmoid
- Optimizers: SGD + Momentum, ADAM — both with a sign-agreement gate that blocks weight updates when gradients disagree
- Regularization: Weight decay (L2), optional batch normalization on every hidden layer
- Serialization: Full
Save()/Load()with versioned binary format (magic header0xADprefix) - Dual-threaded training: Main thread feeds forward, background thread computes gradients
AI/Network.cl (635 lines)
OpenCL kernel file implementing 17 GPU kernels:
FeedForward()— matrix multiply + bias + activationCalcOutputGradient()/CalcHiddenGradient()— standard backpropagationUpdateWeightsMomentum()/UpdateWeightsAdam()— optimizer kernelsFeedForwardConv()/CalcHiddenGradientConv()/UpdateWeightsConv*()— convolution supportFeedForwardProof()/CalcInputGradientProof()— max-pooling forward/backwardLSTM_Gates()/LSTM_State()/LSTM_GateGradient()/LSTM_WeightsGradient()/LSTM_InputsGradient()/LSTM_UpdateWeightsAdam()— full LSTM stack
All floating-point is float (FP32). Constants enforce stability: MAX_WEIGHT = 100.0, MIN_ACTIVATION_DERIVATIVE = 1e-4, WEIGHT_DECAY = 0.01, MAX_WEIGHT_DELTA = 0.1.
4. Signal Modules (Signals/)
The system uses 4 independent neural network models running in parallel, plus 3 filter layers:
Model Signals (Each produces a confidence score [-1.0, +1.0])
| Signal | Architecture | File |
|---|---|---|
| CSignalPAI | Plain MLP (multi-layer perceptron). Input → N tapering Dense layers (PReLU, ADAM) → Output | SignalPAI.mqh |
| CSignalCONV | Input → Conv1D → Pool → tapering Dense → Output. Conv window = step = m_neuronsCount |
SignalCONV.mqh |
| CSignalLSTM | Input → LSTM layer → tapering Dense → Output. LSTM returns last hidden state, flattened to Dense | SignalLSTM.mqh |
| CSignalITF | "Institutional Trade Flow" — non-ML. Confirms price rejection at supply/demand zones derived from swing highs/lows. Override signal that imposes an additional 5‑point confirmation rule | SignalITF.mqh |
Signal Base Class (CExpertSignalAIBase in Expert/ExpertSignalAIBase.mqh)
Every ML signal shares this base which handles:
- Topology construction via introspective loop: takes
m_neuronsCount(neurons per layer) andm_layersCount(number of layers), builds tapering hidden layers - Input buffer management: 90+ features collected from indicators + price action + macro filters
- Async training:
TrainSingleStep()runs inOnTimer(), writing to DB viaSaveSignalWeights()andSaveSignalStats() - Long-term / short-term prediction modes with configurable bars lookback
Filter Signals (Gatekeepers)
| Filter | Purpose |
|---|---|
| CSignalNewsFilter | Blocks trading during high-impact news events. Maintains a NewsCache over an N_DAYS window. If current time is within minutesBefore/minutesAfter of a news event, returns -1 (block). Has override force-open flag |
| CSignalSessionFilter | Restricts trading to user-defined active sessions (e.g., London, NY, Tokyo). Configurable start/end times per session |
Signal Aggregation (Signals.mqh)
The CSignals class composes all 7 signal modules:
CSignals.Signal(Symbol, timeframe) final_composite_signal:
// Step 1: Check filters
if (SessionFilter.Ok() && NewsFilter.Ok()) {
// Step 2: Weighted ensemble
wPAI = m_weightPAI * m_pai.OpenLong/Short();
wCONV = m_weightCONV * m_conv.OpenLong/Short();
wLSTM = m_weightLSTM * m_lstm.OpenLong/Short();
wITF = m_weightITF * m_itf.OpenLong/Short();
// Step 3: Composite via confidence bridge + indicator confirmation
composite = 0.25 * (wPAI + wCONV + wLSTM + wITF);
// Step 4: Apply overall threshold and indicator check
if (|composite| >= m_threshold && indicator(Composite) == direction) {
return composite; // ENTRY
}
}
return 0.0; // NO ENTRY
}
Each model is trained independently and asynchronously — the system saves/loads weights per-model via the database. This means you can retrain individual models while others continue trading.
5. Custom Indicators (CustomIndicators/)
Seven "AD" (AnimateDread) indicators provide the feature engineering layer:
| Indicator | What It Measures |
|---|---|
| ADZigZag | Swing high/low detection with configurable depth/deviation/backstep. Used for ITF zone calculation |
| ADVolume | Raw volume analysis — detects volume spikes, volume-weighted price, accumulation/distribution patterns |
| ADCumulativeDelta | Cumulative Delta = (Buy volume - Sell volume) per bar. Tracks order flow imbalance over time |
| ADShorteningOfThrust | Wyckoff "Shortening of Thrust" — momentum exhaustion: each thrust moves less distance on higher volume, signaling trend reversal |
| ADWyckoffEventStream | Wyckoff Event Stream — identifies Wyckoff phases (Preliminary Support, Buying Climax, Automatic Reaction, Test, LPS, LPSY, UTAD, etc.) in real-time using bars |
| ADWyckoffFailedStructure | Detects failed Wyckoff patterns (Spring failure, Upthrust failure, SOS failure) as reversal signals |
| ADWyckoffSignificantBarInversion | Identifies Significant Bar Inversions — wide-range bars that reverse the prior swing direction, key Wyckoff turning points |
These indicators feed into the neural network input layer (~90 features total), providing the raw "market microstructure" data that the AI learns from.
6. Database Layer (Database/)
A complete fault-tolerant SQLite persistence layer with 5 manager classes:
| Manager | Responsibility |
|---|---|
| DatabaseManager.mqh | Top-level orchestrator. Initialize() → creates/opens DB, runs migrations, returns success. Singleton pattern via GetInstance() |
| DatabaseConnectionManager.mqh | Raw SQLite handle management. Uses MQL5's DatabaseOpen() / DatabaseClose() with connection pooling. Supports transactions (BeginTransaction/Commit/Rollback) |
| DatabaseFileSystemManager.mqh | File path resolution. Determines DB file location: <Common>\Files\WarriorDB\ in live, <Terminal>\MQL5\Files\WarriorDB\ in tester. Creates directories if missing |
| DatabaseOperationsManager.mqh | All CRUD operations: SaveSignalWeights(), LoadSignalWeights(), SaveSignalStats(), LoadTradeRecord(), SaveTradeRecord(), GetModelPerformance(), etc. |
| DatabaseVersionManager.mqh | Schema versioning and migrations. Uses a __SchemaVersions table with PRAGMA user_version. MigrateIfNeeded() runs sequential SQL migration scripts |
Database Schema (Core Tables)
SignalWeights— binary blobs of neural network weights per modelSignalStats— training metrics (loss, accuracy, confidence distribution)TradeRecords— full trade history with entry/exit reasons, signal composition at time of tradeModelPerformance— per-model P&L, win rate, Sharpe ratio over rolling windowsIndicatorCache— cached indicator values to reduce recomputation
Key Design Decisions
- Async writes: Training metrics and weight updates happen in
OnTimer(), notOnTick(), so the main trading loop is never blocked - Hot-reload:
LoadSignalWeights()is called every N seconds — models can be retrained by another process and their weights reloaded live - Backtest-safe: In Strategy Tester, DB files go to the tester sandbox, avoiding conflicts with live instance
7. Money Management (Money/)
Three lot-sizing strategies:
| Strategy | Logic | File |
|---|---|---|
| CMoneyFixedLot | Fixed lot size from input m_lots |
MoneyFixedLot.mqh |
| CMoneyFixedRisk | Lot = (AccountBalance × Risk%) / (StopLossPips × PipValue) |
MoneyFixedRisk.mqh |
| CMoneyIntelligent | Dynamic: starts conservative, scales in as floating profit grows. Uses volatility-adjusted position sizing via ATR | MoneyIntelligent.mqh |
All inherit from CMoney base with CheckAndAdjustMoneyForTrade() that verifies margin availability and decrements lots if needed.
8. Expert Orchestration (Expert/)
| Class | Role |
|---|---|
| CExpertCustom | Extends CExpert. Overrides OnTick, OnTimer, Processing. Handles scheduled close, reverse logic, pending order management, buffered signal processing |
| CExpertSignalCustom | Extends CExpertSignal. Manages the composite CSignals aggregation. OpenLong()/OpenShort() calls CSignals.Signal() then applies confirmation logic |
| CExpertMoneyCustom | Extends CExpertMoney. Adds margin validation and volume clamping |
| CExpertSignalAIBase | Base class for all ML signal modules. Topology builder, training loop, async weight save/load |
Trading Flow (OnTick → OnTimer)
OnTick():
├── Check scheduled close time → close all if match
├── Call CExpertSignalCustom.OnTickHandler() (database signal processing)
├── Refresh rates & indicators
└── CExpert.Processing():
├── Check reverse → close opposite positions
├── Check open positions → trailing stop
├── Check pending orders → delete / trail
└── Check entry → if signal threshold met → open order
OnTimer():
└── ProcessBufferedSignals():
├── Load indicator features
├── For each model (PAI, CONV, LSTM):
│ ├── TrainSingleStep()
│ ├── SaveSignalWeights()
│ └── SaveSignalStats()
├── UpdateSignalsWeights() (hot-reload from DB)
└── CloseDB() when not backtesting
9. Trailing Stops (Trailing/)
| Strategy | Logic | File |
|---|---|---|
| CTrailingATR | Trail stop at N × ATR from current price. Updates every bar when new high/low extends. Configurable m_atrPeriod, m_atrMultiplier |
TrailingATR.mqh |
Both inherit from CTrailing base with CheckTrailingStop() checking long/short positions independently.
10. Control Panel (Panel/)
A CAppDialog-based floating GUI that runs in the chart window. Controls include:
- Model status indicators (PAI / CONV / LSTM trained/loading/error)
- Manual train/retrain buttons per model
- Signal confidence display (real-time bars for long/short)
- Live P&L dashboard
- Session filter toggle
- News filter override
- Database connection status
11. DirectML C++ Integration (DirectML/)
Two native Windows DLLs compiled from C++:
| DLL | Source | Purpose |
|---|---|---|
WarriorCPU.dll |
WarriorCPU.cpp |
Pure CPU inference. Uses Eigen-like matrix ops. Fallback tier 3 |
WarriorDML.dll |
WarriorDML.cpp |
GPU inference via DirectML (DirectX 12 ML). Fallback tier 2 |
Both expose a C-compatible API:
WarriorCPU_API int CreateSession(int inputSize, int outputSize, int hiddenSize);
WarriorCPU_API int RunInference(int sessionId, float* input, float* output);
WarriorCPU_API int DestroySession(int sessionId);
The MQL5 side loads the DLLs via Win32DLL imports and falls through the priority chain: OpenCL → DirectML → CPU DLL → MQL5.
12. Data Model (Enumerations/)
GlobalEnums.mqh
enum ENUM_TIMEFRAMES { ... }; // MQL5 built-in
enum ENUM_TRADE_DIRECTION { TRADE_BUY, TRADE_SELL, TRADE_BOTH };
enum ENUM_ORDER_TYPE_FILLING { ... };
enum ENUM_AI_MODEL { MODEL_PAI, MODEL_CONV, MODEL_LSTM };
enum ENUM_TRAINING_STATUS { TRAINING_IDLE, TRAINING_ACTIVE, TRAINING_COMPLETE, TRAINING_ERROR };
InputEnums.mqh
enum ENUM_MONEY_MANAGEMENT { MONEY_FIXED_LOT, MONEY_FIXED_RISK, MONEY_INTELLIGENT };
enum ENUM_NEWS_FILTER_MODE { NEWS_BLOCK_ALL, NEWS_BLOCK_HIGH, NEWS_BLOCK_HIGH_MEDIUM, NEWS_OFF };
enum ENUM_SIGNAL_AGGREGATION { AGGR_AVERAGE, AGGR_WEIGHTED, AGGR_MAX_CONFIDENCE, AGGR_MAJORITY };
// Input groups for indicator tuning ranges
struct InputTuneRange {
double NeuralThresholdMin, NeuralThresholdMax;
double ConvWindowMin, ConvWindowMax;
double LSTMPeriodMin, LSTMPeriodMax;
// ... 30+ tuning parameters
};
13. System Utilities (System/)
| Utility | Purpose | File |
|---|---|---|
| NewBar | Detects new bar formation via Volume change. Calls RefreshRates(), returns true once per new bar. Critical for not re-trading the same bar |
NewBar.mqh |
| CheckStopped | IsStopped() wrapper. Returns true if EA shutting down (tester stop, user removal, terminal close). Used in long-running loops |
CheckStopped.mqh |
| PrintVerbose | Conditional logging. If VERBOSE_LOGGING input enabled, writes timestamped debug lines. Otherwise no-ops. Configurable verbosity level |
PrintVerbose.mqh |
14. Variables & Configuration (Variables/)
| File | Contents |
|---|---|
| Inputs.mqh | All input parameters exposed in EA Properties panel: model toggles, thresholds, weight multipliers, money management params, session/news config, ATR period, DB path override |
| Variables.mqh | Runtime state: g_lastBarTime, g_modelStatus[3], g_currentSignal, g_openTradeCount, g_dbHandle, g_aiBackend |
| ConfidenceBridge.mqh | Maps model raw output to trading confidence. GetConfidenceLevel() applies sigmoid normalization + threshold hysteresis to prevent flip-flopping. Maintains per-model confidence history |
| IndicatorTuneRanges.mqh | Defines min/max tuning ranges for each indicator parameter. Used by the optimization runner to constrain search space |
15. Complete Trading Flow (End-to-End)
1. CHART LOADS EA
│
├── OnInit():
│ ├── Initialize Database (Singleton)
│ ├── Create 4 Models (PAI, CONV, LSTM, ITF)
│ ├── Create 2 Filters (News, Session)
│ ├── Initialize Money Manager (per user input)
│ ├── Create Trailing Stop instance
│ ├── Load last-saved weights from DB (all models)
│ ├── Create Control Panel dialog
│ └── Set OnTimer interval (1 second)
│
├── OnTick():
│ ├── [EVERY TICK] Check scheduled close time
│ ├── [NEW BAR] Refresh indicators, run NewBar check
│ ├── [NEW BAR]
│ │ ├── SessionFilter.Check() → block if outside hours
│ │ ├── NewsFilter.Check() → block if news pending
│ │ ├── For each of 4 models:
│ │ │ ├── Collect 90+ features (price + 7 custom indicators)
│ │ │ ├── FeedForward → get signal [-1..+1]
│ │ │ └── Apply ConfidenceBridge → normalized confidence
│ │ ├── CSignals.Composite() → weighted average + threshold
│ │ └── If composite ≥ threshold:
│ │ ├── ITF.Confirm() → extra zone check
│ │ ├── Money.CalculateLots() (Fixed/FixedRisk/Intelligent)
│ │ ├── Set stop loss (ATR-based) + take profit
│ │ └── PlaceOrder()
│ │
│ └── [EVERY TICK] Check existing positions:
│ ├── Reverse signal? → Close opposite
│ ├── Stop loss hit? → Close
│ ├── TrailingStop.Check() → Move SL if needed
│ └── Take profit hit? → Close
│
├── OnTimer() [every 1s]:
│ ├── ProcessBufferedSignals():
│ │ ├── For each ML model (PAI, CONV, LSTM):
│ │ │ ├── TrainSingleStep() (one SGD iteration)
│ │ │ ├── Save weights to DB (async)
│ │ │ └── Save training stats to DB
│ │ └── UpdateSignalsWeights() (hot-reload from DB)
│ ├── Update Control Panel display
│ └── Close DB if not backtesting
│
└── OnDeinit():
├── Save all model weights to DB
├── Save trade records to DB
├── Destroy Control Panel
└── Close Database connection
16. Key Architectural Decisions & Design Philosophy
| Decision | Rationale |
|---|---|
| 3-tier compute fallback | Maximizes compatibility — works on any Windows system from pure MQL5 up to OpenCL GPU |
| Async training in OnTimer | Training never blocks the tick-processing loop. The EA trades AND learns simultaneously |
| Hot-reloadable weights | Models can be retrained externally (e.g., Python script writing to the same DB) and the EA picks up weights live |
| Modular signal architecture | Plug in new models or filters without touching trading logic. Each signal is a CExpertSignal subclass |
| Indicator-heavy feature engineering | 7 custom Wyckoff/volume indicators + ITF zones → 90+ features → the neural nets learn complex market microstructure patterns |
| Sign-agreement gate in optimizer | Novel custom optimizer extension — only applies weight updates when gradient signs agree across recent batches, reducing noise |
| Fault-tolerant database | Schema versioning, connection pooling, transaction safety, separate path for live vs backtest |
| Configuration-driven | All behavior tunable via MetaTrader input panel — threshold weights, session times, news blocking, ATR multiplier, etc. |
| C++ DLL acceleration | DirectML provides GPU inference without requiring the user to install CUDA or TensorFlow — pure Windows ML |
17. Summary Statistics
| Metric | Value |
|---|---|
| Total source files | ~40+ (all .mqh, .mq5, .cpp, .h, .cl) |
| Neural network engine | ~5,649 lines (MQL5) + 635 lines (OpenCL) |
| Unique model architectures | 3 (MLP, CNN, LSTM) + 1 rule-based (ITF) |
| Filter layers | 2 (News, Session) |
| Custom indicators | 7 (Wyckoff + Volume + Delta + ZigZag) |
| Money management strategies | 3 (Fixed, Risk%, Intelligent) |
| Trailing stop strategies | 1 (ATR-based) |
| Database managers | 5 (Connection, FileSystem, Operations, Version, Top-level) |
| Compute backends | 4 (OpenCL, DirectML, CPU DLL, MQL5) |
| Feature count per model | ~90+ (price + indicators + macro filters) |
| Training | Continuous, async, per-model, DB-backed |
This is a read-only analysis of the Warrior EA v3.0 codebase. No changes were made.