# MT5 EA Optimizer β Full Project Handoff Document **Last Updated:** 2026-04-13 **Status:** β Phase 1 (Backend Engine) + β Phase 2 (Live Web Dashboard) β BOTH COMPLETE **GitHub:** https://github.com/tonnylegacy/Apex_AI_MT5_EA_Optimizer **Primary EA:** LEGSTECH_EA_V2 | Symbol: XAUUSD | Timeframe: H1 | Broker TZ: UTC+2 --- ## π― Project Goal Build an automated, iterative backtesting and analysis system for MT5 Expert Advisors. It is NOT a trading bot. It is an **optimization engine** that: - Runs MT5 strategy tester automatically with different parameter sets - Extracts rich trade-level data (MAE/MFE) after each run - Analyzes results to find failure patterns using statistical methods - Proposes and tests parameter mutations based on findings - Validates improvements before accepting them (IS β WFV β OOS) - Prevents overfitting via Walk-Forward + Out-of-Sample testing - Displays everything live in a beautiful browser dashboard - Writes human-readable reports to a visible `Reports\` folder **End user:** Traders (non-technical). Double-click app, no terminal needed. --- ## ποΈ Architecture Overview ``` [Trader double-clicks "Launch Optimizer.bat"] β [Browser auto-opens http://localhost:5000] β [Flask + SocketIO Dashboard] β [Trader clicks βΆ Start] β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β OPTIMIZATION LOOP β β β β 1. Kill any running MT5 process (psutil) β β 2. Clear stale report files β β 3. Validate environment (EA exists, paths valid) β β 4. Build INI file (Period=H1, Report=relative) β β 5. Launch fresh MT5 via subprocess /config: β β 6. Wait 10s for data readiness β β 7. Poll MT5 appdata root for Optimizer_*.htm β β 8. Parse report (UTF-16 LE HTML β metrics+trades) β β 9. Run 4 analyzers on trade data β β 10. Score composite (Calmar-primary) β β 11. Mutate parameters β Hypotheses β β 12. Test each hypothesis (steps 1-10 repeated) β β 13. Validate: IS check β WFV β promote candidate β β 14. Write Reports\run_XXX\ (HTML + CSV + JSON) β β 15. Repeat until converged or max_iterations β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β [Dashboard updates live via WebSocket events] [Reports\ folder has all results] ``` --- ## π Complete File Structure ``` C:\Users\DELL\Desktop\MT5_Optimizer\ β βββ app.py β Flask + SocketIO app entry point β Auto-opens browser at localhost:5000 β Routes: /, /api/start, /api/pause, β /api/stop, /api/skip, /reports β βββ optimizer_loop.py β Background thread: full optimization pipeline β Emits SocketIO events for every phase/run/finding β βββ config.yaml β ALL settings (see section below) βββ requirements.txt β Python dependencies βββ PROJECT_HANDOFF.md β THIS DOCUMENT βββ "Launch Optimizer.bat" β Double-click to start (opens browser automatically) β Uses Python 3.11 at hardcoded path β βββ mql5/ β βββ TradeLogger.mqh β MQL5 include: per-trade MAE/MFE logger β DEPLOYED to: ...Terminal\...\MQL5\Include\ β INTEGRATED in: LEGSTECH_EA_V2.mq5 via TL_OnTick() β βββ data/ β βββ models.py β Pydantic v2: Trade, RunMetrics, Run, Finding, β β Hypothesis, Candidate, RunResult β βββ store.py β DataStore: SQLite metadata + Parquet trade arrays β βββ mt5/ β βββ ini_builder.py β Builds MT5 tester .ini files β β CRITICAL: Period=H1 (string), Report=relative name β β Model=4 (OHLC M1), ShutdownTerminal=1 β βββ runner.py β Full MT5 process control: β β kill_mt5() β clear_stale() β validate() β β β launch() β wait_data() β poll_report() β retry β β Report location: appdata_path\ root (NOT /reports/) β βββ report_parser.py β Parses MT5 HTML report β β CRITICAL: MT5 reports are UTF-16 LE encoded! β β Uses lhtml.document_fromstring(raw_bytes) β β Pairs in/out deals β complete Trade objects β βββ log_reader.py β Merges TradeLogger CSV (MAE/MFE) into trades β βββ analysis/ β βββ base.py β BaseAnalyzer ABC + statistical helpers β βββ reversal.py β Trades that went to MFE then reversed (permutation test) β βββ time_performance.py β Bad sessions/hours/days (Z-score) β βββ entry_exit_quality.py β MAE/MFE quality matrix (4-case diagnosis) β βββ equity_curve.py β Flatness, loss clusters, RΒ² of equity curve β βββ scoring/ β βββ composite.py β Weighted scorer: Calmar(35%) + PF(20%) + β MFE capture(20%) + stability(15%) + recovery(10%) β βββ mutation/ β βββ engine.py β Findings β Hypothesis objects (dedup, cascade) β βββ knowledge_base.yaml β 13 rules: finding_type β param_delta β βββ param_manifest.yaml β Full EA parameter space: types, bounds, defaults β βββ validation/ β βββ gate.py β IS check β Walk-Forward (2 folds) β OOS β βββ reports/ β βββ writer.py β Writes per-run: summary.json, summary.html, β trades.csv, findings.csv, parameters.json β βββ ui/ β βββ templates/ β β βββ index.html β Live dashboard (dark premium design) β β βββ report.html β Per-run report template β β βββ reports_index.html β Reports browser page (card grid) β βββ static/ β βββ css/style.css β Full dark theme CSS (glassmorphism, animations) β βββ js/dashboard.js β SocketIO events + Chart.js + live metrics β βββ tests/ β βββ test_analyzers.py β 10 unit tests (all passing β ) β βββ runs/ β Generated INI + local run folders (gitignored) βββ baseline_YYYYMMDD_.../ βββ run.ini ``` --- ## βοΈ Configuration (config.yaml) ```yaml ea: name: "LEGSTECH_EA_V2" file: "LEGSTECH_EA_V2" # no extension β MT5 adds .ex5 symbol: "XAUUSD" timeframe: "H1" periods: train_start: "2022.01.01" train_end: "2023.12.31" validate_start: "2024.01.01" validate_end: "2024.06.30" oos_start: "2024.07.01" # SACRED β never optimize against this oos_end: "2024.12.31" mt5: terminal_exe: "C:/Program Files/MetaTrader 5/terminal64.exe" appdata_path: "C:/Users/DELL/AppData/Roaming/MetaQuotes/Terminal/D0E8209F77C8CF37AD8BF550E51FF075" mql5_files_path: "C:/Users/DELL/AppData/Roaming/MetaQuotes/Tester/D0E8209F77C8CF37AD8BF550E51FF075/Agent-127.0.0.1-3000/MQL5/Files" tester_model: 4 # 4=OHLC M1 (fast). 0=Every Tick (slow, needs tick data) tester_timeout_seconds: 1800 shutdown_terminal: 1 # MT5 closes itself after each test data_readiness_wait_seconds: 10 kill_on_start: true # Always kill existing MT5 before each run broker: timezone_offset_hours: 2 # UTC+2 (HFMarkets) deposit: 10000.0 currency: "USD" leverage: 100 ``` --- ## β What Is Complete ### Phase 1 β Backend Engine | Component | Status | Notes | |---|---|---| | TradeLogger.mqh | β Deployed | In MT5 Include folder, integrated in EA | | data/models.py | β | All Pydantic v2 models | | data/store.py | β | SQLite + Parquet | | mt5/ini_builder.py | β | Period=H1 string, relative Report path | | mt5/runner.py | β | Killβvalidateβlaunchβwaitβpollβretry | | mt5/report_parser.py | β | UTF-16 LE HTML, pairs 597 trades | | mt5/log_reader.py | β | MAE/MFE merge + session labelling | | analysis/reversal.py | β | Permutation-tested | | analysis/time_performance.py | β | Z-score per hour/session/day | | analysis/entry_exit_quality.py | β | 4-case diagnosis matrix | | analysis/equity_curve.py | β | Flatness + RΒ² + loss clusters | | scoring/composite.py | β | Calmar-primary (0-1 score) | | mutation/engine.py | β | 13 KB rules, dedup, cascade | | validation/gate.py | β | IS β WFV β OOS β sensitivity | | tests/ | β 10/10 | Pure Python, no MT5 needed | ### Phase 2 β Live Web Dashboard | Component | Status | Notes | |---|---|---| | app.py | β | Flask + SocketIO, all API routes | | optimizer_loop.py | β | Background thread, live event emitter | | ui/templates/index.html | β | Score chart, metrics, findings, log, candidates | | ui/templates/report.html | β | Per-run full report with trade table | | ui/templates/reports_index.html | β | Card grid browser page | | ui/static/css/style.css | β | Premium dark theme | | ui/static/js/dashboard.js | β | SocketIO + Chart.js + live updates | | reports/writer.py | β | HTML + CSV + JSON per run | | Launch Optimizer.bat | β | Double-click launcher | | GitHub | β | https://github.com/tonnylegacy/Apex_AI_MT5_EA_Optimizer | --- ## π Critical Bugs Found & Fixed (Important for Future AI) ### 1. MT5 Report Encoding β UTF-16 LE **Problem:** MT5 HTML reports (`.htm`) are UTF-16 LE encoded (BOM: `\xFF\xFE`). Standard `decode('utf-8')` silently failed, lxml returned a single `
` element. **Fix:** Detect BOM and use `lhtml.document_fromstring(raw_bytes)` directly. ```python if raw[:2] == b'\xff\xfe': tree = lhtml.document_fromstring(raw) # handles UTF-16 internally ``` ### 2. MT5 Report Location **Problem:** Runner was looking in `appdata_path/reports/` β folder doesn't exist. **Reality:** MT5 writes reports to the **root** of `appdata_path\` directly. ``` C:\Users\DELL\AppData\Roaming\MetaQuotes\Terminal\D0E8209F...\Optimizer_baseline_*.htm ``` **Fix:** `self.mt5_reports_dir = self.appdata_path` (not `/ "reports"`) ### 3. INI Period Format **Problem:** Code used `Period=16385` (ENUM integer) β MT5 CLI ignores this. **Fix:** `Period=H1` (string name). `TIMEFRAME_NAMES = {"H1": "H1", ...}` ### 4. INI Report Path **Problem:** `Report=C:/absolute/path/...` β MT5 ignores absolute paths in CLI mode. **Fix:** `Report=Optimizer_{run_id}` (relative name only β MT5 writes to appdata root). ### 5. MQL5 Reference Syntax **Problem:** `TL_Positions[idx]&.fieldname` β C++ reference syntax, invalid in MQL5. **Fix:** `TL_Positions[idx].fieldname` β direct array index access. ### 6. Stale Report Detection **Problem:** Old `Optimizer_*.htm` files from previous runs triggered false-positive detection. **Fix:** `_clear_stale_reports()` deletes old files before each new run. --- ## π₯οΈ How to Run (For Any User) ### Prerequisites 1. MT5 installed at `C:\Program Files\MetaTrader 5\terminal64.exe` 2. LEGSTECH_EA_V2 compiled in MetaEditor (`.ex5` file must exist) 3. Python 3.11 installed at `C:\Users\DELL\AppData\Local\Programs\Python\Python311\` 4. Dependencies installed: `python.exe -m pip install -r requirements.txt` ### Starting the App 1. **Close MT5** if it's open (the optimizer kills and relaunches it automatically from the next run, but first run needs it clean) 2. **Double-click** `Launch Optimizer.bat` on Desktop 3. Browser opens at `http://localhost:5000` 4. Click **βΆ Start Optimizer** 5. Watch it run live β MT5 launches automatically, results appear in real-time 6. Reports saved to `MT5_Optimizer\Reports\run_XXX\` ### Save Changes to GitHub ```powershell cd "C:\Users\DELL\Desktop\MT5_Optimizer" git add . git commit -m "describe what changed" git push ``` --- ## π§ Environment Details | Item | Value | |---|---| | Python | 3.11 β `C:\Users\DELL\AppData\Local\Programs\Python\Python311\python.exe` | | GitHub | https://github.com/tonnylegacy/Apex_AI_MT5_EA_Optimizer | | MT5 Terminal ID | `D0E8209F77C8CF37AD8BF550E51FF075` | | MT5 Broker | HFMarketsGlobal-Live3 (Build 5660) | | Tester Agent | `Agent-127.0.0.1-3000` | | OS | Windows 11 | **Install all dependencies:** ```powershell C:\Users\DELL\AppData\Local\Programs\Python\Python311\python.exe -m pip install -r requirements.txt ``` **Key dependencies:** ``` flask, flask-socketio, eventlet β Web dashboard pydantic>=2.5, pandas>=2.1, pyarrow β Data layer lxml>=4.9, beautifulsoup4 β Report parsing psutil β MT5 process control loguru, rich, scipy, pyyaml β Utilities ``` --- ## π§ Key Design Decisions 1. **Hypothesis-driven, not brute-force** β Detect failure patterns β hypothesize fix β test β validate. Not grid search. 2. **Calmar ratio = primary score** β Return/MaxDrawdown most relevant for live trading. 3. **Three validation gates** β IS β WFV (2 folds) β OOS. No candidate promoted unless all pass. 4. **OOS is sacred** β `2024.07.01 β 2024.12.31` is NEVER used during optimization. Final check only. 5. **MT5 process control** β Always kill existing instance, launch clean, retry once on failure. 6. **UTF-16 LE** β ALL MT5 HTML reports are UTF-16 LE. Always use `document_fromstring(raw_bytes)`. 7. **Report location** β Always `appdata_path\Optimizer_{run_id}.htm` (root, not subfolder). 8. **Python 3.11 required** β System Python on this machine is 3.13 which is missing packages. 9. **Broker TZ = UTC+2** β Session analysis normalizes to UTC. London=07-16, NY=13-22. --- ## π Live Dashboard Events (SocketIO) The optimizer emits these events to the browser in real-time: | Event | Payload | When | |---|---|---| | `status_change` | `{state, phase}` | Phase transitions | | `run_started` | `{run_id, phase, period, params}` | MT5 launches | | `run_complete` | `{score, calmar, pf, dd, trades, ...}` | Report parsed | | `run_failed` | `{run_id, error}` | MT5 failed | | `finding` | `{analyzer, severity, description, confidence}` | Each finding | | `hypotheses` | `{items: [{id, desc, delta}]}` | Mutations proposed | | `score_update` | `{iteration, score, calmar, pf}` | Chart data point | | `candidate_promoted` | `{score, delta, params}` | Validation passed | | `optimization_complete` | `{candidates, best_score, iterations}` | Loop done | | `log` | `{level, msg}` | Live log feed | --- ## π Next Steps (Phase 3 β Packaging) 1. **PyInstaller EXE** β Bundle everything into `MT5_Optimizer.exe` ```bat pyinstaller --onefile --noconsole --name MT5_Optimizer app.py ``` Note: Need `--add-data` flags for templates, static, config, yaml files 2. **Auto `.set` file export** β When a candidate is promoted, export its params as a valid MT5 `.set` file the trader can load directly into the EA 3. **Email/Telegram notification** β Alert the trader when a candidate is promoted 4. **Multi-symbol support** β Run optimization across EURUSD, GBPUSD alongside XAUUSD 5. **Monte Carlo simulation** β Test robustness of promoted candidates --- ## β οΈ Known Issues & Watch Points 1. **First run needs MT5 closed manually** β From the second run onward, the system kills MT5 automatically via psutil. 2. **Tester Agent path** β `Agent-127.0.0.1-3000` may change if MT5 port changes. If TradeLog CSV not found, check Tester folder for new agent subfolder. 3. **WFV fold count** β Currently 2 folds (hardcoded in `validation/gate.py`). Easy to increase. 4. **XAUUSD data** β If the date range 2022-2023 gives errors, ensure XAUUSD H1 history is downloaded in MT5 (Tools β History Center). 5. **Model 4 vs 0** β `tester_model: 4` (OHLC M1) is fast and reliable. `tester_model: 0` (Every Tick) is more accurate but requires full tick data download and takes ~10x longer. 6. **ShutdownTerminal=1** β MT5 closes itself after each test. Cannot be used for live trading simultaneously. --- ## π Baseline Run Results (Confirmed Working) First successful parser test on real MT5 report (2026-04-13): | Metric | Value | |---|---| | Net Profit | -$621.15 | | Profit Factor | 0.95 | | Max Drawdown | 19.25% | | Calmar Ratio | -0.32 | | Sharpe Ratio | -1.60 | | Total Trades | 597 | | Win Rate | 77.7% | | Test Period | 2022.01.01 β 2023.12.31 | | Model | OHLC M1 (Model 4) | | Duration | ~56 seconds | > This is the baseline β the optimizer's job is to improve these numbers over iterations. --- *Last updated by Antigravity AI β 2026-04-13* *GitHub: https://github.com/tonnylegacy/Apex_AI_MT5_EA_Optimizer* *Both Phase 1 and Phase 2 are complete. Continue from Phase 3 (packaging).*