Ⅰ · 概念地基 — 1.4

状态、账本与生命周期

生产系统与回测脚本的差别,几乎全部落在这一页。

持仓不是“查一下”,是一个组件

MT5 里想知道当前持仓,调 PositionsTotal() / AccountInfoDouble()——终端就是唯一真相,问一句就有答案。

自研平台里持仓是一个由事件驱动维护的组件:订单成交事件到达 → 更新持仓 → 重算未实现盈亏 → 更新保证金占用。它不“问”券商,它推演

为什么要推演而不是查?因为回测里没有券商可问。同一份策略要在两种模式下工作,持仓状态就必须由框架自己维护。

于是有了两份账本

框架内存账本由成交事件推演得出回测与实盘用同一套逻辑券商真实账本唯一的外部真相仅实盘存在漂移断线重连 · 部分成交 · 人工干预 · 强制平仓对账(reconciliation)启动与重连时拉取真实状态,为漏记的成交补录事件MT5 只有右边一份,所以结构上没有这个问题 —— 这是自研引入的新问题,而非改进项。
对账不是可选项。Nautilus 的实盘对账模块含 create_inferred_order_filled_event(为本地未记录的成交推断补录事件)、calculate_reconciliation_priceadjust_fills_for_partial_window ✓ 已实测——系统需要推断自己漏掉的成交,这个模块的存在本身说明问题是真实的。

组件有状态机,因为生产环境会出事

EA 的生命只有两个状态:OnInit() 成功了在跑,或者没跑。生产系统需要更细的划分——比如“行情断了但持仓还在,不能当作正常运行,也不能直接关停”。

Nautilus 的 ComponentState 实测有 14 个取值 ✓ 已实测

# 正常路径
PRE_INITIALIZED → READY → STARTING → RUNNING → STOPPING → STOPPED → DISPOSING → DISPOSED
# 恢复路径
RESUMING · RESETTING
# 异常路径 —— MT5 无对应概念
DEGRADING → DEGRADED    降级:部分功能不可用,但不停机
FAULTING  → FAULTED     故障:需要人工介入

状态迁移由 ComponentTrigger(15 个取值)约束,不能任意跳转。策略可以覆写 on_degrade() / on_fault() 来定义“降级时怎么办”——例如只平仓不开新仓。

**另一项 MT5 没有的能力:状态持久化。**Nautilus 的 on_save() / on_load() 是框架级回调,重启后策略内部状态可恢复。MT5 需要自行用 FileOpen 实现——这在实际项目中确实有人做(SaveExpertData / LoadExpertData),只是没有框架约定,每个 EA 各写各的。