Python回测跑通但MT5实盘报错,才发现tick数据格式藏了这个坑

较热59.7
登录发帖
XM 推荐平台

覆盖品种全,新手友好,支持多种入金方式

CySEC(塞浦路斯) / ASIC(澳洲) / IFSC(伯利兹) · 最低入金 $5
QuietWillow
QuietWillow 楼主 2026-9-17 22:24:10 浏览 518 回复 4 阅读 1 分钟
Lv.1 新手汇友 等级 Lv.1 主题 1 帖数 15 积分 1745 汇币 1515
1楼
回测里跑得再漂亮的夏普比率,也可能被实盘第一笔tick直接打回原形。我上个月用Python给一个欧美M15的均值回归策略做回测,三年数据年化夏普1.8,最大回撤6.2%,结果挂上MT5实盘第三天就报了数组越界,查了两天才发现是tick数据格式在作怪。
问题出在我用MT5的copy_ticks_from拉取历史tick时,默认返回的是带毫秒时间戳的float结构,而我在Python里用pandas解析时直接当成了秒级整数处理。回测阶段我图省事,用的是MT5导出的CSV,时间列已经被格式化成了"YYYY.MM.DD HH:MM:SS",两边的时间基准根本没对齐。实盘EA里我用numpy做滚动窗口计算,时间戳精度一错,窗口切片直接错位,报错信息只显示"index out of bounds",压根没提时间格式的事。
具体排查过程我列一下,给后面踩坑的汇友省点时间:
  • 第一步,先用MT5的脚本单独跑一遍copy_ticks_from,把返回的time和time_msc两个字段都打印出来。time是秒级,time_msc是毫秒级,很多人只取time,结果高频逻辑里相邻tick的时间差全是0,滚动窗口算出来全是NaN。
  • 第二步,在Python端统一转成datetime64[ms],别用默认的datetime64[ns],MT5的tick精度只到毫秒,转成纳秒后做resample容易产生空值。
  • 第三步,检查你用的回测框架,backtrader和vectorbt对时间索引的要求不一样。vectorbt默认要求DatetimeIndex是单调递增且无重复,MT5的tick里同一毫秒可能有多笔报价,必须先做drop_duplicates或者groupby聚合,否则实盘信号和回测信号在相同K线内会差出1到2个点。
  • 第四步,如果你在EA里用Python做信号计算再回传给MT5,注意socket传输时别用json默认的float序列化,时间戳会被截断成科学计数法,我在这上面浪费了整整一个下午。

另外提一个隐蔽的坑:MT5的tick数据里,bid和ask的last字段在非活跃时段可能是0,回测时如果不做过滤,点差计算会瞬间放大到几百点,策略直接触发止损。我现在的做法是在Python端加一层校验,last为0或者点差超过品种历史95分位数的tick直接丢弃,实盘和回测用同一套清洗逻辑,误差才压到可接受范围。
最后说下VPS部署的连带问题。我用的Windows VPS延迟在12ms左右,但Python进程和MT5终端如果不在同一台机器上,tick到达顺序和回测里的时间排序会有微秒级偏差。建议把Python信号模块直接跑在MT5所在的VPS上,用shared memory或者本地socket通信,别走外网。我现在跑欧美和镑美两个品种,实盘滑点控制在0.3点以内,和回测的偏差主要来自隔夜跳空,这个只能靠在回测里加入真实tick的gap处理来逼近。
你们在用Python对接MT5的时候,有没有遇到过tick时间戳精度导致信号错位的情况?或者有没有人试过用MT5的onTick事件直接驱动Python计算,而不是轮询拉数据?交流。

补充一句,copy_ticks_from返回的time字段单位其实是秒,毫秒在time_msc里,别问我怎么知道的。
0 回复 众裁0 复制
#1
pearl132
pearl132 #5· 7 天前
5楼
你提到copy_ticks_from返回带毫秒的float结构,我遇到的情况是同一毫秒多笔tick聚合取last会丢报价,改用numpy的searchsorted按time_msc对齐切片才不越界,实盘稳了。
赞 回复 众裁0 复制
7 天前 #5
EAMaintaineri
EAMaintaineri #4· 2026-9-19 20:21:04
4楼
你提到time_msc转datetime64[ms]这点我踩过同样的坑,之前只取time字段,欧美M1的滚动窗口相邻tick时间差全变0。我自己也做欧美M15,但用Dukascopy的tick补数据,发现毫秒精度下groupby聚合取last更贴近实盘撮合,vwap反而拖慢切片速度。
赞 回复 众裁0 复制
2026-9-19 20:21:04 #4
MistyMeadow
MistyMeadow #3· 2026-9-19 15:23:15
3楼
大佬,我卡在你说的drop_duplicates那步了,groupby聚合的话,同一毫秒多笔tick你是取last还是用vwap?我实盘就遇到过切片还是对不齐。
赞 回复 众裁0 复制
2026-9-19 15:23:15 #3
WanderLustv
WanderLustv #2· 2026-9-19 09:08:02
2楼
你说的time和time_msc两个字段这点太关键了,我之前也栽在只取time上,欧美M15高频逻辑里相邻tick时间差全变0,滚动窗口全是NaN。我自己也用过copy_ticks_from,后来统一转datetime64[ms]才稳,纳秒确实容易出空值。
赞 回复 众裁0 复制
2026-9-19 09:08:02 #2
THE END
本帖内容仅供学习交流,不构成任何投资建议。外汇交易存在高风险,请谨慎参与。
← 上一帖 EA回测盈利实盘却亏,先查MT4历史数据中心的报价缺口 下一帖 → 看了半天忍不住来发个帖,折腾MT5又搞到半夜