Files
gavindiazandClaude Code ae47b4e30f feat: EURUSD 策略 + MT5 盈亏/仓位折算率修复 (tick_value 语义)
- mtlib: PnL/仓位统一走 报价货币->账户货币 折算率 (tick_value 语义),
  USDJPY 已用 demo 实盘+导出记录逐分验证关闭 (偏差 <0.01 USD)
- run_backtest/position_sizing 由注册商品自动推导折算率 (USD 报价对子恒 1.0)
- 新增 eurusd_scalp 策略 (M1 均值回归, MAGIC=2026091501) + 50k 数据
- 协议入口 AGENTS.md / CLAUDE.md / .mcp.json; 策略登记 MAGIC/DATA_FILE
- 验证记录 ReportHistory-52845377.html (12 笔 deal 交叉核对, smoke 47 PASS)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-18 20:08:53 +08:00

5.9 KiB
Raw Permalink Blame History

MT5 多策略量化工作区

MetaTrader 5 策略的回测 / 样本外验证 / 参数优化 / 实盘一体化工作区。 结构目标: 多策略 × 多商品, 回测与实盘信号同源, 杜绝逻辑漂移。

AI 代理入口协议: 任何 AI 改本仓库前先读 AGENTS.md(铁律/命名/魔术号, 由 python -m mtlib smoke 机器把关)。

前置依赖: 本项目根植于 mtdata MCP

整个工作区的数据、行情、分析与实盘交易全部建立在 mtdata 之上, 没有它什么都跑不了:

┌───────────────┐   mcp__mtdata__* 工具    ┌──────────────────┐   mtdata-cli(子进程)  ┌───────────────┐
│  Claude Code  │ ───────────────────────▶ │   mtdata 服务     │ ───────────────────▶ │ MetaTrader 5  │
│ (交互分析 + 本项目代码) │ ◀─────────────────────── │ (MCP Server / CLI) │ ◀─────────────────── │  (终端运行中)  │
└───────────────┘     行情/指标/分析/交易      └──────────────────┘         JSON 回传        └───────────────┘
  • 两条通道, 同一个后端: 交互分析时 Claude 直接调 mcp__mtdata__* MCP 工具; 策略代码一律经 mtlib/cli.py 调 mtdata-cli 子进程(唯一出口, 见该文件头注释)。
  • 前置条件:
    1. MetaTrader 5 终端运行中且已登录;
    2. mtdata-cli / mtdata-stdio 已安装并在 PATH;
    3. Claude Code 已注册 mtdata MCP(本项目已配好):
      • 用户级(所有项目可用): claude mcp add -s user --transport stdio mtdata -- mtdata-stdio
      • 项目级(双保险): 仓库根 .mcp.json(同定义); 修改后重启 Claude Code 生效。
  • 参考文档(随仓库提供): mtdata MCP 详细说明书.md(全部工具契约与坑) / 指标列表.md(193 个可内嵌指标)。
  • 版本注意: 用户级 MCP 配置存在 ~/.claude.json, 不是 ~/.claude/mcp.json(后者当前版本不读取)。

目录结构

mtlib/                    # 公共核心库 (与具体策略无关)
  data.py                 #   数据加载 (唯一入口)
  instruments.py          #   商品事实注册表 (点差/合约/时段, 实测后填写)
  cli.py                  #   mtdata-cli 封装 (参数契约/去重/下单/平仓)
  backtest.py             #   回测引擎 (唯一)
  metrics.py              #   绩效指标 (唯一)
  plot.py / walkforward.py / console.py / __main__.py
strategies/<name>/        # 一个策略一个目录
  strategy.py             #   唯一信号源: generate_signals + generate_signal_at 共用 _check
  params.py               #   策略参数 (dataclass)
  backtest.py / walkforward.py / optimize.py / session_analysis.py / live.py
data/                     # K线 JSON
tools/                    # 数据拉取 / 点差实测 (规划中)

常用命令 (仓库根目录, 一律 python -m)

命令 作用
python -m mtlib smoke 冒烟测试: 一致性把关 (~30s, 改动前必跑)
python -m strategies.xauusd_scalp.backtest 回测
python -m strategies.xauusd_scalp.walkforward 样本外验证 (前后两半)
python -m strategies.xauusd_scalp.walkforward + XAUUSD_SPREAD=0.22 点差压力测试
python -m strategies.xauusd_scalp.optimize 参数网格优化
python -m strategies.xauusd_scalp.session_analysis 时段/星期/方向分析
python -m strategies.xauusd_scalp.live 实盘/模拟盘 (默认 dry-run 预览)

旧文件名 (python xauusd_scalp_backtest.py 等) 保留为薄壳, 转调新命令。

实盘安全开关

  • 默认预览模式, 绝不发单: XAUUSD_DRY_RUN 未设置或非 0
  • 真实下单: XAUUSD_DRY_RUN=0 python -m strategies.xauusd_scalp.live
  • 点差覆盖(压力测试): XAUUSD_SPREAD=0.22 ...

开始一个新策略 (5 步)

  1. 注册商品: 在 mtlib/instruments.py 添加一个 Instrument(必须填实测点差与交易时段; 禁止拍脑袋)。
  2. 复制目录: strategies/<name>/ 复制 xauusd_scalp/。
  3. 写信号: 在 strategy.py 只改 _check(或重写信号逻辑), 同时保留 generate_signals + generate_signal_at 双入口。
  4. 改参数: 编辑 params.py 的 StrategyParams。
  5. 验证: 跑 python -m mtlib smoke(信号双入口一致断言会自动覆盖新策略)。

铁律: 信号逻辑只写一份。任何"实盘另写一份信号"的冲动都是 bug。 回测假设(成交价/点差/滑点)口径见 mtlib/backtest.py 头注释。

2026-09 重构记录 (三个显式行为修正)

重构时统一了三处旧脚本间的漂移, 数字与旧版不同是预期的:

项目 旧值 新值(统一) 影响
时段过滤 回测/实盘用离散 {7,8,9,10,16,17,18,20}; optimize/session_analysis 用区间 (7-16)∪(12-21) 全部离散集合 (来自 instruments) optimize/session_analysis 信号集合变化
点差 backtest/walkforward/optimize=0.16, session_analysis=0.06 全部 0.16 (商品实测) session_analysis 结果变化
回测签名默认值 tp=2.0/sl=1.0/step=0.5 (从未实际使用) tp=1.2/sl=0.6/start=1.0/step=0.2 无 (main 早已传 1.2/0.6/0.2)

另修复 walkforward 判定: 旧逻辑"测试半 PF>1 即判泛化"会漏过训练半亏损的过拟合; 新逻辑要求两半都 PF>=1 且收益>0。

验证哲学

  • 回测只是筛选器, 不是结论。样本量 50 笔/段远远不够。
  • 判读顺序: 样本外两半都正 → 点差压力测试 → demo 真实成交 2~4 周对照实际滑点/点差。
  • 任何改动前跑 python -m mtlib smoke。