Files
2026-07-06 21:58:56 +08:00

654 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MT5 EA 批量回测系统
基于 MetaTrader 5 的自动化批量回测工具,支持多EA、多交易品种、多时间周期的组合测试。
## 项目结构
```
mt5_backtest/
├── gui.py # 图形界面(统一入口,所有回测操作都在这里)
├── scripts/
│ ├── ini_generator.py # 生成MT5配置文件
│ ├── mt5_auto_runner.py # 自动运行回测
│ ├── batch_executor.py # 批量执行器
│ ├── result_parser.py # 解析HTM/XML报告
│ ├── report_generator.py # 生成汇总报告
│ ├── symbol_resolver.py # 根品种别名解析(XAUUSD→XAUUSDc
│ └── optimizer/ # EA参数优化系统
├── config/ # 配置文件目录
├── reports/ # 回测报告输出目录
├── tests/ # 自检脚本(test_*.py / smoke_*.py
├── logs/ # 日志目录
└── README.md # 本文档
```
## 核心原理
### 1. 配置生成阶段 (ini_generator.py)
- 读取配置文件 `config/ea_configs.yaml`
- 扫描 MT5 的 `MQL5/Experts` 目录获取 EA 列表
- 根据配置的 EA品种、时间周期、参数组合生成 INI 配置文件
- 每个 INI 文件对应一次回测任务
- 写入 INI 的 `Symbol=` 行通过 `scripts/symbol_resolver.py` 查表替换(见下文"根品种别名映射")
### 2. 自动执行阶段 (mt5_auto_runner.py)
- 通过命令行调用 MT5 终端: `terminal64.exe /config:xxx.ini`
- 监控回测进度,等待报告文件生成
- 自动终止并重启 MT5 进程(可选)
- 复制生成的 HTM 报告到项目目录
### 3. 结果解析阶段 (result_parser.py)
- 读取 `reports/` 目录下的 HTM 报告文件
- 自动检测文件编码(UTF-16-LE with BOM
- 使用正则表达式提取关键指标
- 支持中英文标签匹配
### 4. 报告生成阶段 (report_generator.py)
- 将解析结果导出为 Excel、CSV、HTML、Markdown 格式
- 支持按盈利因子、胜率等指标排序
## 使用方式
### 方式一:图形界面(推荐)
```bash
python gui.py
```
界面包含三个标签页:
- **回测配置**:选择 EA、交易品种、时间周期、回测日期等
- **执行选项**:设置超时、跳过已完成的测试等
- **报告查看**:查看已解析的回测结果,支持排序和导出CSV
### 方式二:GUI(推荐,唯一入口)
```bash
python gui.py
```
> 整个回测流程(生成 INI → 运行 → 解析 → 汇总)都在 GUI 后台线程完成,
> 进度实时显示在 "参数优化" 标签页的日志框。
> YAML 仅作为可读的配置导出/快照(GUI "保存配置" 按钮),不参与运行时通信。
## 配置文件格式
配置文件 `config/ea_configs.yaml` 示例:
```yaml
eas:
- name: GMarket
filename: GMarket.ex5
set_file: GMarket_default.set # 可选,使用SET文件
backtest_settings:
symbols: ["EURUSD", "GBPUSD", "XAUUSD", "USDJPY"]
timeframes: ["M1", "M5", "M15", "H1"]
# 可选:根品种别名映射(见下文"根品种别名映射")
# symbol_aliases:
# XAUUSD: XAUUSDc # 逻辑 XAUUSD -> 实际 XAUUSDc
# XAGUSD: XAGUSDm # 逻辑 XAGUSD -> 实际 XAGUSDm
date_range:
from: "2026.01.01"
to: "2026.01.04"
model: 0 # 0=Every Tick, 1=OHLC, 4=Real Tick
execution_delay: 0 # 延迟设置
deposit: 10000 # 初始保证金
leverage: "1:100" # 杠杆
replace_report: true # 覆盖已有报告
shutdown_terminal: true
mt5_settings:
terminal_path: "C:\\Program Files\\MetaTrader 5 IC Markets Global\\terminal64.exe"
data_dir: "C:\\Users\\Administrator\\AppData\\Roaming\\MetaQuotes\\Terminal\\..."
reports_dir: "reports"
ini_dir: "config/generated"
execution:
timeout_per_test: 30 # 分钟
skip_existing: true
kill_between: true # 测试间关闭MT5
```
## 关键指标说明
| 指标 | 说明 | 评判标准 |
|------|------|----------|
| **profit_factor** | 盈利因子 = 毛利/毛损 | >1.5 优秀, >1.0 微利, <1.0 亏损 |
| **net_profit** | 总净盈利 | 越高越好 |
| **gross_profit** | 毛利(所有盈利交易总和) | 越高越好 |
| **gross_loss** | 毛损(所有亏损交易总和) | 越低越好 |
| **win_rate** | 胜率(盈利交易占比) | >60% 较好 |
| **total_trades** | 总交易次数 | 样本量参考 |
| **max_drawdown** | 最大回撤金额 | 越低越稳定 |
| **sharpe_ratio** | 夏普比率(风险收益比) | >1.0 较好, >2.0 优秀 |
| **recovery_factor** | 采收率 | >1.5 较好 |
## 如何添加新的交易品种
### 方法一:通过 GUI 界面
1. 打开 `python gui.py`
2. 切换到"回测配置"标签页
3. 在"交易品种"区域勾选需要的品种
4. 点击"保存配置"
### 方法二:直接编辑配置文件
编辑 `config/ea_configs.yaml`
```yaml
backtest_settings:
symbols:
- EURUSD
- GBPUSD
- XAUUSD # 添加新品种
- USDJPY
- BTCUSD # 添加数字货币
```
### 支持的交易品种类型
| 类型 | 示例 |
|------|------|
| 主流货币对 | EURUSD, GBPUSD, USDJPY, USDCHF |
| 商品货币 | AUDUSD, NZDUSD, USDCAD |
| 交叉货币 | EURGBP, EURJPY, GBPJPY |
| 贵金属 | XAUUSD, XAGUSD |
| 原油 | XBRUSD, XTIUSD |
| 数字货币 | BTCUSD, ETHUSD, LTCUSD |
## 根品种别名映射 (`symbol_aliases`)
MT5 自带品种(如 `XAUUSD`)历史深度和精度有限;用户常在 MT5 里添加自定义品种
(如 `XAUUSDc` / `XAUUSDm`)作为更长时间范围或优化用途的"替身"。本系统通过 `symbol_aliases`
让你在 yaml 里写一次逻辑品种名、由系统按表替换成实际 MT5 品种。
### 写入 `config/ea_configs.yaml`
```yaml
backtest_settings:
symbols: [XAUUSD, XAGUSD, EURUSD] # 用户的"逻辑品种"
symbol_aliases:
XAUUSD: XAUUSDc # 逻辑 XAUUSD -> 实际 XAUUSDc
XAGUSD: XAGUSDm # 逻辑 XAGUSD -> 实际 XAGUSDm
# EURUSD 不列 -> 始终 EURUSD
```
### 工作机制
1. `scripts/ini_generator.py``scripts/optimizer/ea_batch_optimizer.py`
写 INI 的 `Symbol=` 之前调用 `scripts/symbol_resolver.resolve_symbol()`
2. 解析器是**纯查表**——没有任何"基于日期/优化/周期的智能判断"——写啥用啥:
- 别名表里有这个逻辑品种 → 用别名替换
- 没有 → 原样写入 `Symbol=`
3. 两条调用路径共用同一份解析器(`scripts/symbol_resolver.py`),保证 GUI 回测页
和优化器生成的 INI 行为一致。
### GUI 优化页
GUI 优化页下拉只显示**逻辑品种**(不再同时列出 XAUUSD / XAUUSDc)。旁边有一个
`→ XAUUSDc` 提示标签,**实时反映 yaml 里 `symbol_aliases` 当前配置下实际会用什么品种**。
改 yaml 后重启 GUI 即可看到提示变化,无需在 GUI 里反复切换。
### 验证
无需 MT5 也能验:
```bash
python tests/test_symbol_resolver.py # 9 条查表断言
python tests/test_ini_generator.py # 5 条端到端断言
```
需要 MT5 验证完整流水线:
```bash
python tests/smoke_alias_backtest.py
# 跑两次真实回测:一次无别名 (Symbol=XAUUSD),一次有别名 (Symbol=XAUUSDc)
# 期望:C:\Users\Administrator\Desktop\mt5-backtest\reports 下生成两份 .htm 报告
# 报告"交易品种"字段分别是 XAUUSD 和 XAUUSDc
```
> 注:`smoke_alias_backtest.py` 顶部硬编码了 MT5 路径和 data dir hash,复制到其他电脑后
> 需要相应修改 `MT5_PATH` / `MT5_DATA_DIR` 常量。
### 扩展点(ponytail
`scripts/symbol_resolver.py` 是共享函数入口,将来要把"配置源"切换成数据库或要做
MT5 `SymbolSelect` 校验,**只改这一个文件**即可,所有调用方(ini 生成器、批量优化器、
GUI 预览)同步生效。
## 如何添加新的时间周期
编辑 `config/ea_configs.yaml`
```yaml
backtest_settings:
timeframes:
- M1 # 1分钟
- M5 # 5分钟
- M15 # 15分钟
- M30 # 30分钟
- H1 # 1小时
- H4 # 4小时
- D1 # 日线
- W1 # 周线
```
## 报告导出功能
```bash
# 导出排序后的CSV
python scripts/result_parser.py --results-dir reports --csv reports/results.csv --sort profit_factor
# 可用排序字段
# expert, symbol, period, net_profit, gross_profit, profit_factor
# total_trades, win_rate, max_drawdown, sharpe_ratio
```
## HTM 报告解析说明
MT5 生成的 HTM 报告采用特殊编码:
- 编码格式:UTF-16-LE with BOM
- 标签语言:中英混合
解析器会自动处理以下情况:
1. BOM 标记检测与跳过
2. 中文字段名匹配(如"盈利因子"、"夏普比率"
3. 特殊格式数据提取(如 "92.46 (8.61%)"
### 解析的完整字段列表
**测试信息 (test_info)**:
- expert: EA名称
- symbol: 交易品种
- period: 时间周期
- company: 经纪商
- currency: 货币
- leverage: 杠杆
**性能指标 (metrics)**:
- initial_deposit: 初始入金
- net_profit: 总净盈利
- gross_profit: 毛利
- gross_loss: 毛损
- profit_factor: 盈利因子
- expected_payoff: 预期收益
- recovery_factor: 采收率
- sharpe_ratio: 夏普比率
- ahpr/ghpr: 几何/算术平均收益率
- lr_correlation: LR相关性
- lr_standard_error: LR标准误差
- max_drawdown: 最大结余亏损
- max_equity_drawdown: 最大净值亏损
- absolute_drawdown: 绝对结余亏损
- margin_level: 预付款维持率
- total_trades: 交易总计
- total_deals: 总成交
- short_trades: 卖出交易
- long_trades: 买入交易
- winning_trades: 盈利交易
- losing_trades: 亏损交易
- win_rate: 胜率
- max_profit_trade: 最大获利交易
- max_loss_trade: 最大亏损交易
- avg_profit_trade: 平均获利交易
- avg_loss_trade: 平均亏损交易
- longest_win_streak: 最大连胜
- longest_lose_streak: 最大连败
- avg_win_streak: 平均连胜
- avg_lose_streak: 平均连败
- min_hold_time/max_hold_time/avg_hold_time: 持仓时间
- quality: 质量历史
- bars: 柱数
- quotes: 报价数
- score: 分值
- on_tester: OnTester结果
## EA参数优化系统
### 概述
EA参数优化系统用于自动寻找EA的最优参数组合,支持多种搜索策略。
### 目录结构
```
optimizer/
├── configs/ # EA配置文件目录
│ ├── MA_Cross.json # 示例: MA交叉策略 (6参数, Grid搜索)
│ └── Grid_Pro.json # 示例: 网格策略 (8参数, 遗传算法)
├── set_files/ # 生成的SET参数文件
│ └── {EA_NAME}/
│ └── params_00000001.set ~ params_NNNNNNNN.set
├── reports/ # MT5测试报告
├── results/ # 分析结果
│ ├── {EA_NAME}_param_mapping.csv
│ └── optimization_report.txt
├── scripts/ # PowerShell脚本
└── logs/ # 日志
```
### EA配置文件格式
```json
{
"ea_name": "MA Cross Scalper",
"ea_path": "Experts\\MA_Cross.ex5",
"description": "双MA交叉策略",
"search_strategy": "grid",
"optimization_criterion": "profit_factor",
"parameters": {
"FastMA_Period": {
"type": "int",
"default": 14,
"min": 5,
"max": 30,
"step": 1,
"description": "快速MA周期"
},
"SlowMA_Period": {
"type": "int",
"default": 50,
"min": 20,
"max": 100,
"step": 5,
"description": "慢速MA周期",
"condition": ">FastMA_Period"
}
},
"test_config": {
"symbol": "EURUSD",
"period": "H1",
"from_date": "2025.01.01",
"to_date": "2025.12.31",
"model": 1,
"deposit": 10000,
"leverage": "1:100"
},
"walk_forward": {
"enabled": false
}
}
```
### 参数类型
| 类型 | 说明 | 示例 |
|------|------|------|
| int | 整数参数 | FastMA_Period: 5-30 |
| double | 浮点参数 | RiskPercent: 0.5-3.0 |
| bool | 布尔参数 | EnableMM: true/false |
| enum | 枚举参数 | TradingMode: BUY/SELL/BOTH |
### 搜索策略选择
| 组合数 | 策略 | 说明 |
|--------|------|------|
| ≤10,000 | Grid Search | 暴力遍历,适合快速测试 |
| 10,001-500,000 | Latin Hypercube | 均匀采样,效率高 |
| >500,000 | Genetic Algorithm | 遗传算法,智能搜索 |
### 使用方式
#### 方式一:图形界面
```bash
python gui.py
```
切换到"参数优化"标签页,可以:
- 查看EA配置列表
- 生成SET文件
- 运行优化测试
- 分析优化结果
#### 方式二:命令行
```bash
# 列出所有EA配置
python optimizer_main.py list
# 生成SET文件
python optimizer_main.py generate --ea "MA Cross Scalper"
# 分析结果
python optimizer_main.py analyze --sort profit_factor
```
### 参数约束
在EA配置中使用 `condition` 字段定义参数约束:
```json
"SlowMA_Period": {
"condition": ">FastMA_Period"
}
```
支持的运算符:`>`, `<`, `>=`, `<=`, `==`, `!=`
### GUI优化面板功能
1. **列出EA配置** - 显示所有配置的参数数量、组合数、预估时间
2. **生成SET文件** - 为每个参数组合创建.set文件
3. **运行优化** - 生成PowerShell脚本,用户可手动执行
4. **分析结果** - 解析报告,找出最优参数组合
### 输出文件
- `{EA_NAME}_param_mapping.csv` - 参数ID映射表
- `optimization_report.txt` - 优化分析报告
- `best_params.json` - 最优参数JSON
## AI辅助参数优化工具
### 概述
`scan_set_prompt.py` 是一个命令行工具,用于扫描 MT5 的 SET 参数文件,生成带完整提示词的文本文件,方便发给 AI 讨论参数优化方案。
### 工作流程
```
SET文件 → scan_set_prompt.py → AI提示词txt → AI生成优化JSON → 保存到optimizer/configs/
```
### 使用方式
```bash
# 交互式选择模式
python scripts/scan_set_prompt.py --interactive
# 扫描单个SET文件
python scripts/scan_set_prompt.py --file "C:\path\to\EA.set"
# 扫描文件夹下所有SET文件
python scripts/scan_set_prompt.py --folder "C:\path\to\Profiles\Tester"
# 批量扫描多个SET文件
python scripts/scan_set_prompt.py --batch a.set b.set c.set
# 指定输出目录
python scripts/scan_set_prompt.py --file "C:\path\to\EA.set" --output "C:\path\to\output"
```
### 交互式模式选项
```
1. 扫描单个 SET 文件
2. 扫描文件夹下所有 SET 文件
3. 批量扫描多个 SET 文件
4. 从剪贴板读取 SET 内容
0. 退出
```
### 生成的文件内容
生成的 `_optimization_prompt.txt` 包含:
1. **基本信息** - EA名称、参数总数
2. **参数详情表** - 所有参数的当前值、范围、步进
3. **参数分析任务** - 引导 AI 分析哪些参数该优化、范围建议
4. **完整JSON模板** - 符合 `optimizer/configs/*.json` 格式,包含:
- `ea_path` 自动做 ASCII 安全处理(支持中文名 EA)
- `parameters` 部分带优化建议注释
- `test_config``walk_forward` 配置
### 输出示例
```json
{
"ea_name": "GoldSniper_Pro_v2",
"ea_path": "MY-EA\\GoldSniper_Pro_v2.ex5",
"description": "Edited via GUI",
"search_strategy": "auto",
"parameters": {
"LotSize": {
"type": "double",
"default": 0.01,
"min": 0.01,
"max": 0.1,
"step": 0.001,
"optimize": true // AI根据策略分析填写
}
},
"test_config": {...},
"walk_forward": {...}
}
```
### 注意事项
- SET 文件支持多种格式:我们的 `=val||min||step||max||Y` 格式、MT5 原生 `<val1> <val2>` 格式、布尔 `true/false` 格式
- 自动检测文件编码(UTF-8、UTF-16-LE/BE
- `ea_path` 使用双反斜杠 `\\`,中文 EA 名自动转换为 ASCII(如 `EAGoldSniper``EA_GoldSniper`
- AI 生成的 JSON 可直接保存到 `optimizer/configs/` 目录使用
## 批量提取文件名工具
### 概述
`extract_filenames.py` 用于批量提取某个文件夹下所有文件名,支持子文件夹递归检索。
### 使用方式
```bash
python extract_filenames.py
```
交互式操作:
1. 输入要扫描的文件夹路径
2. 选择是否包含子文件夹(默认包含)
3. 输入输出文件名(直接回车使用自动命名)
### 输出文件命名规则
- 自动命名格式:`{源文件夹名}_filenames_{日期时间}.txt`
- 例如:`mt5_backtest_filenames_20260531_195723.txt`
- 文件保存在被扫描文件夹的**父目录**
### 示例
```
请输入文件夹路径: C:\Projects\MyEA
是否包含子文件夹? (y/n, 默认y):
输出文件名 (直接回车使用自动命名):
正在扫描文件夹: C:\Projects\MyEA
模式: 包含子文件夹 (递归)
请稍候...
完成! 共找到 128 个文件
结果已保存到: C:\Projects\MyEA_filenames_20260531_195723.txt
```
## 未来可扩展方向
### 1. 自动化参数优化
- 集成 OptParams 参数优化功能
- 支持遗传算法、枚举等优化方法
- 自动寻找最优参数组合
### 2. 多经纪商支持
- 支持不同经纪商的配置切换
- 账户资金和杠杆差异化设置
### 3. 实时监控面板
- Web 界面实时显示回测进度
- 推送通知(邮件/微信)回测完成提醒
### 4. 机器学习辅助
- 使用历史数据训练预测模型
- 辅助参数选择和优化方向建议
### 5. 云端分布式回测
- 支持多台机器并行回测
- 任务队列和负载均衡
### 6. 更丰富的报告分析
- 资金曲线图表
- 交易分布热力图
- 月度/年化收益统计
### 7. 数据库存储
- SQLite/PostgreSQL 存储历史回测结果
- 支持历史对比和趋势分析
## 依赖环境
- Python 3.8+
- MetaTrader 5 Terminal
- 依赖库: tkinter (GUI), yaml, openpyxl, beautifulsoup4, lxml
## 项目结构
```
mt5_backtest/
├── gui.py # 图形界面(回测 + 优化,唯一入口)
├── scripts/
│ ├── ini_generator.py # 生成MT5配置文件
│ ├── mt5_auto_runner.py # 自动运行回测
│ ├── batch_executor.py # 批量执行器
│ ├── result_parser.py # 解析HTM/XML报告
│ ├── report_generator.py # 生成汇总报告
│ ├── symbol_resolver.py # 根品种别名解析(symbol_aliases 查表)
│ └── optimizer/ # EA优化系统
│ ├── ea_config_parser.py # EA配置解析
│ ├── smart_search.py # 搜索策略
│ ├── parameter_constraint.py # 参数约束
│ ├── analyze_results.py # 结果分析
│ └── ea_batch_optimizer.py # 批量优化器
├── config/ # 配置文件
├── reports/ # 回测报告目录
├── tests/ # 自检脚本(test_symbol_resolver / test_ini_generator / smoke_alias_backtest
├── optimizer/ # 优化系统目录
│ ├── configs/ # EA配置
│ ├── set_files/ # SET文件
│ ├── reports/ # 优化报告
│ └── results/ # 分析结果
└── logs/ # 日志目录
```
## 常见问题
### Q: MT5 终端路径不正确
修改 `config/ea_configs.yaml` 中的 `terminal_path` 为实际路径
### Q: 报告文件未生成
1. 检查 MT5 是否正常启动
2. 查看 `logs/batch_executor.log` 日志
3. 确认 `data_dir` 配置正确
### Q: 中文显示乱码
HTM 报告采用 UTF-16-LE 编码,result_parser.py 会自动处理,无需手动转换
### Q: 想用 MT5 自定义品种(如 XAUUSDc)跑同一 EA
`config/ea_configs.yaml``backtest_settings` 下加:
```yaml
symbol_aliases:
XAUUSD: XAUUSDc
```
yaml 符号表里仍写 `XAUUSD`,系统会自动把 INI 的 `Symbol=` 替换为 `XAUUSDc`
详见上文"根品种别名映射"一节。
### Q: 改了 `symbol_aliases` 后 GUI 提示没变
GUI 启动时读取一次 `config/ea_configs.yaml`,改完后重启 GUI 即可看到
`→ XAUUSDc` 提示标签更新。无需重新生成报告历史。
## 许可证
MIT License