首页 / 交易学院 / EA 交易事件处理:用 OnTrade() 监控每一笔成交
EA 交易事件处理:用 OnTrade() 监控每一笔成交

EA 交易事件处理:用 OnTrade() 监控每一笔成交

交易事件、OnTrade 触发次数、订单/持仓快照对比法

EA 开发实战 难度 · 进阶 2026-07-11 9 分钟阅读
#EA#OnTrade#交易事件#事件驱动#监控

很多 EA 在 OnTick 里一遍遍检查持仓和挂单,既浪费资源又不及时。MQL5 提供了“交易事件”:每当订单或持仓列表发生变化,终端会自动调用 OnTrade() 函数。把监控逻辑放进 OnTrade,等于让终端在成交发生的那一瞬主动通知你。

一、交易事件与 OnTrade()

OnTrade() 是预定义事件处理函数,交易动作完成时由系统自动调用。常见用途:记录交易日志、弹窗/推送通知、统计成交质量。注意它和 OnTick 是两套机制——价格变动走 OnTick,交易变动走 OnTrade。

⚠ 一个市价开仓会触发 4 次
下单(订单列表变)→ 交易执行 → 订单与交易进入历史 → 开启持仓。这 4 个节点各调用一次 OnTrade(),所以不要在 OnTrade 里假设“调用一次 = 一笔成交”。

二、实测限制:别迷信历史触发

作者与官方开发人员确认:历史列表的变更并不会触发 OnTrade(),且运行期去读历史里的已执行订单可能有延迟。OnTrade 只在“已下订单”和“新建持仓”列表变更时被调用。因此判断事件类型要靠“订单/持仓数量与属性对比”,而不是单纯读历史。

三、订单数量对比法

用一个全局变量 OrdersPrev 记住上一次 OnTrade 时的 OrdersTotal()。OnInit 里初始化,OnTrade 末尾更新。若 OrdersPrev < OrdersTotal() 表示有新订单出现;若大于,表示有订单消失/被执行。这是判断“新增”还是“消失”的最简方法。

四、持仓/挂单参数快照对比

定义结构体(如 _position 含 sl/tp/volume)和获取函数,在 OnTrade 开头刷新“当前快照”,与“上一次快照”比较。当订单数和持仓数都没变时,逐条比对 SL/TP,有变化就提示“修改了止损/获利”。挂单同理用 _orders 结构体比对。

五、事件分类:switch 区分建仓/平仓/反向

订单消失时,用 HistorySelect 拉取历史,取最后一笔成交的 DEAL_ENTRY(IN 建仓 / OUT 平仓 / INOUT 反向 / STATE 状态)配合 DEAL_TYPE(0 买 1 卖)区分动作,再用 Alert 报出品种与盈亏。全程配合 GetLastError / ResetLastError 避免误判。

✦ 小布盯盘的视角
事件驱动天然比轮询省资源、响应快。我们的面板也采用“发生即通知”的思路:成交、改止损、平仓都即时体现在状态里,而不是靠刷新去猜。

小结

常见问题

订单列表或持仓列表发生变更时由终端自动调用,例如下单、成交、开仓、平仓、修改挂单。它和 OnTick 独立:价格变动走 OnTick,交易变动走 OnTrade。
因为开仓经过四个状态节点:提交订单、交易执行、订单与成交进入历史、建立持仓。每个节点都算一次“列表变更”,所以会连续触发 4 次。
用订单数量对比(OrdersPrev vs OrdersTotal)确定新增或执行,再从历史取最后一笔成交的 DEAL_ENTRY:IN 是建仓、OUT 是平仓、INOUT 是反向;配合 DEAL_TYPE 区分买卖。
轮询每 tick 都检查,浪费 CPU 且延迟随逻辑复杂度上升;OnTrade 是事件驱动,只在交易真的发生时执行,省资源、响应即时,更适合做通知与日志。