把 MT5 的历史行情搬到 MT4 里用,看起来只是换个文件夹,实际上格式、时区、报价精度三样都得对上。
很多投资者换经纪商或换平台后,第一件事就是把旧平台的历史数据倒进新平台,好让图表和回测有"过去"可看。但 MT4 和 MT5 虽然同出一门,历史数据的存放格式完全不同,直接复制粘贴通常只会得到一片空白图表,或者一张价格明显错位的图。
更麻烦的是,错位的数据不会报错。它安安静静地躺在那里,你用它跑策略测试,得到一份漂亮的资金曲线,然后在真实账户上亏钱——因为回测里那根"伦敦开盘的大阳线",实际上是凌晨三点的一根小波动。下面就说清楚这件事:MT5 的历史数据,到底怎样才能变成 MT4 认得的行情。
MT4 的 .hst 文件和 MT5 的历史缓存,差在哪
一句话定义:把 MT5 历史数据转成 MT4 历史行情,就是把 MT5 平台保存的 K 线记录,按时区、精度和二进制格式重新排布,写成 MT4 能读懂的 .hst 文件。
可以把它类比成把一份外文手写稿翻译成另一国语言的印刷排版:内容还是那些内容,但字母要换成对方认得的字符,行距页边要按对方的规矩排,否则排版机读进去只会吐出一堆乱码。这个类比只到"格式转换"为止,它不涉及两边的行情本身是否一致——那是另一件事。
两边的差别主要在三个地方:MT5 的历史数据以 .hcc 一类的缓存文件保存,带压缩与索引,MT4 只认 .hst;两者的时间戳都按"服务器时间"记录,但不同经纪商的服务器时区可能差一到两小时;MT4 的 .hst 文件头里明确写着品种名、报价位数和周期,这些字段必须和 MT4 里实际存在的品种严格对应。
从 MT5 导出到 MT4 能读的完整流程
• 先从 MT5 导出中间格式。用 MQL5 脚本或 Python 的 MetaTrader5 模块,按品种、周期、起止时间调用复制行情的函数,把结果存成 CSV,字段至少包含时间、开、高、低、收、成交量。这一步要明确记录导出的时间戳是 UTC 还是服务器时间,后面所有换算都以此为准。
• 对齐时间基准。如果两边经纪商服务器时区一致(不少都设在 GMT+2 或 GMT+3 并跟随夏令时),时间戳可以原样保留;不一致就整段平移。平移是"整段一起挪",不是改某一天的某一根。
• 处理符号名与报价精度。MT4 里常见的 EURUSD、EURUSD.a、EURUSDm 是三个不同品种,文件头里的符号名必须和 MT4 品种列表里那一个完全一致。五位数报价转四位数品种时,要按目标位数四舍五入,而不是简单截断。
• 写 .hst 文件。文件由 148 字节的文件头加若干条 44 字节的 K 线记录组成,记录里依次是时间(4 字节整数)、开高低收(各 8 字节浮点数)、成交量(8 字节浮点数)。记录必须按时间升序、无重复。
• 放进 MT4 数据目录。把文件放到 MT4 数据文件夹下 history 目录中对应服务器名的子目录里,用"历史数据中心"导入或直接覆盖后重启客户端,再打开图表按 F2 检查根数和时间范围。
三个带数字的换算例子
例子一:时区平移。MT5 服务器是 GMT+3,MT4 服务器是 GMT+2,两边差 3600 秒。你在 MT5 上看到 2023-01-02 09:00 那根 H1 的开盘价是 1.07000,如果原样写入,MT4 会在自己的 09:00 画出这根 K 线,而它实际对应的是目标服务器时间 08:00 的行情。修正方式是把这一段的每个时间戳各减去 3600 秒,1000 根 H1 就是整段前移一小时。没有这一步,所有"只在某时段交易"的规则都会整体错位。
例子二:报价精度取舍。MT5 上 EURUSD 报价 1.08432,目标 MT4 品种设定为四位小数。若直接截断成 1.0843,单次偏差是 0.00002。1 标准手是 100000 单位货币,0.00002 × 100000 = 2,也就是每笔交易在价格上差出约 2 美元;若这 2 美元出现在一万根 M1 的每一根上,回测的进出场价和盈亏统计都会被系统性地拉偏。正确做法是按目标位数四舍五入:1.08432 变 1.0843,1.08436 变 1.0844。
例子三:用文件体积反推根数。假设你要导入 1000000 根 M1,文件大小应为 148 + 1000000 × 44 = 44000148 字节,约 41.96 MB(44000148 ÷ 1024 ÷ 1024)。拿到文件先做一次校验:(文件大小 − 148)能否被 44 整除。多一根或少一根,MT4 读到文件尾部时就会解析错位,表现为最后几根 K 线价格变成天文数字或直接不显示。
四个容易踩的认知陷阱
• 以为复制文件夹就行。把 MT5 的 bases 目录整个拷到 MT4 数据目录下,MT4 一个字节都读不懂。格式不同,不是路径问题。
• 以为数据越多越好。导入十年的 M1 有上千万根 K 线,MT4 加载和策略测试会明显变慢,而早期数据本身的缺口和异常值也更多。够用即止,通常比"尽可能长"更划算。
• 以为两边的 H1 是同一根 H1。周期标签相同,不代表划分边界相同。服务器时区差一小时,两边的日线收盘时刻就不一样,跨日、跨周的策略在这上面最容易出问题。
• 以为成交量可以直接比较。MT4 的成交量通常是报价跳动次数,和 MT5 里可能提供的真实成交量不是一回事,用成交量做过滤条件时不能混用。
动手之前、转换之中、导入之后
动手之前
• 先记下两边经纪商的服务器时区、夏令时规则和品种的报价位数,这三项决定后面所有换算,写下来再动手。
• 确认目标 MT4 里已经存在同名品种并刷新过报价,否则导入的数据没有地方挂靠。
转换之中
• 全程保留一份原始 CSV,任何调整都在副本上做,出问题时可以回退重来,而不是从头再导一次。
• 每转换一个周期就抽样核对:随手挑三个时间点,把两边同一时刻的开高低收逐项对照,出现不一致先停下来查。
导入之后
• 用 F2 打开历史数据中心,检查首尾时间、K 线根数和最大最小价格是否落在合理区间,再看图表有没有异常的长影线。
• 拿一个你熟悉的历史事件日期在图上定位,比如某次重要数据公布当天的波动,位置对不对,一眼就能看出来。
风险提示与常见问题
历史数据转换只是把记录搬家,它不改变数据本身的质量,也不保证两边的报价一致。不同经纪商的报价来源不同,点差和滑点在历史 K 线里往往只体现为价格差异,转换过程中还会额外引入舍入误差。用转换来的数据做回测,结果和真实成交之间天然存在距离,任何据此得出的收益预期都应当打折看待。转换前务必备份原始数据,转换后不要直接投入实盘决策。
问:转过去之后,回测结果为什么和在 MT5 里差很多?
多半是时区没对齐或报价位数改了,先核对两边同一根 K 线的时间与收盘价。
问:一定要用专门的转换工具吗?
不一定,写一段简单脚本按格式拼字节也可以,前提是严格按文件头和记录长度来。
问:能把 MT5 的逐笔数据也转过去吗?
MT4 的历史文件按 K 线存储,逐笔数据只能先合成对应周期的 K 线再写入。
