上周四帮一个做Prop Firm(自营交易)的哥们弄权益曲线,差点被他那个MT5账号搞得血压升高。他需要导出最近三个月的交易历史做成CSV提交审核。我寻思这不就是点几下鼠标的事?结果运行脚本直接给我弹了个红框:"History error: Failed to get data."
我先检查了日期范围。脚本里用的是固定字符串格式,比如"2026.01.01"。MQL5官方文档里关于日期和时间那一章其实已经提醒过了,推荐用
MqlDateTime结构体或者StringToTime转换,但我发现很多人图省事直接用字符串赋值,这在MT5里很容易被当成无效格式,直接报错返回空数据。转成datetime类型后,这个报错算是消停了。但最折腾人的还在后头。CSV是导出来了,可一打开Excel我就傻眼了——持仓跨过周末的单子,
Open(开仓价)和Close(平仓价)两列的数据对调了。我在MQL5里用HistorySelect拉数据的时候,没指定时区参数,结果MT5默认按服务器时间返回,周末K线跳空导致索引错位。这个坑在MetaQuotes官方帮助中心的"历史数据导出"说明里只提了一嘴"注意时区差异",但具体怎么处理压根没展开。这里讲一个我的独家处理思路:网上大多数教程教人直接用
HistorySelect(0, TimeCurrent())一把梭全拉出来。但如果你账号跑了一年以上的数据,这个方法会把分笔数据也拽下来,数据量暴涨,脚本卡半天。做权益曲线根本不需要那么细,只需要每个交易日结束时的Balance(余额)或者每笔平仓的盈亏DEAL_PROFIT就够了。我排查发现,问题出在
OrderGetDouble(ORDER_PRICE_OPEN)上,它返回的数值和HistoryDealGetDouble(DEAL_PROFIT)算出来的结果对不上,差了整整一个点。原因就是我拿本地的TimeCurrent()去和服务器时间做减法,没考虑夏令时切换。所以我的解决方案是:放弃按时间切片查询权益,改成逐笔交易累加盈亏,然后手工重算余额曲线。这样绕开了MT5内部时间戳对齐的模糊地带,出来的数据跟券商端的报表完全一致。
排查和解决步骤:
StringToTime("2026.01.01 00:00")统一转成datetime,否则HistorySelect不认。TimeCurrent()和服务器时间时,用TimeGMTOffset()获取偏移量,加在时间戳上再传入,避免周末跨天导致的收盘价错位。C:\根目录写文件,Win Server直接静默失败。正确的做法是用TerminalInfoString(TERMINAL_DATA_PATH)拼接\MQL5\Files作为导出目录,这是MT5授权过的安全区域。HistorySelectByPosition(按持仓单号选择)代替HistorySelect(按时间范围选),只拉取目标区间内的成交订单,大幅减少内存负担和导出耗时。参考来源:MQL5官方文档 - 日期和时间(docs.mql5.com);MetaQuotes帮助中心 - 历史数据处理(help.metaquotes.net)。
本文首发于FXEAR.com,原创内容,未经授权禁止转载。
```