EA 交易事件处理:用 OnTrade() 监控每一笔成交
交易事件、OnTrade 触发次数、订单/持仓快照对比法
一、为什么需要 OnTrade
下单不是「发了就完事」:成交可能部分成交、被拒、或因滑点价格不同。EA 需要知道「我的单到底成没成、成了多少、成交价多少」,才能正确更新状态、决定下一步。OnTrade 就是终端在成交/持仓/订单变化时通知 EA 的钩子,是连接「发单」与「知单」的桥梁。
没有 OnTrade,EA 只能在下一次 OnTick 里去查持仓猜结果,既慢又容易在快速波动里误判。把成交后的状态同步交给 OnTrade,主逻辑才干净。
二、OnTrade 的触发时机
当订单被成交、被拒、持仓被修改或删除时,终端会调用 OnTrade()。它不传参数,你要在函数里用 PositionsTotal / HistorySelect 等主动查询「现在发生了什么」。关键是:OnTrade 可能在一次下单后连续触发多次(如部分成交再补全),逻辑要能处理重复通知。
三、用 OnTrade 同步状态
典型用法:在 OnTrade 里检查当前持仓,更新「是否已开仓」「入场价」「订单ticket」等状态变量。这样无论成交发生在哪个 tick,EA 的状态都能及时跟上,下一根 OnTick 看到的就最新。
void OnTrade()
{
bool has = (PositionSelect(_Symbol));
if(has) myOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
myHasPos = has;
}
四、OnTrade 与 OnTick 的分工
规则很清晰:OnTick 负责「决策与发单」(看信号、算手数、调 CTrade),OnTrade 负责「成交后同步状态」(更新持仓、记录成交价)。不要把下单逻辑塞进 OnTrade,也别在 OnTick 里反复轮询成交——各管一段,代码不打架。
五、处理部分成交与拒绝
市价单在大行情里可能部分成交(只成一部分),限价单可能根本不成交。OnTrade 里要能识别「订单状态」:用 OrderGetInteger(ORDER_STATE) 看是 FILLED / PARTIAL / CANCELED / REJECTED。对部分成交,要决定是补还是等;对拒绝,要记录原因(Retcode)而非假装成功。
六、实战:下单后确认成交
一个稳健模式:在 OnTick 里发单并记录期望 ticket;在 OnTrade 里核对 HistorySelect 后的实际 Deal,确认成交价/成交量,更新 myOpenPrice 与 myHasPos。若发现被拒,写日志并触发风控(如暂停 N 秒)。这条链路做扎实,EA 的「账」才清楚。
void OnTrade()
{
HistorySelect(TimeCurrent()-86400, TimeCurrent());
ulong tkt = myPendingTicket;
if(OrderSelect(tkt) && OrderGetInteger(ORDER_STATE)==ORDER_STATE_FILLED)
Print("filled at ", OrderGetDouble(ORDER_PRICE_FILL));
}
七、常见坑
- 在 OnTrade 里又发单,造成 OnTrade↔OnTick 互相触发死循环
- 不处理部分成交,按全仓管理导致手数错
- HistorySelect 时间窗太窄漏掉跨日成交
- 重复通知下重复更新导致计数错乱
八、用 OnTrade 触发风控与统计
OnTrade 不只是同步持仓,更是做账与事后动作的好地方。每次成交,你可以在这里累加当日成交笔数、记录实际成交价与期望值偏差、更新连续亏损计数,这些状态供 OnTick 的风控分支使用(比如连亏三笔后暂停新单)。把统计放进成交事件,能保证「每笔真实成交只计一次」,比在 OnTick 里轮询更准。
还可以用它触发通知:成交后 SendNotification 或写文件日志,让你在手机上第一时间知道 EA 已进场或离场,而不必盯着终端。注意通知类调用要轻量,别在 OnTrade 里再做重计算或下单,否则事件内部又触发事件,形成重入。
九、OnTrade 的重入与禁忌
终端在「一笔订单引发一连串成交」时,可能连续多次调用 OnTrade(比如部分成交、改仓、平仓拆成多条 Deal)。因此 OnTrade 里的代码必须是幂等且轻量的:只读持仓或历史、更新标量状态、发通知,不要在这里再下新单或做耗时循环。
若你确实需要在成交后做交易动作(例如平仓同时开反向仓),正确做法是在 OnTrade 里只置一个待处理标志,真正的发单留给 OnTick 去执行。这样既能响应成交,又规避了在事件回调里交易导致的不可预期行为。