上个月一个做手工交易的朋友给我发消息,说他从MT4里导出最近半年的交易记录,想拉到Excel里画资金曲线。结果CSV一打开,时间那一列全是“######”,改成日期格式之后,又发现每个订单的开仓时间都跟他记忆里的对不上,差了整整三个小时。
我第一反应是,他是不是直接用了MT4自带的“保存为详细报告”那个功能?他说是。那个功能导出来的是html格式,拿去Excel里处理那是自找麻烦。正确的姿势应该是去“历史中心”(按F2),选中品种,然后点“导出”。但就算这样,出来的CSV文件也有一堆暗坑等着你。
他遇到的第一个问题就是时区。MT4的服务器时间通常设成GMT+2或者GMT+3(夏令时切换),而他本人是东八区的。导出来的CSV里,时间戳是按服务器时间存的,往Excel一贴,默认按本地时区显示,里外里差了好几个小时。他一开始还以为是数据坏了,拿历史中心的界面跟CSV比对了半天,发现界面上显示的时间是正常的,但导出来的文件就不对。
这就说明了一个事儿:“历史中心”的界面显示和“导出”功能用的不是同一套时间转换逻辑。我当时跟他说,别用那个手动导出按钮了,直接写个脚本拉数据。
我翻了翻MQL4官方文档(docs.mql4.com)里“文件操作”那一章,里面写
FileWrite函数处理datetime时,格式取决于终端当前的时区设置。这就是问题的根源。我给他写了个小脚本,直接用HistorySelect()和HistoryDealGetInteger()拿原始时间戳,然后手动加上时区偏移量再写进文件。核心代码片段是这样的:
``
mql4
void OnStart()
{
int handle = FileOpen("MyHistory.csv", FILE_CSV|FILE_WRITE, ",");
if(handle == INVALID_HANDLE) return;
HistorySelect(0, TimeCurrent());
int total = HistoryDealsTotal();
FileWrite(handle, "订单号", "开仓时间", "类型", "手数", "价格");
for(int i=0; i
{
ulong ticket = HistoryDealGetTicket(i);
datetime openTime = (datetime)HistoryDealGetInteger(ticket, DEAL_TIME);
long type = HistoryDealGetInteger(ticket, DEAL_TYPE);
double volume = HistoryDealGetDouble(ticket, DEAL_VOLUME);
double price = HistoryDealGetDouble(ticket, DEAL_PRICE);
// 手动把服务器时间(GMT+3)转成北京时间
openTime += 10800; // 东八区比GMT+3快5个小时,但这里我直接加3小时只是为了演示原理
FileWrite(handle, ticket, TimeToString(openTime, TIME_DATE|TIME_MINUTES), type, volume, price);
}
FileClose(handle);
}
`
这个脚本跑完之后,时间对上了,但他又说数据不全。他明明是3月份开始做的交易,但导出来的记录只从5月份开始有。中间两个月的单子人间蒸发了。
这次我让他别急着折腾脚本,先看看“历史中心”里手动显示的数据是不是完整的。他点开一看,发现界面里也只显示到5月份。那问题就很清晰了——不是导出坏了,是本地缓存的FXT文件被截断了。
后来我在MetaQuotes官方帮助中心(help.metaquotes.net)翻到一个技术帖,里面提到MT4的“历史中心”显示的内容取决于当前终端缓存里加载了多少K线。如果你之前做过“压缩数据库”的操作,或者你的经纪商用了自定义的FXT压缩算法,那么早于某个时间点的历史数据可能已经被归档,不会出现在标准的导出列表里。
真正的解决方法是这样的:先去 “工具” > “选项” > “图表”,把“历史K线最大数量”和“图表中K线最大数量”这两个数值直接拉到最大,比如500万根。然后关掉MT4再重开。接着按F2打开历史中心,在任意品种上右键,选“刷新”。这个“刷新”动作很关键,它会强制MT4重新从.hst文件里读取完整的历史数据,而不是只加载内存里那部分。做完这步再导出,所有缺失的记录就都回来了。
最后再说Excel那边的格式问题。如果导出来之后时间那列还是一串数字(比如44927.5),那是Excel把日期当成序列号了。你选中整列,右键“设置单元格格式” -> “自定义”,在类型里手动敲进去 yyyy-mm-dd hh:mm:ss。如果敲完还是不行,就去检查你的Windows区域设置——Excel的日期分隔符是跟着系统走的,跟MT4半毛钱关系都没有。
现在我的习惯是:但凡涉及到导出历史数据做分析的,一律写脚本走HistorySelect`接口,绝不依赖手工导出。写一个脚本也就十分钟,但能让你省下好几个小时对着乱码发呆的时间。参考来源:
---
本文首发于FXEAR.com,原创内容,未经授权禁止转载