4. 数据模型与数据类型

在 NautilusTrader 中,回测与实盘共用同一套数据模型,这是它区别于许多“回测一套、实盘另一套”框架的核心优势。理解 QuoteTick、TradeTick、Bar、OrderBookDelta 这四类数据的结构、用途与转换关系,是写出可复用策略、避免回测失真和实盘异常的前提。本节从数据模型的设计意图出发,逐层拆解它们的字段、适用场景与相互转换方法。

一、核心原理:为什么需要多种数据类型

市场信息本身是多层次的:最细粒度是订单簿的每一次增删改,其次是逐笔成交与最优买卖报价,再往上是按时间窗口聚合的 K 线。NautilusTrader 用不同的数据类型分别承载这些层次,而不是用单一结构“一把梭”。这样做的原因是:数据精度决定策略能感知到的信息边界。一个只依赖 Bar 的策略无法看到盘口挂单变化,而一个做市策略必须依赖 OrderBookDelta 才能重建订单簿。

所有数据类型都继承自统一的数据基类,携带 instrument_id、ts_event(事件发生时间)和 ts_init(系统初始化时间)等公共字段。理解 ts_event 与 ts_init 的区别非常关键:前者是交易所时间戳,后者是本地接收时间戳,回测中二者通常一致,实盘中二者可能相差数毫秒甚至更多,直接影响延迟敏感策略的表现。

NautilusTrader 数据模型层次与转换关系 OrderBookDelta 订单簿增删改 最细粒度 QuoteTick 最优买卖报价 bid / ask TradeTick 逐笔成交 price / size / aggressor Bar OHLCV 聚合 时间窗口 聚合 提取 聚合 聚合 精度递减 → 数据量递减 → 策略可感知信息递减 回测与实盘共用同一数据模型,保证策略逻辑一致性

二、四类数据的结构与用途

QuoteTick 表示某一时刻的最优买卖报价,核心字段为 bid_price、ask_price、bid_size、ask_size。它适合做价差监控、盘口强度判断和基于报价的挂单策略。注意 QuoteTick 只反映最优档,不包含深度信息。

TradeTick 表示一笔实际成交,字段包括 price、size 和 aggressor_side(主动方方向)。主动方方向是判断买卖压力的关键:主动买盘推高价格,主动卖盘压低价格。做量价分析和订单流策略时,TradeTick 是基础数据。

Bar 是时间窗口聚合结果,包含 open、high、low、close、volume,并带有 bar_type 描述周期与价格类型(如 EUR/USD.SIM-1-MINUTE-BID-EXTERNAL)。Bar 数据量小、计算快,适合趋势、均值回归等中低频策略。

OrderBookDelta 描述订单簿的增量变化,字段包括 action(ADD/UPDATE/DELETE)、side、price、size 和 order_id。它是重建完整订单簿的唯一途径,适合做市、高频套利和微观结构研究。

数据类型 核心字段 典型用途 数据量级
QuoteTick bid/ask price & size 价差监控、报价驱动挂单 高
TradeTick price, size, aggressor_side 量价分析、订单流 高
Bar OHLCV, bar_type 趋势、均值回归策略 低
OrderBookDelta action, side, price, size 做市、高频、微观结构 极高

三、数据转换方法与实操

NautilusTrader 提供了内置的聚合器,可以把细粒度数据转换为粗粒度数据。最常见的是用 QuoteTick 或 TradeTick 聚合出 Bar。以下代码演示如何配置一个基于 TradeTick 的 1 分钟 Bar 聚合器:

from nautilus_trader.config import BarAggregatorConfig
from nautilus_trader.model.data import BarType, BarAggregation

bar_type = BarType.from_str("EUR/USD.SIM-1-MINUTE-LAST-EXTERNAL")

config = BarAggregatorConfig(
    bar_type=bar_type,
    aggregation=BarAggregation.MINUTE,
    price_type="LAST",   # 使用最新成交价
    interval=1,
)

# 在策略中订阅 TradeTick 后,聚合器会自动生成 Bar
self.subscribe_trade_ticks(instrument_id)
self.subscribe_bars(bar_type)

反向转换并不总是可行:Bar 无法还原出逐笔成交,QuoteTick 也无法还原完整订单簿。因此数据精度只能向下聚合,不能向上还原。这一点在回测数据选择时至关重要——如果你用 Bar 回测一个依赖盘口深度的策略,结果必然失真。

实用建议:回测数据精度应不低于策略实际依赖的精度。做市策略必须使用 OrderBookDelta 或至少 QuoteTick;中低频策略用 Bar 即可,避免无谓的计算开销。

四、常见误区与复盘

  • 误区一:混用 ts_event 与 ts_init。回测中二者常被当作相同值,但实盘中 ts_init 晚于 ts_event。若策略逻辑依赖时间差,回测会低估延迟影响。
  • 误区二:认为 Bar 可以替代 Tick。Bar 丢失了窗口内的价格路径,止损触发点、滑点估算都会失真。
  • 误区三:忽略 aggressor_side。只看成交价和成交量,会丢失买卖主动方信息,订单流策略无法成立。
  • 误区四:OrderBookDelta 不做快照对齐。增量数据必须从某个快照开始重建,否则订单簿状态错误。
复盘要点:在实盘接入前,务必用同一份数据分别跑回测和模拟盘,对比策略信号是否一致。若不一致,优先检查数据类型是否匹配、时间戳字段是否被误用。