开发回放系统 市场模拟(第 04 部分):调整设置(II)·综合运用
「用历史tick文件驱动MT5回放」
想在不接真实行情的情况下复盘某段行情,可以借助 Market Replay 类把历史 tick 文件注入到 MT5 的图表里。下面这段脚本以 WINZ21_202110220900_202110221759 这一小时级别的 tick 文件为例,在 OnStart 里直接拉起回放窗口。 回放不是一启动就自己跑,脚本先等全局变量 def_GlobalVariableReplay 出现(每 750 毫秒轮询一次),拿到权限后才打印「Replay system started」。这一步卡住很正常,没开回放控制面板就会一直 Sleep。 核心推进逻辑在 while 循环:未播放时调 Event_OnTime 探一下有没有待处理事件;播放中则按 delay 节拍走,delay 默认 3 毫秒,若 AdjustPositionReplay 返回 0 就复位成 3,否则沿用返回值。外汇与贵金属回测属高风险,历史tick重播结果只代表该样本表现,换时段可能完全走样。 让小布替你跑这套 把 user01 改成你自己的 tick 文件名(格式 YYYYMMDDHHMM_YYYYMMDDHHMM),编译前确认 Include 路径下有 Market Replay\C_Replay.mqh,否则 CreateSymbolReplay 直接返回失败。
class="macro">#class="kw">property copyright "Daniel Jose" class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#include <Market Replay\C_Replay.mqh> class=class="str">"cmt">//+------------------------------------------------------------------+ class="kw">input class="type">class="kw">string user01 = "WINZ21_202110220900_202110221759"; class=class="str">"cmt">//File with ticks class=class="str">"cmt">//+------------------------------------------------------------------+ C_Replay Replay; class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class="type">class="kw">ulong t1; class="type">int delay = class="num">3; class="type">long id; u_Interprocess Info; class="type">bool bTest = class="kw">false; if (!Replay.CreateSymbolReplay(user01)) class="kw">return; id = Replay.ViewReplay(); Print("Wait for permission to start replay ..."); class="kw">while (!GlobalVariableCheck(def_GlobalVariableReplay)) Sleep(class="num">750); Print("Replay system started ..."); t1 = GetTickCount64(); class="kw">while ((ChartSymbol(id) != "") && (GlobalVariableGet(def_GlobalVariableReplay, Info.Value))) { if (!Info.s_Infos.isPlay) { if (!bTest) bTest = (Replay.Event_OnTime() > class="num">0); }else { if (bTest) { delay = ((delay = Replay.AdjustPositionReplay()) == class="num">0 ? class="num">3 : delay); bTest = class="kw">false; t1 = GetTickCount64(); }else if ((GetTickCount64() - t1) >= (class="type">uint)(delay)) { if ((delay = Replay.Event_OnTime()) < class="num">0) class="kw">break; t1 = GetTickCount64(); } } } }
回放系统的停止与收尾
在 MQL5 回放逻辑里,停止动作往往藏在某个条件分支的末尾,而不是单独写个 Stop 函数。上面这段截断的代码显示,当外层判断不成立时,先闭合内层花括号,再闭合外层花括号,随后调用 Replay.CloseReplay() 释放回放资源,并打印 "Replay system stopped ..." 作为终止信号。 这种写法意味着回放句柄在退出前必须显式关闭,否则 MT5 策略测试器里的可视化回放可能占用内存句柄不释放,再次启动同符号回放时概率出现「旧帧残留」。 复制这段代码到你的 EA 收尾段,把 Print 内容改成带时间戳的自定义串,跑一次 EURUSD 的 M1 回放就能验证关闭是否干净。外汇与贵金属回放涉及杠杆品种,历史重演不代表未来,实盘前务必用小资金验证。
} } Replay.CloseReplay(); Print("Replay system stopped ..."); class=class="str">"cmt">//+------------------------------------------------------------------+
◍ 回放系统落地前的最后提醒
附件里的 Market_Replay.zip 约 10.8 MB,内附两份真实市场跳价文件,可在不同跳价密度的交易日里试跑移动与定位。当前版本在把光标拖到目标价位点时,移动执行偶有卡顿,作者确认后续会修,但眼下不影响你熟悉整套回放逻辑。 用这套回放真正能练的是市场分析本身,而不是找某个绝对入场点——你看到的走势可能实际发生在几根柱线之后,外汇与贵金属市场高杠杆、跳价稀疏时段尤甚,误把回放里的‘清晰信号’当实盘依据概率上会吃亏。 有读者在评论里问过:EA 能否接管回放服务、停掉图表绘刻?作者回说只需在 EA 里加一行代码即可,但前提是把这行代码在 MT5 里的机制先弄懂,相关文章还没发。想验证的人,现在就能做的动作是:下载 ZIP,用经纪商 tick 数据替换附件样本,跑一遍看百分比推进是否符合你的预期。