# MQL5 Synthetic Test Harness A lightweight, deterministic synthetic testing and mocking engine for MetaTrader 5 (MQL5) using Dependency Injection (DI), Mocking, and Event-Driven Architecture. > **Part 1 of the Institutional Architecture for MQL5 Series.** --- > [!NOTE] > **Version & Branch Notice:** > - **Tag `v1.0.0-article` / Branch `article-version`**: Contains the exact code and state published in the original MQL5 community article. Use this release/tag if you are following the article step-by-step. > - **`main`**: The active development branch containing the latest updates, ongoing enhancements, bug fixes, and architectural improvements beyond the published article. --- ## Overview Backtesting and live forward-testing alone cannot reliably test edge cases such as spread spikes, latency bursts, order rejections, and broker disconnections under controlled conditions. **MQL5-SyntheticTestHarness** introduces software engineering best practices to MQL5: - **Dependency Injection (DI)**: Decouples trading logic from the native terminal runtime. - **Mock Environment**: Deterministic tick generation and controllable market state injection. - **On-Chart Telemetry**: Real-time HUD and visualizer powered by `CCanvas` for test progress, metrics, and assertion verdicts. - **Fail-Fast & Zero Cost**: Run comprehensive unit and scenario tests inside MetaTrader 5 in milliseconds. --- ## Architecture & Components ``` MQL5/ ├── Include/ │ └── SyntheticTestHarness/ │ ├── IMarketEnvironment.mqh # Market data & terminal state abstraction interface │ ├── ITickProvider.mqh # Interface for streaming and replaying ticks │ ├── CLiveEnvironment.mqh # Production implementation wrapping native MQL5 calls │ ├── CSyntheticEngine.mqh # Dual-mode synthetic mock (tick simulation + behavior injection) │ ├── MockPositionStore.mqh # In-memory mock store for open positions and trade deal history │ ├── BehaviorDelegates.mqh # Function pointer delegates for dynamic behavior injection │ ├── BehaviorLibrary.mqh # Pre-built chaos engineering behaviors (requotes, disconnects) │ ├── CArrayProvider.mqh # In-memory tick provider for deterministic test vectors │ ├── MockTick.mqh # Synthetic tick builder & data structures │ ├── CCanvasVisualizer.mqh # On-chart HUD / graphical assertion dashboard │ ├── CAssert.mqh # Centralized, reusable assertion framework & test reporter │ └── ErrorCodes.mqh # Harness-specific status and error definitions └── Scripts/ └── SyntheticTestHarness/ ├── TestSpreadSpike.mq5 # Executable scenario demonstrating spread spike tests └── TestBehaviorInjection.mq5 # TDD runner demonstrating behavior injection and hot-swapping ``` --- ## Installation & Setup ### Option 1: Automatic Setup via Symlinks (Recommended) We provide a PowerShell script to symlink this repository directly into your MetaTrader 5 Data Folder. Changes in this repository will instantly reflect in MetaEditor/MT5 without manual copying. 1. Open PowerShell (run as Administrator if Windows Developer Mode is disabled). 2. Execute: ```powershell .\Install-Symlinks.ps1 -Mt5DataFolder "C:\Users\\AppData\Roaming\MetaQuotes\Terminal\" ``` *(Find your path in MT5 via **File -> Open Data Folder**)*. ### Option 2: Manual Copy Copy the `MQL5/` directory directly into your MetaTrader 5 Data Folder: - `MQL5/Include/SyntheticTestHarness/` → `/MQL5/Include/SyntheticTestHarness/` - `MQL5/Scripts/SyntheticTestHarness/` → `/MQL5/Scripts/SyntheticTestHarness/` --- ## Running the Tests 1. Open **MetaEditor** (`F4` in MT5). 2. In the Navigator, browse to `Scripts/SyntheticTestHarness/` and open either: - `TestSpreadSpike.mq5` (Deterministic tick replay test suite) - `TestBehaviorInjection.mq5` (Dynamic behavior injection and Chaos Engineering test suite) 3. Press **Compile** (`F7`). 4. In **MetaTrader 5**, drag the compiled script onto any active chart. 5. Observe the test assertions, retcodes, and summary dashboard. --- ## Changelog (Since Article Version) All notable changes and enhancements introduced after the baseline publication (`article-version`) will be documented here #### Added - **Mock Position & Deal History Store (`MockPositionStore.mqh`)**: In-memory state storage (`SMockPosition`, `SMockDeal`, `CMockPositionStore`) enabling deterministic testing of position lifecycles, exposure tracking, and daily PnL history without an active broker connection. - **Terminal State Bridge (`IMarketEnvironment.mqh`)**: Extended interface with generic bridge methods matching native MT5 signatures for Account (`AccountInfo*`), Symbol (`SymbolInfo*`), Open Positions (`Position*`), and Deal History (`History*`). - **Reusable Assertion Framework (`CAssert.mqh`)**: Centralized self-validating assertions (`AssertTrue`, `AssertFalse`, `AssertEqual`, `AssertIntEqual`, `AssertUintEqual`, etc.) and automated test suite reporting (`CAssert::Summary`). - **Behavior Injection (`BehaviorDelegates.mqh`)**: Typedef function pointer delegates enabling dynamic, runtime behavior mocking without mock frameworks. - **Chaos Behavior Library (`BehaviorLibrary.mqh`)**: Stateful and fault-injection mock implementations including `Behavior_RequoteTwice` and `Behavior_FatalDisconnect`. - **TDD Behavior Test Suite (`TestBehaviorInjection.mq5`)**: Test runner validating AAA pattern, stateful retries, hot-swapping, and behavior resetting. - **DOM Abstraction**: Added `MarketBookGet` to `IMarketEnvironment`, `CSyntheticEngine`, and `CLiveEnvironment`. - **Architecture Record (`ADR-003`)**: Documented the rationale for behavior injection via function pointers in MQL5. #### Changed - **`CSyntheticEngine` & `CLiveEnvironment`**: Implemented the full terminal state bridge, allowing synthetic engines to mock symbol specifications, balance, equity, and position stores seamlessly while live environments delegate directly to native MT5 calls. - **Test Scripts**: Refactored `TestSpreadSpike.mq5` and `TestBehaviorInjection.mq5` to eliminate code duplication by adopting `CAssert.mqh`. - **`IMarketEnvironment`**: Renamed `TryExecuteOrder` to `OrderSend` for 1:1 parity with the native MT5 terminal API. - **`CSyntheticEngine`**: Upgraded into a dual-mode engine supporting both tick-driven simulation and priority behavior injection. - **`CLiveEnvironment`**: Explicitly scoped all native MT5 API calls with the global scope resolution operator (`::`). - **`TestSpreadSpike.mq5`**: Updated invocation call sites to `OrderSend`. --- ## License This project is open-source under the [MIT License](LICENSE).