前阵子看监管那边又收紧了算法交易的报备要求,不少汇友在群里聊到EA合规的事,我倒是想起自己刚摸MQL5那会儿的一段经历。当时写了个欧美1小时图的挂单策略,逻辑跑回测挺顺,可一上VPS实盘就发现不对劲——每次K线收线后要等好几秒才下单,行情都窜出去一截了。折腾半天才明白,问题出在我压根没搞懂MQL5的定时器机制,靠 sleep 硬扛,结果整个EA的响应节奏全乱了。今天就把这块从零理一遍,给刚碰MQL5的朋友少走点弯路。
先说 EventSetTimer() 这个函数,它相当于给EA装了个闹钟。语法不复杂,EventSetTimer(1) 就是每秒触发一次 OnTimer() 回调。关键是新手容易把它当成 setInterval 随便用,我一开始就设成1秒,结果在400倍杠杆的账户上同时开三个货币对,回调里又塞了一堆订单查询,CPU直接顶到VPS的报警线。后来改成 EventSetTimer(5),把非紧急的持仓状态检查扔进去,下单逻辑还是走 OnTick,才稳定下来。记住:定时器适合做轮询类的轻活,高频计算别往里塞。
具体落地我踩过的坑列一下:
再提一句事件驱动的思路。MQL5除了定时器,还有 OnTrade() 和 OnTradeTransaction() 这类交易事件,比死循环轮询优雅得多。我现在的习惯是:定时器负责定时体检,交易事件负责即时响应,例如挂单成交后立刻用 OnTradeTransaction 记录成交价和滑点,写到文件里方便复盘。VPS上跑的话,定时器周期别低于1秒,网络稍有抖动就容易堆回调。
这块入门其实不难,难的是把节奏控制住。你们平时用定时器做哪些轮询任务,有没有遇到过回调堆积的情况?跟帖说说自己的配置参数。😊
先说 EventSetTimer() 这个函数,它相当于给EA装了个闹钟。语法不复杂,EventSetTimer(1) 就是每秒触发一次 OnTimer() 回调。关键是新手容易把它当成 setInterval 随便用,我一开始就设成1秒,结果在400倍杠杆的账户上同时开三个货币对,回调里又塞了一堆订单查询,CPU直接顶到VPS的报警线。后来改成 EventSetTimer(5),把非紧急的持仓状态检查扔进去,下单逻辑还是走 OnTick,才稳定下来。记住:定时器适合做轮询类的轻活,高频计算别往里塞。
具体落地我踩过的坑列一下:
- 回调函数名必须一字不差,写 OnTimer 就只能是 OnTimer,我手滑写成 OnTime 编译能过但永远不触发,排查了快一个小时
- OnDeinit 里务必调 EventKillTimer(),不然切换周期或卸载EA时定时器还在后台跑,我在MT5日志里见过一堆重复触发的记录
- 定时器和 OnTick 不要抢同一份数据,我的做法是 OnTimer 只更新全局变量做标记,真正下单交给 OnTick,避免订单状态读到一半被改
- 多品种EA用定时器时,给每个symbol单独算冷却时间,别用一个计数器通吃,镑美和黄金的波动节奏差太远了
再提一句事件驱动的思路。MQL5除了定时器,还有 OnTrade() 和 OnTradeTransaction() 这类交易事件,比死循环轮询优雅得多。我现在的习惯是:定时器负责定时体检,交易事件负责即时响应,例如挂单成交后立刻用 OnTradeTransaction 记录成交价和滑点,写到文件里方便复盘。VPS上跑的话,定时器周期别低于1秒,网络稍有抖动就容易堆回调。
这块入门其实不难,难的是把节奏控制住。你们平时用定时器做哪些轮询任务,有没有遇到过回调堆积的情况?跟帖说说自己的配置参数。😊
