Forward-Simulation/Article-22323-Forward-Sim-V1/README.md

231 lines
No EOL
12 KiB
Markdown

# ForwardSimEngine.mq5
## EMA Crossover Forward Simulation Indicator — Synthetic Candles
This repository contains a custom MQL5 indicator built as a forward simulation engine.
It does not claim to reproduce any third-party source code.
All logic is original and derived from the accompanying article series.
---
## Overview
This project implements a chart-native forward projection indicator for MetaTrader 5.
The system detects EMA crossover signals on closed bars and immediately projects a
sequence of synthetic OHLC candles into the future time slots of the chart.
The architecture is built around three independent modules:
- a **Signal and Calibration module** that detects crossovers, latches state, and measures real candle metrics from history
- a **Prediction Engine** that generates synthetic OHLC candles using the measured baseline, a sine-wave size envelope, and counter-trend injection
- a **Renderer** that draws each candle as chart objects and removes the leading projected candle as each new real candle closes
The indicator is designed for the **M15 timeframe** but adapts automatically to any timeframe via `PeriodSeconds()`.
---
## Original Article
| Field | Value |
|------------------|---------------------------------------------------------------|
| Article Title | Creating an EMA Crossover Forward Simulation Indicator in MQL5 |
| Author | johnhlomohang |
| Publication Date | 2026.05.13 |
| Category | Indicators |
| Article URL | https://www.mql5.com/en/articles/22323 |
| Part 1 URL | "This is part 1" |
---
## Repository Purpose
This repository should be treated as a reference project accompanying the published article. Its purpose is to:
- preserve the full indicator source for study and extension
- document every input parameter and its effect
- serve as a base for replacing the EMA detector with structure-based or volatility-based triggers
- demonstrate the object-lifecycle, calibration, and rendering patterns described in the article series
---
## Key Concepts
- fast and slow EMA crossover detection on fully closed bars
- automatic anchor placement at the crossover bar
- average candle body and wick measurement from recent price history
- EMA slope as a momentum scale factor (0.5× – 1.5×) applied on top of the measured baseline
- sine-wave body-size envelope producing organic variation across the projection
- exponential decay flattening the projection toward the tail
- counter-trend candle injection every N bars for realistic pullbacks
- wick lengths derived from measured wick-to-body ratios
- inter-candle spacing via time-inset OBJ_RECTANGLE bodies
- pip-based signal invalidation with automatic object cleanup
- interactive projection: the leading synthetic candle is removed as each real candle closes
- dual-mode anchoring: automatic (tracks crossover bar) or manual (user-placed OBJ_VLINE)
---
## Algorithm and Architecture Summary
### Signal Detection
`OnCalculate` runs on every tick. The two most recently closed bars (index `rates_total-2` and `rates_total-3`) are compared. A bullish signal is latched when the fast EMA crosses above the slow EMA between those two bars. A bearish signal is latched on the reverse cross. Each new signal resets the drawn state and triggers a calibration refresh.
### Calibration
`CalcAvgCandleMetrics` reads the last `AvgLookback` closed bars using `CopyOpen`, `CopyHigh`, `CopyLow`, `CopyClose` starting at shift 1 (skipping the live forming bar). It computes:
- `g_AvgBody` — mean of `|close - open|`
- `g_AvgUpperWick` — mean of `high - max(open, close)`
- `g_AvgLowerWick` — mean of `min(open, close) - low`
- `g_AvgRange` — mean of `high - low`
All values are floored at 1 pip to prevent collapse in flat markets. The function runs once at `OnInit` and again on each new crossover signal.
### Prediction Engine
`GeneratePrediction` builds the `PredictedCandle[]` array. Each candle body size is computed as:
```
bodySize = avgBody × momentumScale × sin²(phase) × 0.93^i × jitter
```
where `momentumScale` maps the EMA slope to the range `[0.5, 1.5]`, the sine-squared term pulses sizes across the projection, `0.93^i` is the exponential decay, and jitter adds ±8% noise. Every `CounterCandleFreq` bars a counter-trend candle is injected at 25–45% of the trend body size. Wick lengths use the `avgWick / avgBody` ratio with ±25% jitter and a 20% floor.
### Rendering
`DrawAllCandles` places each synthetic candle one bar-width into the future relative to the anchor, inset by `CandleGapFraction` on each side for visible spacing. Each candle is drawn as:
- `OBJ_RECTANGLE` — filled body
- `OBJ_RECTANGLE` — body outline (unfilled)
- `OBJ_TREND` × 2 — upper and lower wicks, centred on the full bar slot
Supporting objects include a dashed `OBJ_VLINE` separator at the anchor, an `OBJ_TEXT` zone label, and an `OBJ_TEXT` invalidation notice.
### Invalidation
On every tick, the live bar's close is compared against the signal price. If a bullish projection's live price drops more than `InvalidationPips` below the signal price, or a bearish projection's live price rises more than `InvalidationPips` above it, all objects are deleted, an invalidation label is drawn, and the engine waits silently for the next valid cross.
### Interactive Removal
`OnCalculate` detects when `rates_total` increases by one, meaning a new real bar has closed. At that point the object group for `FutureCandle_0` is deleted and the remaining projected candles shift down by one index. The projection is always anchored exactly one bar ahead of the current live bar.
---
## Attached Files
| File | Description |
|-----------------------------|--------------------------------------------------|
| `ForwardSimEngine.mq5` | The complete MQL5 custom indicator |
---
## Input Parameters
| Parameter | Default | Description |
|---------------------|----------------|---------------------------------------------------------------------|
| `FastEMA_Period` | 9 | Period of the fast EMA |
| `SlowEMA_Period` | 21 | Period of the slow EMA |
| `FutureBars` | 30 | Number of synthetic candles to project |
| `SpreadMultiplier` | 2.0 | Secondary wick size multiplier (used as floor before calibration) |
| `AutoAnchor` | true | Auto-place anchor at the crossover bar; false = manual OBJ_VLINE |
| `AnchorLineName` | "FSE_Anchor" | Name of the anchor vertical line chart object |
| `BullishColor` | DodgerBlue | Body fill color for bullish projected candles |
| `BearishColor` | Crimson | Body fill color for bearish projected candles |
| `WickColor` | DimGray | Color for upper and lower wick lines |
| `ShowZoneLabel` | true | Show the `[ BULLISH PROJECTION ]` / `[ BEARISH PROJECTION ]` label |
| `ShowSeparatorLine` | true | Show a dashed vertical line at the anchor bar |
| `InvalidationPips` | 10 | Pip distance from signal price that triggers projection removal |
| `CandleGapFraction` | 0.08 | Gap between candles as a fraction of bar width (range: 0.04–0.20) |
| `CounterCandleFreq` | 4 | Insert one counter-trend candle every N candles (minimum: 3) |
| `AvgLookback` | 50 | Number of recent closed bars used to measure average candle size |
---
## Chart Object Naming Convention
All drawn objects use consistent prefixes so `ObjectsDeleteAll` can remove them cleanly in bulk.
| Prefix | Object type |
|-------------------------|------------------------------------|
| `FutureCandle_N_body` | Filled rectangle — candle body |
| `FutureCandle_N_bord` | Unfilled rectangle — body outline |
| `FutureCandle_N_wU` | Trend line — upper wick |
| `FutureCandle_N_wD` | Trend line — lower wick |
| `FSE_Sep` | Dashed vertical separator |
| `FSE_Label` | Projection zone label text |
| `FSE_Invalid` | Invalidation notice text |
| `FSE_Anchor` | Gold dash-dot anchor vertical line |
---
## Statistics
| Metric | Value |
|--------------------------------|----------------------------|
| Indicator type | Chart window overlay |
| Plot buffers | 2 (Fast EMA, Slow EMA) |
| Crossover bars evaluated | 2 (last two closed bars) |
| Default projection length | 30 bars |
| Default calibration lookback | 50 bars |
| Exponential decay base | 0.93 per bar |
| Sine envelope range | 0.40× – 1.30× baseStep |
| Momentum scale range | 0.5× – 1.5× avgBody |
| Counter-trend retrace range | 25% – 45% of body |
| Wick minimum floor | 20% of body height |
| Timer interval | 3 seconds (manual anchor) |
| Chart objects per candle | 4 |
---
## Installation
1. Copy `ForwardSimEngine.mq5` to your MetaTrader 5 data folder:
```
MQL5/Indicators/ForwardSimEngine.mq5
```
2. Open MetaEditor (F4 in MT5) and compile the file (F7).
3. In the MT5 Navigator panel under Custom Indicators, drag the indicator onto a chart.
4. Recommended timeframe: **M15**.
5. Configure inputs and click OK.
6. Open the Experts tab in the terminal to confirm the `[INIT]` and `[AVG]` log lines appear.
---
## Tuning Notes
- **`AvgLookback`** — increase to 100+ for a smoother long-run average. Lower to 20–30 to react faster to recent volatility shifts such as news events.
- **`InvalidationPips`** — increase on wide-spread instruments (XAUUSD, GBPJPY) to avoid premature removal. Lower on tight instruments (EURUSD, USDJPY) for stricter invalidation.
- **`CandleGapFraction`** — 0.08 works well on M15. Increase to 0.12–0.15 on higher timeframes where bar width appears wider on screen.
- **`CounterCandleFreq`** — set to 3 for more frequent pullbacks. Set to 6–8 for a cleaner directional sequence.
- **`FutureBars`** — keep at or below 60. Above that, the exponential decay reduces later candles to near the floor size and the projection becomes visually flat.
- **Manual anchor** — set `AutoAnchor = false` and draw an `OBJ_VLINE` named `FSE_Anchor` on any past bar to replay the projection from that point.
---
## Limitations
- The projection is a structured visual scenario, not a price forecast. It does not use volume, order flow, or market microstructure data.
- Signal detection is limited to EMA crossovers on closed bars. Intra-bar crosses are ignored until the bar closes.
- The invalidation threshold is fixed in pips. It does not adapt dynamically to ATR or recent volatility.
- The indicator does not place, manage, or close any trades. It is a visualization tool only.
- Wick and body calibration depends on the quality and quantity of history available on the active symbol and timeframe.
---
## Tags
`MQL5` `MetaTrader5` `CustomIndicator` `ForwardSimulation` `EMA` `Crossover` `SyntheticCandles` `ChartObjects` `Projection` `Visualization` `AlgorithmicTrading`
---
## Difficulty
**Intermediate — Advanced**
Requires familiarity with:
- MQL5 indicator development (`OnCalculate`, `SetIndexBuffer`, `CopyBuffer`)
- Chart object creation and lifecycle management (`ObjectCreate`, `ObjectDelete`, `ObjectsDeleteAll`)
- MQL5 array indexing conventions (series vs non-series layout)
- Basic EMA crossover concepts
- MetaTrader 5 Strategy Tester for validation
---
## Reference
Original article series: https://www.mql5.com/en/articles/22323