Ⅲ · 逐项对照 — 3.2
策略生命周期
不要把回调名当作词典翻译。先看策略何时启动、收到什么事件、如何恢复状态与如何结束。
生命周期不是函数名对照表
三个系统都需要初始化、处理市场和订单事件、结束时释放资源,但触发者不同:MQL5 是终端中附着到图表的程序;Nautilus 是引擎管理的策略组件;LEAN 是由 Engine 运行的算法对象。因此下图和表格按发生阶段整理,而不是暗示存在一一对应的函数翻译。
| 阶段与要解决的事 | MQL5 | NautilusTrader | LEAN |
|---|---|---|---|
| 配置与初始资源 | OnInit(),创建句柄、读取输入参数、确认资源可用 |
构造后可用 on_load() 恢复已保存的策略状态,再以 on_start() 开始运行 |
initialize(),添加证券、设置现金、指标、调度和模型 |
| 指标或历史状态是否可用 | 指标自行处理历史数组、buffer 空值和 EA 的启用条件 | 策略自行装载或请求历史,并检查指标是否已初始化 | 可先 warm-up:历史数据照常流过回调,但预热期不允许交易 |
| 市场数据到来 | OnTick(),指标则由 OnCalculate() 处理计算事件 |
on_quote_tick、on_trade_tick、on_bar 等按数据类型拆开 |
on_data(slice) 收到同一时刻的数据集合 |
| 定时或日历动作 | OnTimer(),开发者自行处理交易日与假期 |
配置时钟或定时事件 | schedule.on(...) 可与市场日历规则结合 |
| 订单结果 | OnTradeTransaction() 中根据交易事务类型分支 |
on_order_accepted、on_order_filled、on_order_denied 等具名回调,也可在 on_order_event 汇总处理 |
on_order_event(order_event),从事件对象读取状态、成交量和原因 |
| 持仓层事件 | 需要由交易事务或账户查询自行归纳 | on_position_opened、changed、closed 把持仓状态变化单列 |
从订单事件和 Portfolio 状态读取,框架没有同名持仓回调 |
| 保存、故障与退出 | OnDeinit(),持久化或清理需要自行约定 |
on_save / on_load 可作为状态持久化约定;另有 on_degrade、on_fault、on_stop、on_dispose |
on_end_of_algorithm() 用于正常结束;另有经纪商连接、保证金和公司行动等特定事件 |
三个最容易写错的位置
**订单已请求,不等于已成交。**三个系统都能在订单结果回来后触发处理,但 MQL5 将多种事务合并进 OnTradeTransaction,Nautilus 细分为具名订单或持仓回调,LEAN 将信息放进一个类型化 OrderEvent。写仓位、止损或审计记录时,应该依赖结果事件,而不是发单函数返回后就假定成交。
**预热、恢复和初始化不是同一件事。**LEAN 的 warm-up 是把较早市场数据回放进正在初始化的算法。Nautilus 的 on_load 是恢复策略此前保存的状态。MQL5 的 OnInit 是程序加载后的入口。它们可能都发生在“开始前”,但输入和应做的事情不同。
**结束至少有两个层次。**策略需要停止接收新工作,还需要释放资源或持久化状态。Nautilus 把 on_stop 与 on_dispose 分开,适合让策略明确区分“停止交易”与“对象销毁”;MQL5 和 LEAN 则将大部分结束清理集中在各自的 deinit/end 回调中。
迁移现有 EA 时,不应把 OnTick 的整段代码机械塞进 on_bar 或 on_data。先标出其中哪些是数据更新、下单意图、订单结果处理、状态恢复与界面更新,再放进对应阶段,测试点才会清楚。