feat: MT5-Quant MCP server for backtesting and optimization

MCP server exposing MetaTrader 5 strategy development tools to AI
assistants (Claude, Cursor, etc.) on macOS (CrossOver) and Linux (Wine).

Tools:
- run_backtest: full pipeline — compile EA, clean cache, backtest,
  parse HTML/XML report, analyze deals → metrics.json + analysis.json
- run_optimization: background genetic optimization with nohup/disown,
  UTF-16LE .set file handling, OptMode reset
- compile_ea: MQL5 compilation via MetaEditor with auto-detected
  include/ directory sync
- get_backtest_status / get_optimization_status: job polling
- verify_environment: Wine/MT5 path validation

Analytics:
- extract.py: MT5 HTML and SpreadsheetML XML report parser
- analyze.py: deal-level analysis (drawdown events, grid depth,
  loss sequences, monthly P&L) → analysis.json
- optimize_parser.py: optimization result parser with convergence analysis

Platform support:
- macOS CrossOver (GUI mode, no Xvfb needed)
- Linux Wine + Xvfb (headless, CI/CD compatible)
- Auto-detection of Wine executable and MT5 terminal paths
This commit is contained in:
Devid HW
2026-04-18 11:41:41 +07:00
commit 3f763827f4
25 changed files with 9824 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
time,type,direction,volume,price,sl,tp,profit,balance,comment,order,magic,entry
2025.01.10 09:00:00,buy,in,0.01,1900.00,1880.00,1920.00,0.0,10000.0,Layer #1,1001,12345,in
2025.01.10 09:30:00,buy,out,0.01,1915.00,0.0,0.0,15.00,10015.0,Layer #1,1001,12345,out
2025.01.15 10:00:00,sell,in,0.01,1910.00,1930.00,1890.00,0.0,10015.0,Layer #1,1002,12345,in
2025.01.15 10:45:00,sell,out,0.01,1920.00,0.0,0.0,-10.00,10005.0,Layer #1,1002,12345,out
2025.01.20 14:00:00,buy,in,0.02,1905.00,1880.00,1935.00,0.0,10005.0,Layer #2,1003,12345,in
2025.01.21 09:00:00,buy,in,0.04,1895.00,1870.00,1925.00,0.0,10005.0,Layer #3,1004,12345,in
2025.01.21 15:30:00,buy,out,0.06,1925.00,0.0,0.0,30.00,10035.0,Layer #3,1003,12345,out
2025.02.05 10:00:00,sell,in,0.01,1930.00,1950.00,1910.00,0.0,10035.0,Layer #1,1005,12345,in
2025.02.05 14:00:00,sell,out,0.01,1945.00,0.0,0.0,-15.00,10020.0,Layer #1,1005,12345,out
2025.02.12 11:00:00,buy,in,0.01,1920.00,1900.00,1940.00,0.0,10020.0,Layer #1,1006,12345,in
2025.02.12 16:00:00,buy,out,0.01,1938.00,0.0,0.0,18.00,10038.0,Layer #1,1006,12345,out
2025.01.06 02:30:00,buy,in,0.01,1885.00,1865.00,1905.00,0.0,10038.0,Layer #1,2001,23456,in
2025.01.06 03:15:00,buy,out,0.01,1898.00,0.0,0.0,12.00,10050.0,Layer #1 TP,2001,23456,out
2025.01.07 20:00:00,sell,in,0.01,1910.00,1930.00,1890.00,0.0,10050.0,Layer #1,2002,23456,in
2025.01.07 21:30:00,sell,out,0.01,1918.00,0.0,0.0,-8.00,10042.0,Layer #1 cutloss,2002,23456,out
2025.01.08 09:30:00,buy,in,0.01,1892.00,1872.00,1912.00,0.0,10042.0,Layer #1,2003,23456,in
2025.01.08 10:20:00,buy,out,0.01,1905.00,0.0,0.0,20.00,10062.0,Layer #1,2003,23456,out
2025.01.13 08:00:00,sell,in,0.01,1925.00,1945.00,1905.00,0.0,10062.0,Layer #1,2004,23456,in
2025.01.13 08:01:00,sell,in,0.02,1928.00,1948.00,1908.00,0.0,10062.0,Layer #2,2005,23456,in
2025.01.13 08:02:00,sell,in,0.04,1931.00,1951.00,1911.00,0.0,10062.0,Layer #3,2006,23456,in
2025.01.13 09:30:00,sell,out,0.07,1905.00,0.0,0.0,-45.00,10017.0,Layer #3 cutloss,2004,23456,out
2025.01.16 15:00:00,buy,in,0.01,1900.00,1880.00,1920.00,0.0,10017.0,Layer #1,2007,23456,in
2025.01.16 17:30:00,buy,out,0.01,1915.00,0.0,0.0,22.00,10039.0,Layer #1,2007,23456,out
1 time type direction volume price sl tp profit balance comment order magic entry
2 2025.01.10 09:00:00 buy in 0.01 1900.00 1880.00 1920.00 0.0 10000.0 Layer #1 1001 12345 in
3 2025.01.10 09:30:00 buy out 0.01 1915.00 0.0 0.0 15.00 10015.0 Layer #1 1001 12345 out
4 2025.01.15 10:00:00 sell in 0.01 1910.00 1930.00 1890.00 0.0 10015.0 Layer #1 1002 12345 in
5 2025.01.15 10:45:00 sell out 0.01 1920.00 0.0 0.0 -10.00 10005.0 Layer #1 1002 12345 out
6 2025.01.20 14:00:00 buy in 0.02 1905.00 1880.00 1935.00 0.0 10005.0 Layer #2 1003 12345 in
7 2025.01.21 09:00:00 buy in 0.04 1895.00 1870.00 1925.00 0.0 10005.0 Layer #3 1004 12345 in
8 2025.01.21 15:30:00 buy out 0.06 1925.00 0.0 0.0 30.00 10035.0 Layer #3 1003 12345 out
9 2025.02.05 10:00:00 sell in 0.01 1930.00 1950.00 1910.00 0.0 10035.0 Layer #1 1005 12345 in
10 2025.02.05 14:00:00 sell out 0.01 1945.00 0.0 0.0 -15.00 10020.0 Layer #1 1005 12345 out
11 2025.02.12 11:00:00 buy in 0.01 1920.00 1900.00 1940.00 0.0 10020.0 Layer #1 1006 12345 in
12 2025.02.12 16:00:00 buy out 0.01 1938.00 0.0 0.0 18.00 10038.0 Layer #1 1006 12345 out
13 2025.01.06 02:30:00 buy in 0.01 1885.00 1865.00 1905.00 0.0 10038.0 Layer #1 2001 23456 in
14 2025.01.06 03:15:00 buy out 0.01 1898.00 0.0 0.0 12.00 10050.0 Layer #1 TP 2001 23456 out
15 2025.01.07 20:00:00 sell in 0.01 1910.00 1930.00 1890.00 0.0 10050.0 Layer #1 2002 23456 in
16 2025.01.07 21:30:00 sell out 0.01 1918.00 0.0 0.0 -8.00 10042.0 Layer #1 cutloss 2002 23456 out
17 2025.01.08 09:30:00 buy in 0.01 1892.00 1872.00 1912.00 0.0 10042.0 Layer #1 2003 23456 in
18 2025.01.08 10:20:00 buy out 0.01 1905.00 0.0 0.0 20.00 10062.0 Layer #1 2003 23456 out
19 2025.01.13 08:00:00 sell in 0.01 1925.00 1945.00 1905.00 0.0 10062.0 Layer #1 2004 23456 in
20 2025.01.13 08:01:00 sell in 0.02 1928.00 1948.00 1908.00 0.0 10062.0 Layer #2 2005 23456 in
21 2025.01.13 08:02:00 sell in 0.04 1931.00 1951.00 1911.00 0.0 10062.0 Layer #3 2006 23456 in
22 2025.01.13 09:30:00 sell out 0.07 1905.00 0.0 0.0 -45.00 10017.0 Layer #3 cutloss 2004 23456 out
23 2025.01.16 15:00:00 buy in 0.01 1900.00 1880.00 1920.00 0.0 10017.0 Layer #1 2007 23456 in
24 2025.01.16 17:30:00 buy out 0.01 1915.00 0.0 0.0 22.00 10039.0 Layer #1 2007 23456 out
+25
View File
@@ -0,0 +1,25 @@
<html>
<head><title>Strategy Tester Report</title></head>
<body>
<table>
<tr><td>Net profit</td><td>1234.56</td></tr>
<tr><td>Profit factor</td><td>1.25</td></tr>
<tr><td>Maximal drawdown</td><td>500.00 (5.00%)</td></tr>
<tr><td>Sharpe Ratio</td><td>0.75</td></tr>
<tr><td>Total trades</td><td>150</td></tr>
<tr><td>Recovery factor</td><td>2.50</td></tr>
<tr><td>Profit trades (% of total)</td><td>90 (60.00%)</td></tr>
<tr><td>Gross profit</td><td>2000.00</td></tr>
<tr><td>Gross loss</td><td>-765.44</td></tr>
</table>
<table>
<tr><td>Deal Time</td><td>Type</td><td>Direction</td><td>Volume</td><td>Price</td><td>S/L</td><td>T/P</td><td>Profit</td><td>Balance</td><td>Comment</td><td>Order</td><td>Magic</td><td>Entry</td></tr>
<tr><td>2025.01.10 09:30:00</td><td>buy</td><td>out</td><td>0.01</td><td>1915.00</td><td>0</td><td>0</td><td>15.00</td><td>10015.00</td><td>Layer #1</td><td>1001</td><td>12345</td><td>out</td></tr>
<tr><td>2025.01.15 10:45:00</td><td>sell</td><td>out</td><td>0.01</td><td>1920.00</td><td>0</td><td>0</td><td>-10.00</td><td>10005.00</td><td>Layer #1</td><td>1002</td><td>12345</td><td>out</td></tr>
<tr><td>2025.01.21 15:30:00</td><td>buy</td><td>out</td><td>0.06</td><td>1925.00</td><td>0</td><td>0</td><td>30.00</td><td>10035.00</td><td>Layer #3</td><td>1003</td><td>12345</td><td>out</td></tr>
<tr><td>2025.02.05 14:00:00</td><td>sell</td><td>out</td><td>0.01</td><td>1945.00</td><td>0</td><td>0</td><td>-15.00</td><td>10020.00</td><td>Layer #1</td><td>1005</td><td>12345</td><td>out</td></tr>
<tr><td>2025.02.12 16:00:00</td><td>buy</td><td>out</td><td>0.01</td><td>1938.00</td><td>0</td><td>0</td><td>18.00</td><td>10038.00</td><td>Layer #1</td><td>1006</td><td>12345</td><td>out</td></tr>
</table>
</body>
</html>
+88
View File
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<Worksheet ss:Name="Report">
<Table>
<Row>
<Cell><Data ss:Type="String">Net profit</Data></Cell>
<Cell><Data ss:Type="Number">1234.56</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Profit factor</Data></Cell>
<Cell><Data ss:Type="Number">1.25</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Sharpe Ratio</Data></Cell>
<Cell><Data ss:Type="Number">0.75</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Total trades</Data></Cell>
<Cell><Data ss:Type="Number">150</Data></Cell>
</Row>
</Table>
</Worksheet>
<Worksheet ss:Name="Deals">
<Table>
<Row>
<Cell><Data ss:Type="String">time</Data></Cell>
<Cell><Data ss:Type="String">type</Data></Cell>
<Cell><Data ss:Type="String">direction</Data></Cell>
<Cell><Data ss:Type="String">volume</Data></Cell>
<Cell><Data ss:Type="String">price</Data></Cell>
<Cell><Data ss:Type="String">sl</Data></Cell>
<Cell><Data ss:Type="String">tp</Data></Cell>
<Cell><Data ss:Type="String">profit</Data></Cell>
<Cell><Data ss:Type="String">balance</Data></Cell>
<Cell><Data ss:Type="String">comment</Data></Cell>
<Cell><Data ss:Type="String">order</Data></Cell>
<Cell><Data ss:Type="String">magic</Data></Cell>
<Cell><Data ss:Type="String">entry</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">2025.01.10 09:30:00</Data></Cell>
<Cell><Data ss:Type="String">buy</Data></Cell>
<Cell><Data ss:Type="String">out</Data></Cell>
<Cell><Data ss:Type="Number">0.01</Data></Cell>
<Cell><Data ss:Type="Number">1915.00</Data></Cell>
<Cell><Data ss:Type="Number">0</Data></Cell>
<Cell><Data ss:Type="Number">0</Data></Cell>
<Cell><Data ss:Type="Number">15.00</Data></Cell>
<Cell><Data ss:Type="Number">10015.00</Data></Cell>
<Cell><Data ss:Type="String">Layer #1</Data></Cell>
<Cell><Data ss:Type="Number">1001</Data></Cell>
<Cell><Data ss:Type="Number">12345</Data></Cell>
<Cell><Data ss:Type="String">out</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">2025.01.15 10:45:00</Data></Cell>
<Cell><Data ss:Type="String">sell</Data></Cell>
<Cell><Data ss:Type="String">out</Data></Cell>
<Cell><Data ss:Type="Number">0.01</Data></Cell>
<Cell><Data ss:Type="Number">1920.00</Data></Cell>
<Cell><Data ss:Type="Number">0</Data></Cell>
<Cell><Data ss:Type="Number">0</Data></Cell>
<Cell><Data ss:Type="Number">-10.00</Data></Cell>
<Cell><Data ss:Type="Number">10005.00</Data></Cell>
<Cell><Data ss:Type="String">Layer #1</Data></Cell>
<Cell><Data ss:Type="Number">1002</Data></Cell>
<Cell><Data ss:Type="Number">12345</Data></Cell>
<Cell><Data ss:Type="String">out</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">2025.02.05 14:00:00</Data></Cell>
<Cell><Data ss:Type="String">sell</Data></Cell>
<Cell><Data ss:Type="String">out</Data></Cell>
<Cell><Data ss:Type="Number">0.01</Data></Cell>
<Cell><Data ss:Type="Number">1945.00</Data></Cell>
<Cell><Data ss:Type="Number">0</Data></Cell>
<Cell><Data ss:Type="Number">0</Data></Cell>
<Cell><Data ss:Type="Number">-15.00</Data></Cell>
<Cell><Data ss:Type="Number">10020.00</Data></Cell>
<Cell><Data ss:Type="String">Layer #1</Data></Cell>
<Cell><Data ss:Type="Number">1005</Data></Cell>
<Cell><Data ss:Type="Number">12345</Data></Cell>
<Cell><Data ss:Type="String">out</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook>