3. 核心架构总览

核心架构总览 学习卡片

从回测迁移到实盘,最容易踩的坑不是策略逻辑本身,而是对框架运行机制的理解偏差。NautilusTrader 采用事件驱动架构,回测与实盘共享同一套核心组件,差异只在于数据来源和时钟推进方式。理解这套架构,是保证“回测能跑、实盘也能跑”的前提。

一、核心原理:一切皆事件,组件靠总线解耦

NautilusTrader 的中枢是 消息总线(MessageBus)。所有组件之间不直接互相调用,而是通过总线发布和订阅消息。数据引擎收到行情后发布 QuoteTick、TradeTick、Bar 等事件;策略订阅这些事件并产生订单命令;执行引擎接收命令后与交易场所交互,再把成交回报发布回总线;投资组合订阅成交事件更新持仓与盈亏。这种解耦让回测和实盘可以复用同一份策略代码。

围绕总线,几个核心组件各司其职:

  • NautilusKernel:系统内核,负责按配置装配所有组件、管理生命周期(启动、运行、停止)。
  • DataEngine:数据引擎,负责行情数据的接入、解析、缓存与分发,是策略的“输入口”。
  • ExecutionEngine:执行引擎,负责订单管理、路由到交易场所适配器、处理成交与拒单。
  • Portfolio:投资组合,跟踪账户、持仓、未实现与已实现盈亏,是风控和绩效的基础。
  • Cache:缓存,保存订单、持仓、账户、合约等状态,供各组件快速查询。
  • Clock:时钟,回测时由数据时间戳驱动,实盘时使用真实时间,是回测与实盘的关键差异点。
关键认知:回测与实盘的组件拓扑几乎一致,唯一显著区别是 Clock 与数据/执行适配器的实现。策略代码不应感知自己运行在哪种模式。

二、方法流程:一次行情到一次成交的完整链路

下面用一条行情驱动一次下单的链路,串起各组件协作流程:

  1. 数据适配器(回测为数据目录,实盘为交易所 WebSocket)产生原始行情。
  2. DataEngine 解析并标准化为内部事件,写入 Cache,再发布到 MessageBus。
  3. 策略的 on_bar / on_quote_tick 被触发,计算信号后调用 self.buy(...) 或 self.submit_order(...)。
  4. 订单命令经总线进入 ExecutionEngine,生成 Order 并写入缓存,再交给执行适配器。
  5. 适配器返回 OrderAccepted、OrderFilled 等事件,执行引擎更新订单状态并发布事件。
  6. Portfolio 订阅成交事件,更新持仓、现金与盈亏;策略的 on_order_filled 同步被调用。

这条链路在回测和实盘中完全一致,区别仅在于第 1 步和第 5 步的适配器实现。因此迁移时,重点检查的是适配器配置与时钟行为,而不是重写策略。

三、案例/场景:从回测配置迁移到实盘配置

回测时通常使用 BacktestEngine 并加载本地数据;实盘时改用 TradingNode 并接入交易所适配器。两者共享策略类,但配置结构不同。下面是一个对比清单:

维度 回测(BacktestEngine) 实盘(TradingNode)
时钟 由数据时间戳推进 真实系统时间
数据来源 本地 Parquet/CSV 数据目录 交易所 WebSocket / REST
执行适配器 模拟撮合(含滑点、手续费模型) 真实交易所下单接口
账户状态 初始资金虚拟账户 真实账户,需处理余额与保证金
网络与重连 无 需处理断线、限频、部分成交
策略代码 完全复用,不因模式而改写

一个典型的实盘节点配置片段如下:

from nautilus_trader.live.node import TradingNode
from nautilus_trader.config import TradingNodeConfig

config = TradingNodeConfig(
    trader_id="TRADER-001",
    data_clients={"BINANCE": BinanceDataClientConfig()},
    exec_clients={"BINANCE": BinanceExecClientConfig()},
)
node = TradingNode(config=config)
node.trader.add_strategy(MyStrategy(config=MyStrategyConfig()))
node.build()
node.run()

迁移时,策略类 MyStrategy 与回测中完全相同,变化集中在 config 的客户端与账户配置上。

四、误区与复盘:迁移中最常见的三个错误

误区一:把回测中的“即时成交”当成实盘常态。回测撮合往往假设订单立即全部成交,而实盘存在延迟、部分成交和拒单。迁移后必须让策略能处理 OrderPartiallyFilled 和 OrderRejected。
误区二:忽略时钟差异导致定时逻辑失效。回测中 Clock 由数据驱动,若策略依赖 on_timer 做定时任务,实盘中会按真实时间触发,频率和顺序可能与回测不同。
误区三:直接复用回测缓存状态。实盘启动时 Cache 为空,持仓和订单需从账户同步或重建,不能假设缓存中已有历史状态。

复盘建议:迁移前先在实盘环境用最小仓位跑通“行情接入—下单—成交回报—持仓更新”全链路,确认各组件事件顺序与回测一致,再逐步放大仓位。理解引擎、总线、数据引擎、执行引擎、投资组合与缓存之间的协作关系,能让迁移从“试错”变成“可控验证”。