Nautilus Trader 期权交易完全指南:Greeks 订阅、期权链聚合与回测实战
2026/9/12 16:22:15 网站建设 项目流程

Nautilus Trader 期权交易完全指南:Greeks 订阅、期权链聚合与回测实战

【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader

Nautilus Trader 对期权交易提供了一流的原生支持,覆盖传统交易所与加密货币市场,包括期权专用工具类型、交易所实时 Greeks 数据流、期权链(Option Chain)聚合,以及用于风险管理的本地 Black-Scholes Greeks 计算器。本文以docs/concepts/options.md为主线,结合crates/data/src/option_chains/OptionChainManagerOptionChainAggregatorAtmTracker的 Rust 源码实现,系统讲解期权工具类型、Greeks 订阅方式、StrikeRange 行权价过滤、Snapshot/Raw 双模式、期权链回测配置与架构原理,帮助读者从订阅 API 到引擎内部实现建立完整认知。

期权工具类型(Option Instrument Types)

平台定义了五类期权工具,覆盖从传统交易所到加密衍生品的全部场景:

工具类型说明
OptionContract交易所上市的期权合约,带行权价(strike)与到期日(expiry)。
OptionSpread交易所定义的多元腿(multi-leg)期权策略,作为单一行情行(one line)报价。
CryptoOption加密期权,以加密货币报价/结算,支持 inverse 或 quanto 风格。
CryptoOptionSpread加密期权价差组合,带 inverse、结算货币与小数合约规模。
BinaryOption固定赔付期权,结算结果为 0 或 1。

与 Greeks 相关的元数据差异

不同工具类型携带的 Greeks 相关元数据差异显著:

  • OptionContractCryptoOption:包含完整的 Greeks 输入,如strike_priceoption_kind(CALL/PUT)、expiration_nsunderlyingmultiplier
  • OptionSpreadCryptoOptionSpread:由交易所定义并作为单一可交易工具发布的多元腿策略,具有underlyingexpiration_nsstrategy_type(交易所定义代码)。价差本身不携带strike_priceoption_kind;当适配器提供腿级细节时,保存在info字段中。订单针对价差作为单一行情行执行。CryptoOptionSpread额外携带is_inversesettlement_currency,用于 Deribit 等场所。
  • BinaryOption:具有expiration_nsoutcome/description,但没有strike_priceoption_kindunderlying

从源码看,期权链聚合器在解析工具时正是依赖这些元数据做筛选。在 manager.rs 的resolve_instruments中,从缓存中按 venue、underlying、expiration_nssettlement_currency精确匹配,并只收录具有strike_price()option_kind()的合约,将其映射为HashMap<InstrumentId, (Price, OptionKind)>存入聚合器——这就是整个期权链按行权价建缓冲(BTreeMap<Price, OptionStrikeData>)的基础。

订阅实时 Greeks

Deribit、Bybit、OKX 等交易所会在期权市场发布实时 Greeks。Nautilus 提供两个订阅层级:

  • 单合约 Greeks(Per-instrument):订阅单个期权合约。
  • 期权链切片(Option chain slices):订阅整个期权序列(series)的聚合视图。

单合约 Greeks 订阅

在 Actor 或 Strategy 中订阅单个期权合约的交易所 Greeks:

from nautilus_trader.model import ClientId client_id = ClientId("DERIBIT") self.subscribe_option_greeks(instrument_id, client_id=client_id)

通过实现on_option_greeks处理器接收更新:

def on_option_greeks(self, greeks) -> None: self.log.info( f"{greeks.instrument_id}: " f"delta={greeks.delta:.4f} gamma={greeks.gamma:.6f} " f"vega={greeks.vega:.4f} theta={greeks.theta:.4f} " f"mark_iv={greeks.mark_iv} underlying={greeks.underlying_price}" )

停止接收更新:

self.unsubscribe_option_greeks(instrument_id, client_id=client_id)

在引擎内部,每个OptionGreeks事件通过消息总线(msgbus)主题switchboard::get_option_greeks_topic(instrument_id)分发,OptionChainGreeksHandler负责接收并路由给对应系列的聚合器(见 manager.rs)。

期权链订阅

期权链订阅将整个期权序列所有行权价的报价与 Greeks 聚合成OptionChainSlice快照。DataEngine为每个序列创建一个 RustOptionChainManager,并持有其生命周期:创建管理器、路由进入的数据、运行快照定时器、排空线上(wire)订阅变更。

from nautilus_trader.model import OptionSeriesId from nautilus_trader.model import StrikeRange series_id = OptionSeriesId(...) # venue, underlying, settlement currency, expiry # Subscribe to 5 strikes above and below ATM, snapshot every 1000ms strike_range = StrikeRange.atm_relative(strikes_above=5, strikes_below=5) self.subscribe_option_chain( series_id, strike_range=strike_range, snapshot_interval_ms=1000, )

实现on_option_chain处理器接收快照:

def on_option_chain(self, chain) -> None: for strike in chain.strikes(): call = chain.get_call(strike) put = chain.get_put(strike) if call and call.greeks: self.log.info(f"Call {strike}: delta={call.greeks.delta:.4f}")

引擎侧(manager.rs 的create_and_setup)在收到SubscribeOptionChain后的完整动作是:从缓存解析系列全部工具 → 创建AtmTracker(并按首个行权价精度设置 forward price 精度)→ 创建OptionChainAggregator→ 依据snapshot_interval_ms判断 raw/snapshot 模式 → 为初始活跃集合注册 msgbus 处理器 → 向数据客户端转发「报价 + Greeks + 工具状态」三类订阅 → 按需设置快照定时器。

StrikeRange 行权价过滤

StrikeRange控制链订阅中哪些行权价处于活跃状态:

变体说明示例
Fixed订阅一组显式行权价。StrikeRange.fixed([...])
AtmRelativeATM 上方 N 档与下方 N 档。StrikeRange.atm_relative(5, 5)
AtmPercentATM 价格周围百分比区间内的所有行权价。StrikeRange.atm_percent(0.10)
Deltacall 或 put 的 delta 接近目标值的行权价。StrikeRange.delta(0.25, 0.05)

在 Rust 侧(option_chain.rs),StrikeRange是一个带序列化支持的四变体枚举:Fixed(Vec<Price>)AtmRelative { strikes_above, strikes_below }AtmPercent { pct }Delta { target, tolerance }。其resolve()方法行为如下:

  • Fixed:与可用行权价集合取交集后返回。
  • AtmRelative:通过二分查找(binary_search)定位最接近 ATM 的行权价索引,再向两侧各取 N 档,越界处用saturating_sub/saturating_add截断。
  • AtmPercent:计算每个行权价与 ATM 的百分比距离|s - atm| / |atm|,保留距离不超过pct的行权价。
  • Delta:模型层无 Greeks 时无法解析,回退为 ATM 两侧各 5 档(DEFAULT_DELTA_FALLBACK_STRIKES = 5)的 ATM 相对窗口;真正的 Delta 解析由聚合器基于已积累的 Greeks 完成。

动态行权价区间(AtmRelative/AtmPercent/Delta)的订阅会延迟到 ATM 价格确定之后。ATM 来源于OptionGreeks.underlying_price中的交易所参考价。它也可以通过 HTTP 为该序列拉取参考价预先填充,实现实时 WebSocket ticks 到达前的即时引导(instant bootstrap)。随着 ATM 移动,活跃行权价集合会自动再平衡(rebalance)。

Delta 解析细节(见 aggregator.rs 的resolve_delta):

  • 依据交易所 Greeks:当某行权价的 call 或 put delta 绝对值(call 为正、put 为负,均按绝对值比较)落在target ± tolerance区间内时,该行权价激活。典型的虚值(OTM)目标如0.25会在 ATM 两侧各选出一个行权价。
  • 在 ATM 参考价未知前,Delta与其他动态区间一样延迟。
  • ATM 已知后,若没有任何活跃行权价的 Greeks 匹配该区间(包括 Greeks 尚未到达时),Delta回退到 ATM 两侧各 5 档的窗口。
  • 从回退窗口切换到选中 Delta 行权价之前,聚合器会等待回退窗口内每个腿都获得 Greeksdelta_window_ready检查pending_greeks与缓冲中已有 Greeks),避免早期不完整更新导致相邻行权价被错误取消订阅。

快照模式与原始模式(Snapshot vs. Raw mode)

snapshot_interval_ms参数控制发布行为:

  • 快照模式snapshot_interval_ms=1000):报价与 Greeks 累积在缓冲中,由定时器周期性发布为OptionChainSlice。适合定期组合再平衡或 UI 展示。
  • 原始模式snapshot_interval_ms=None):活跃工具的每次报价或 Greeks 更新都立即发布切片。适合对单笔更新敏感的延迟敏感型策略。

源码实现(manager.rs)以raw_mode = cmd.snapshot_interval_ms.is_none()区分两种模式:raw 模式下handle_quote()/handle_greeks()在更新聚合器后立即调用publish_slice()(前提是已 bootstrap 且该工具处于活跃集);快照模式则通过setup_timerOptionChain|{series_id}|{interval_ms}为定时器名,将OptionChainSlicePublisher回调挂到时钟上,周期触发publish_slice()

回测期权链(Backtesting Option Chains)

期权链回测与实盘订阅走同一套OptionChainManagerOptionChainAggregator路径。前提是 Nautilus Parquet catalog 中已包含期权工具及构建链所需的单合约数据:

  • 每个期权合约的QuoteTick记录,携带回放的最优买卖价(BBO)。
  • 每个期权合约的OptionGreeks记录,携带 delta、隐含波动率、convention 以及用于播种 ATM 的underlying_price
  • 与上述工具 ID 对应的CryptoOptionOptionContract工具。

Tardis 回放数据满足该契约:期权簿快照或报价写入为QuoteTickoption_summary消息写入为OptionGreeks。回测运行期间不会下载或请求缺失的 catalog 数据。

为序列中的期权工具配置带两条数据流的BacktestNode运行:

data = [ BacktestDataConfig( data_type="QuoteTick", catalog_path="/path/to/catalog", instrument_ids=option_instrument_ids, ), BacktestDataConfig( data_type="OptionGreeks", catalog_path="/path/to/catalog", instrument_ids=option_instrument_ids, ), ]

然后在策略中订阅:

strike_range = StrikeRange.delta(0.25, 0.05) self.subscribe_option_chain( series_id, strike_range=strike_range, snapshot_interval_ms=1000, )

使用snapshot_interval_ms=None进入 raw 模式(活跃工具每次报价或 Greeks 更新即发布切片);使用整数间隔进入减薄快照(thinned snapshot)模式——按定时器节奏发布整条链,显著降低大链的事件量。

聚合语义:每个OptionChainSlice按工具 ID 关联最新 BBO 与 Greeks,再按行权价与期权方向(call/put)分组。报价可能先于 Greeks 到达,Greeks 也可能先于报价到达;聚合器保持各自最新状态,并在两者齐备时一并挂接(Greeks 先到时暂存于pending_greeks,见 aggregator.rs)。OptionGreeks中的underlying_price驱动 ATM 检测。

选择策略可在订阅区间内完成,也可在策略内部完成:

  • 货币性(Moneyness):使用StrikeRange.atm_relative(...)StrikeRange.atm_percent(...)
  • Delta:使用StrikeRange.delta(target, tolerance),或在on_option_chain中检查entry.greeks.delta
  • 行权价:使用StrikeRange.fixed([...]),或读取chain.get_call(strike)chain.get_put(strike)

在 Rust 示例 tardis_option_chain.rs 中可以看到两种策略内选择:select_by_delta遍历slice.callsslice.puts,计算(greeks.delta.abs() - target).abs()选取距目标最近的合约;select_by_strike则直接通过get_call/get_put取指定行权价。示例以cargo run -p nautilus-backtest --features examples,streaming --example tardis-option-chain运行,SELECTION常量可切换"delta""strike"两种选择方式。

撮合语义:期权撮合由报价驱动。市价单与可成交限价单作为 taker 以对手方回放 BBO 成交;被动限价单挂在模拟盘口上,后续 BBO 更新穿越限价时作为 maker 成交。模型不模拟期权的 L2 队列位置。

期权手续费模型在模拟交易所上配置,而非按交易所名称推断:

from decimal import Decimal from nautilus_trader.execution import CappedOptionFeeModel from nautilus_trader.execution import TieredNotionalOptionFeeModel deribit_like = CappedOptionFeeModel( maker_rate=Decimal("0.0003"), taker_rate=Decimal("0.0003"), ) okx_like = TieredNotionalOptionFeeModel( maker_rate=Decimal("0.0002"), taker_rate=Decimal("0.0005"), )

将其中任一对象作为fee_model传入BacktestVenueConfig。Rust 侧使用FeeModelAny::CappedOption(CappedOptionFeeModel::new(...))FeeModelAny::TieredNotionalOption(TieredNotionalOptionFeeModel::new(...))(见 fee.rs 及示例 tardis_option_chain.rs)。两个模型都实现统一的FeeModeltrait,其核心接口get_commission/get_commission_with_context接受订单、成交量、成交价、工具(及可选的基础资产价格上下文)返回Money佣金。

参考示例:examples/backtest/tardis_option_chain.py 与 crates/backtest/examples/tardis_option_chain.rs。

期权链架构(Option Chain Architecture)

期权链系统是事件驱动的,围绕按序列隔离(per-series isolation)构建。DataEngine为每个订阅的期权序列创建一个 RustOptionChainManager。管理器包装OptionChainAggregatorAtmTracker,注册消息总线处理器,发布快照,并将线上订阅变更排入队列供引擎排空。

在 Rust 实现中,DataEngineAHashMap<OptionSeriesId, Rc<RefCell<OptionChainManager>>>持有每个活跃序列对应的管理器(见 manager.rs),每个管理器自包含聚合器、msgbus 处理器与定时器。

组件职责

DataEngine

每个活跃OptionSeriesId持有一个OptionChainManager。收到SubscribeOptionChain时:从缓存解析工具、为动态行权价区间请求序列参考价、创建管理器、向数据客户端订阅活跃工具、设置快照定时器。每次定时器 tick 时:检查再平衡、发布快照、将线上订阅变更排队供引擎排空。收到UnsubscribeOptionChain或所有工具到期时:拆除管理器、取消定时器、退订线上数据流。

OptionChainManager

围绕OptionChainAggregatorAtmTracker的按序列 Rust 管理器。DataEngine通过handle_quote()handle_greeks()向它喂入市场数据。快照模式下,定时器回调调用publish_slice();raw 模式下,每个活跃工具的报价或 Greeks 更新立即调用publish_slice()。管理器在首个 ATM 价格到达时在内部引导(bootstrap)活跃工具集——maybe_bootstrap()检查bootstrapped标志与atm_tracker().atm_price(),一旦 ATM 就绪即调用recompute_active_set()计算活跃集、批量注册 msgbus 处理器,并为每个活跃工具排队三条订阅命令(Quotes、OptionGreeks、InstrumentStatus)。

生命周期管理同样完整:teardown()退订活跃工具的 msgbus 处理器并取消定时器;handle_instrument_expired()在工具到期时将其从聚合器移除、注销处理器、排队线上退订,并在整个目录清空时通知引擎拆除管理器(manager.rs)。

OptionChainAggregator

以 keep-latest 语义将报价与 Greeks 累积进 call/put 缓冲(内部为BTreeMap<Price, OptionStrikeData>,天然按行权价有序)。上次快照后未更新的工具仍会出现在后续快照中。Greeks 先于报价到达的暂存于pending_grees缓冲,首个报价到达时挂接。每次snapshot()调用产出不可变OptionChainSlice——快照只过滤活跃行权价并克隆缓冲数据,因此不会破坏 keep-latest 状态(见 aggregator.rs)。

AtmTracker

从进入的OptionGreeks事件中的underlying_price字段响应式推导 ATM 价格(atm_tracker.rs 的update_from_option_greeks将 forward price 以既定精度(默认 2 位,由set_forward_precision覆盖)转为Price)。可通过set_initial_price用 HTTP 参考价预填充,实现无需等待 WebSocket ticks 的即时引导。后续实时更新会正常覆盖该值。

引导与再平衡(Bootstrap and Rebalancing)

对动态行权价区间(AtmRelativeAtmPercentDelta),活跃工具集在 ATM 价格确定前无法确定,有两条引导路径:

即时引导(参考价可用):

  1. DataEngine收到SubscribeOptionChain,从缓存解析该序列全部工具,并向数据客户端请求参考价。
  2. 参考价响应到达后,引擎以预填充的 ATM 价格创建管理器,管理器在构造期间计算活跃行权价集。
  3. 引擎立即订阅活跃工具。

延迟引导(无参考价):

  1. 引擎没有匹配的客户端或缓存期权工具、客户端报告无参考价、请求失败、或请求 30 秒超时。
  2. 引擎以无初始 ATM 价格创建管理器,活跃集为空。若请求到达了持有缓存样本期权的客户端,引擎订阅该样本的 Greeks 作为引导源;若无客户端或样本,引导仍依赖另一订阅中已流动的相关 Greeks 数据。
  3. 当引擎通过handle_greeks()喂入携带underlying_priceOptionGreeks事件时,管理器引导活跃工具集、注册消息总线处理器,并将新的线上订阅排队供引擎排空。样本订阅并入活跃集或释放。

引导完成后,聚合器监控 ATM 漂移。每次快照定时器 tick,管理器调用聚合器的check_rebalance()获取需增删的工具。滞回阈值(hysteresis)与冷却期(cooldown)防止行权价边界附近的频繁抖动(thrashing)。

从源码看再平衡逻辑(aggregator.rs):

  • Fixed区间永不再平衡。
  • 无 ATM 价格时返回None
  • 非 Delta 区间:ATM 最接近行权价未变则返回None;否则检查滞回——价格须穿过到下一行权价间距的hysteresis比例(默认值来自DEFAULT_REBALANCE_HYSTERESIS)才允许切换。
  • 冷却期:距上次再平衡不足DEFAULT_REBALANCE_COOLDOWN纳秒则跳过。
  • Delta 区间:跳过 ATM 位移与滞回门控(其活跃集由 Greeks 解析而非 ATM 窗口),任何解析集变化即再平衡,但仍受冷却期节流;无增删的 no-op 再平衡被抑制以免重置冷却时间戳。

OptionGreeks 数据类型

OptionGreeks携带交易所提供的单一期权合约的敏感度与隐含波动率:

字段类型说明
instrument_idInstrumentId这些 Greeks 适用的期权合约。
conventionGreeksConventionGreeks 的计价(numeraire)惯例。
deltafloat期权价格对每单位基础资产的变动率。
gammafloatdelta 对每单位基础资产的变动率。
vegafloat交易所报告的 vega。
thetafloat交易所报告的 theta。
rhofloat交易所报告的 rho;默认为零。
mark_ivfloat或 None标记隐含波动率。
bid_ivfloat或 None买价隐含波动率。
ask_ivfloat或 None卖价隐含波动率。
underlying_pricefloat或 None计算时刻的基础资产价格。
open_interestfloat或 None合约未平仓量。
ts_eventint事件发生的 UNIX 纳秒时间戳。
ts_initint初始化时的 UNIX 纳秒时间戳。

在 Rust 定义中(option_chain.rs),OptionGreeks#[repr(C)]结构体,通过DerefOptionGreekValues直接暴露delta/gamma/vega/theta/rho字段,并实现HasGreeksSerializable,同时支持 Python 绑定(nautilus_trader.model模块),因而可无缝用于 Python 策略与回测。

OptionChainSlice 数据类型

OptionChainSlice是整个期权序列在某一时刻的快照。

属性:

属性类型说明
series_idOptionSeriesId期权序列标识符。
atm_strikePrice或 None当前 ATM 行权价(若已确定)。
ts_eventintUNIX 纳秒时间戳。
ts_initintUNIX 纳秒时间戳。

Call 与 put 数据通过方法访问而非直接属性。每个OptionStrikeData(option_chain.rs)包含该行权价的quoteQuoteTick)与可选的greeksOptionGreeks)。底层OptionChainSliceBTreeMap<Price, OptionStrikeData>存储 calls 与 puts(option_chain.rs),保证按行权价有序遍历。

方法:

  • strikes():链中全部唯一行权价。
  • strike_count()call_count()put_count():各类计数。
  • get_call(strike)get_put(strike):完整OptionStrikeData
  • get_call_greeks(strike)get_put_greeks(strike):仅 Greeks。
  • get_call_quote(strike)get_put_quote(strike):仅报价。
  • is_empty():链中无数据时为真。

适配器支持

当前支持期权 Greeks 订阅的适配器:

适配器单合约 Greeks期权链
Deribit
Bybit
OKX-

延伸阅读

  • Greeks —— 本地 Greeks 计算与组合风险管理。
  • Data —— 内置数据类型与订阅模型。
  • Actors —— 订阅与处理器参考表。
  • 期权链核心实现:crates/data/src/option_chains/下的 manager.rs、aggregator.rs 与 atm_tracker.rs。
  • 期权链数据模型:crates/model/src/data/option_chain.rs。

【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询