nautilus_trader DeltaNeutralVol 策略详解:短波动率跨式(Short Strangle)的 Delta 中性对冲引擎
【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader
nautilus_trader 在crates/trading的 examples 模块中内置了一个可直接运行的期权策略DeltaNeutralVol:它面向账户中已持有的实值外(OTM)认购与认沽期权跨式组合(strangle),通过底层永续合约(perpetual swap)持续对冲组合净 Delta。本文以 策略文档 为主线,结合 策略实现、配置定义 与 测试用例 的源码级证据,完整讲解它的入场、再对冲、持仓跟踪与退出机制,并给出 Rust 与 Python 两种可复制的接入方式、全部配置参数的含义与风险考量。读完本文,你将能够在 LiveNode 或 BacktestEngine 中部署一个"卖跨式 + 永续对冲"的短波动率组合,或将其改造成只对冲外部已建仓的纯 Delta 对冲器。
策略定位:对"外部持仓"做 Delta 对冲
DeltaNeutralVol的核心假设是:账户中已经存在(或由本策略代为建立)一份同一标的、同一到期日的 OTM 认购与 OTM 认沽(即 short strangle)。由于认购与认沽的 Delta 大致互相抵消,组合初始状态接近 Delta 中性;随着标的价格波动,净 Delta 逐渐偏离零点,策略监测这一漂移,并在组合 Delta 超过可配置阈值时,通过交易底层永续合约进行再对冲。
从 模块注释 可以看出,它通过subscribe_option_greeks订阅交易所提供的 Greeks(由适配器实现,参见 DataActor 中的订阅方法),并用这些 Greeks 跟踪组合 Delta。策略内部状态机维护了以下关键字段(strategy.rs):
call_instrument_id/put_instrument_id:启动时选定的一对腿;call_delta/put_delta:最新一次 Greeks 更新得到的腿 Delta;call_mark_iv/put_mark_iv:用于 IV 定价入场的 mark IV;call_quote/put_quote:用于 premium 定价入场的报价;call_position/put_position/hedge_position:三条腿的持仓数量(带符号);hedge_pending:对冲订单在途锁,防止重复提交;entry_attempted:入场尝试开关,保证跨式只建立一次。
入场流程(Entry)
启动时策略执行 6 步初始化,全部实现在DataActor::on_start中(strategy.rs):
- 按家族查询期权:从缓存中取出与
option_family(例如BTC-USD)匹配的所有期权合约,同时过滤掉已到期的合约; - 筛选到期:若未设置
expiry_filter,自动选取最近到期日,并丢弃其他到期日的合约;若设置了expiry_filter(如260327),则按合约 symbol 中包含的过滤串精确筛选; - 按 Delta 启发式选腿:将 call 按行权价升序排列,取
(1.0 - target_call_delta)百分位的行权价作为认购腿(约 80% 分位,对应约 0.20 Delta 的 OTM call);将 put 按行权价升序排列,取|target_put_delta|百分位的行权价作为认沽腿(约 20% 分位,对应约 -0.20 Delta 的 OTM put)。源码注释明确指出这是"行权价近似 Delta 排序"的简化启发式——生产级策略应先订阅全部 Greeks 再按真实 Delta 选腿; - 水合持仓:从缓存中读取三条腿(call / put / hedge)的当前敞口(
positions_open求和),以支持跨会话恢复与外部建仓场景; - 订阅数据流:为两条期权腿订阅 venue-provided Greeks,为对冲合约订阅报价;若启用 premium 定价入场(
entry_premium_offset_ticks非空),还会订阅两条期权腿的报价; - 等待双腿 Greeks 就绪:
greeks_initialized()要求 call 与 put 的instrument_id均已设置且各自产生过至少一次 Greeks 更新,在此之前不启用再对冲(strategy.rs)。
两种入场定价模式
当enter_strangle为true(默认)且账户中尚无期权持仓时,策略在首批 Greeks 到达后提交两条 SELL 限价单:
- IV 定价模式(默认):按 mark IV 减去
entry_iv_offset定价,即entry_iv = mark_iv - entry_iv_offset。entry_iv_offset = 0.0表示按 mark 卖出,正值(如0.02)表示在 mark 下方 2 个波动率点卖出以加快成交。限价单的价格字段直接填写 IV 值,并额外通过订单参数Params把 IV 传给适配器——参数键由iv_param_key指定,Bybit 适配器用"order_iv",OKX 适配器用"px_vol"(见 config.rs); - Premium 定价模式:设置
entry_premium_offset_ticks后,策略不再使用 IV 参数,而是订阅两条期权腿的报价,以当前 ask 加上指定 tick 数作为卖出价(offset_entry_price内部调用Instrument::next_ask_price)。若某条腿的 quote 为空(例如报价侧缺失),则回退到从 venue IV 字段推导:entry_premium_from_greeks使用ask_iv(要求为正),否则退回mark_iv,结合标的价、行权价、剩余期限调用模型层 compute_greeks(Black-Scholes 定价)反推期权 premium,再叠加 tick 偏移(strategy.rs)。
入场的完整门控条件should_enter_strangle()(strategy.rs)为:enter_strangle开启、双腿 Greeks 已初始化、入场定价数据就绪、call 与 put 持仓均为 0、尚未尝试过入场、且没有在途/挂起的入场订单(has_working_entry_orders检查缓存中的 open 与 in-flight 订单)。测试 tests.rs 逐条验证了这些门控条件(包括 premium 模式必须等到双腿 quote 齐备才入场)。
当enter_strangle为false时,策略退化为纯 Delta 对冲器:只对账户中已存在(或上一会话延续)的跨式持仓做对冲,不提交任何入场订单。
再对冲机制(Rehedging)
再对冲由两个触发源驱动(strategy.rs):
- Greeks 更新:每次
on_option_greeks触发时,更新对应腿的 delta 与 mark IV,随后立即调用check_rehedge()。只有双腿都产生过 Greeks 后(greeks_initialized())才允许对冲; - 周期定时器:
on_start中通过set_timer_ns注册名为delta_rehedge的定时器,间隔rehedge_interval_secs秒。on_time_event中检查事件名并再次调用check_rehedge(),作为 Greeks 流中断时的安全网。
check_rehedge()的核心逻辑(strategy.rs):
- 计算
portfolio_delta = call_delta * call_position + put_delta * put_position + hedge_position; - 若
|portfolio_delta|未超过rehedge_delta_threshold,直接返回; - 若
hedge_pending为真(上一笔对冲订单仍在途),跳过本次对冲,防止重复提交; - 计算对冲数量与方向:Delta 为正时
Sell,为负时Buy,数量取|delta|; - 数量精度防护:从缓存读取对冲合约的
size_precision,用Quantity::new(hedge_qty, size_precision)构造数量;若按该精度取整后数量为零(Delta 绝对值小于最小可表达粒度),跳过本次对冲且不置位hedge_pending——测试 tests.rs 专门验证了"整数张合约"场景下该锁不会被误置,后续可正常对冲; - 提交市价单(
order().market)后置位hedge_pending = true;若提交失败则立即复位锁。
hedge_pending锁的复位时机覆盖了订单生命周期的所有终止态:on_order_filled(且订单已关闭)、on_order_canceled、on_order_rejected、on_order_denied、on_order_expired——所有这些回调都仅在事件属于对冲合约时才复位锁(strategy.rs),相关行为均有测试覆盖。
持仓跟踪(Position Tracking)
所有持仓变动都经由on_order_filled累积(strategy.rs):根据成交订单的方向(Buy 为正、Sell 为负)乘以成交量,累加到hedge_position、call_position或put_position之一;成交事件不匹配任何已知合约时被忽略(有测试验证,tests.rs)。
组合 Delta 的计算公式与 README 一致,即portfolio_delta():
portfolio_delta = call_delta * call_position + put_delta * put_position + hedge_position测试 tests.rs 验证了若干典型场景:空仓时 Delta 为零、卖 10 张 0.25 Delta call 产生 -2.5 的 Delta、对称跨式加 0.5 张对冲后组合 Delta 回到 0.5 等。对冲方向的判定(正 Delta 卖出、负 Delta 买入)同样有独立测试(tests.rs)。
退出与停止(Exit)
on_stop的清理动作(strategy.rs):
- 取消
delta_rehedge定时器; - 退订两条期权腿的 Greeks(以及 premium 模式下的腿报价);
- 对 call、put、对冲合约分别执行
cancel_all_orders; - 退订对冲合约报价,复位
hedge_pending。
策略停止不会平掉任何持仓——期权与对冲仓位原样保留,退出操作必须由外部另行管理(这是设计上明确的生命周期风险,见下文)。测试 tests.rs 验证了停止后三条腿的持仓数值保持不变、订阅列表清空、锁复位。
完整配置参数
README 的配置表完整继承如下,其中标注required的字段没有默认值,其余字段的默认值来自 config.rs 的bon::Builder注解:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
option_family | String | required | 期权家族过滤条件,例如BTC-USD |
hedge_instrument_id | InstrumentId | required | 底层对冲合约,例如BTC-USD-SWAP.OKX |
client_id | ClientId | required | 数据与执行客户端标识,例如OKX |
target_call_delta | f64 | 0.20 | 启动时认购腿行权价启发式的目标 Delta |
target_put_delta | f64 | -0.20 | 启动时认沽腿行权价启发式的目标 Delta |
contracts | u64 | 1 | 每条腿的期权合约张数 |
rehedge_delta_threshold | f64 | 0.5 | 触发对冲的绝对组合 Delta 阈值 |
rehedge_interval_secs | u64 | 30 | 周期再对冲检查定时器间隔(秒) |
expiry_filter | Option<String> | None | 限定特定到期日,例如260327 |
enter_strangle | bool | true | 是否由策略下跨式入场单 |
entry_iv_offset | f64 | 0.0 | 从 mark IV 中扣减的波动率点数 |
entry_time_in_force | TimeInForce | Gtc | 跨式入场单的时效类型 |
entry_premium_offset_ticks | Option<i32> | None | 显式 premium 入场的 ask 上方 tick 偏移 |
iv_param_key | String | "px_vol" | 传给适配器的 IV 参数键(Bybit 用order_iv,OKX 用px_vol) |
注意:
iv_param_key在 README 参数表中未列出,但它是 config.rs 中的真实可配置字段,也在 Python 绑定 的构造签名中暴露(默认"px_vol")。
继承自StrategyConfig的字段
配置结构体通过base字段携带标准的 StrategyConfig,默认值为strategy_id = DELTA_NEUTRAL_VOL-001、order_id_tag = 001(见 config.rs)。实际部署时最相关的几个字段:
strategy_id:默认DELTA_NEUTRAL_VOL-001;order_id_tag:默认001,多实例并行运行时务必设为唯一值;use_uuid_client_order_ids:设为true可避免跨重启的客户端订单 ID 冲突。
测试 tests.rs 同时验证了默认值与 builder 覆盖行为。
风险考量
README 明确列出 5 类风险,实际部署必须逐条评估:
- Gamma 风险:short strangle 具有负 Gamma。标的大幅波动时 Delta 敞口的增长速度快于对冲定时器可响应的速度。可通过收紧
rehedge_delta_threshold、缩短rehedge_interval_secs换取更快的响应,代价是更高的交易成本; - Vega 风险:隐含波动率飙升会直接放大空头期权的 mark-to-market 亏损,而本策略不直接管理 vega 敞口;
- 生命周期风险:停止策略即停止后续对冲更新,且不会平掉期权或对冲仓位,任何退出都必须单独管理;
- 流动性:加密货币交易所的 OTM 期权可能价差很宽、bid/ask 数组为空。适配器的
QuoteCache只处理部分 BBO 更新(这对应了 premium 模式下"quote 为空则回退到 Greeks 推导 premium"的设计);市场跳空或对冲合约以粗粒度数量交易时,对冲质量会下降(对应size_precision取整为零则跳过的防护); - 合约乘数:组合 Delta 计算使用原始合约数量。对于非单位乘数的合约(如 OKX 的 inverse 期权),对冲数量可能需要按合约价值缩放——README 明确指出生产部署应当处理这一点。
Rust 用法
策略与其配置类从nautilus_trading::examples::strategies导出(见 examples/strategies/mod.rs)。以下示例完整继承自 策略文档:
use nautilus_trading::examples::strategies::{DeltaNeutralVol, DeltaNeutralVolConfig}; let config = DeltaNeutralVolConfig::builder() .option_family("BTC-USD".to_string()) .hedge_instrument_id(InstrumentId::from("BTC-USD-SWAP.OKX")) .client_id(ClientId::new("OKX")) .target_call_delta(0.25) .target_put_delta(-0.25) .contracts(5) .rehedge_delta_threshold(0.3) .rehedge_interval_secs(15) .expiry_filter("260627".to_string()) .entry_iv_offset(0.02) // Sell 2 vol points below mark .build(); let strategy = DeltaNeutralVol::new(config); node.add_strategy(strategy)?;若切换到 premium 定价模式,把
.entry_iv_offset(0.02)替换为.entry_premium_offset_ticks(Some(1))(并在需要时通过.iv_param_key("order_iv".to_string())适配 Bybit)。builder 还支持.entry_time_in_force(TimeInForce::Ioc)、.enter_strangle(false)等覆盖,全部字段见上文配置表。
Python 用法(v2)
Python 侧只负责提供配置,策略本体完全在 Rust 中运行。DeltaNeutralVolConfig通过nautilus_trader.trading模块暴露(PyO3 绑定见 crates/trading/src/python/examples.rs),随后传给LiveNode或BacktestEngine的add_builtin_strategy:
from nautilus_trader.trading import DeltaNeutralVolConfig config = DeltaNeutralVolConfig( option_family="BTC-USD", hedge_instrument_id=InstrumentId.from_str("BTC-USD-SWAP.OKX"), client_id=ClientId("OKX"), target_call_delta=0.25, target_put_delta=-0.25, contracts=5, rehedge_delta_threshold=0.3, rehedge_interval_secs=15, expiry_filter="260627", entry_iv_offset=0.02, # Sell 2 vol points below mark ) node.add_builtin_strategy("DeltaNeutralVol", config)Python 构造函数的完整签名与默认值(examples.rs)与 README 参数表一致,额外支持strategy_id、order_id_tag、entry_time_in_force、entry_premium_offset_ticks、iv_param_key等关键字参数。
实战部署参考
本策略已在仓库内配套了可直接运行的教程,可作为端到端部署蓝本:
- Bybit 期权 Delta 中性教程:展示了
DeltaNeutralVolConfig::builder()在 Bybit 环境中的完整组装与 LiveNode 接入方式; - Derive 期权 Delta 中性教程:同一策略在 Derive 适配器下的运行方案,包含策略架构图。
两者都演示了"Python/Rust 提供配置 → 策略在 Rust 引擎内运行 → 经适配器订阅 Greeks 与报价"的完整链路,印证了本文所述机制在真实适配器(OKX 数据适配器、Bybit 数据适配器、Deribit 数据适配器 等均实现了subscribe_option_greeks)上的可用性。
小结
DeltaNeutralVol是一个麻雀虽小、五脏俱全的期权 Greeks 驱动策略范例:它演示了 nautilus_trader 中subscribe_option_greeks数据流、周期定时器安全网、订单生命周期锁(hedge_pending)、缓存持仓水合、Quantity精度防护以及 Black-Scholes 回退定价(compute_greeks)的组合用法。无论是直接部署短波动率跨式对冲,还是把它作为"只用 Greeks 管理期权组合"的参考骨架,这份实现都值得在实盘前逐行研读——尤其是风险章节列出的 gamma、vega 与合约乘数问题,是任何期权做市与波动率策略绕不开的必修课。
【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考