Nautilus Trader BinaryOption 合约模型全解析:从字段设计到预测市场实战
2026/9/12 15:39:55 网站建设 项目流程

Nautilus Trader BinaryOption 合约模型全解析:从字段设计到预测市场实战

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

BinaryOption是 Nautilus Trader 中用于表示二元结果类合约的通用工具模型——它以"条件成立与否决定固定赔付"的方式统一刻画预测市场、二元期权以及交易所自定义的 Yes/No 合约。本文以 docs/concepts/instruments/binary_option.md 为骨架,结合nautilus_model的 Rust 核心实现与 Python 绑定源码,系统讲解BinaryOption的全部 25 个字段、行为语义、双语言构造方式、构建期校验规则,以及 Hyperliquid、Polymarket、OKX 三类适配器如何消费这一模型,帮助读者在回测与实盘中将二元合约当作一等公民处理。

BinaryOption 是什么

BinaryOption代表一类"二元结果"工具:合约在到期时依据某个条件是否成立,结算为固定赔付(fixed payoff)。它天然适合建模:

  • 预测市场(prediction markets):如 "Will the outcome of this market be 'Yes'?" 这类 Yes/No 合约;
  • 二元期权(binary options):交易所自定义的二元结果产品;
  • 交易所特定的 Yes/No 合约:不同交易场所提供的同构合约。

从源码看,这一模型被实现为一个#[repr(C)]的结构体,并同时暴露给 Rust 与 Python(通过pyo3pyclass),定义位于 crates/model/src/instruments/binary_option.rs。它实现了nautilus_modelInstrumenttrait,因此可以无缝进入缓存、回测引擎、风险管理等下游体系。

字段全览

构造一个BinaryOption共涉及 25 个字段,下表完整列出其 Rust 类型、Python 类型、必填性及含义:

FieldRust typePython typeRequired/defaultNotes
instrument_idInstrumentIdInstrumentIdRequiredRust 中存储为id
raw_symbolSymbolSymbolRequired交易所原生符号
asset_classAssetClassAssetClassRequired结果市场的资产类别
currencyCurrencyCurrencyRequired报价与结算货币
activation_nsUnixNanosintRequired合约激活时间戳
expiration_nsUnixNanosintRequired合约到期时间戳
price_precisionu8intRequired价格允许的小数位数
size_precisionu8intRequired订单数量允许的小数位数
price_incrementPricePriceRequired最小有效价格步长(tick size)
size_incrementQuantityQuantityRequired最小有效数量步长
outcomeOption<Ustr>str \| NoneNone交易所提供时给出的结果标签
descriptionOption<Ustr>str \| NoneNone人类可读的市场描述
max_quantityOption<Quantity>Quantity \| NoneNone最大订单数量
min_quantityOption<Quantity>Quantity \| NoneNone最小订单数量
max_notionalOption<Money>Money \| NoneNone最大订单名义价值
min_notionalOption<Money>Money \| NoneNone最小订单名义价值
max_priceOption<Price>Price \| NoneNone最大有效报价/订单价格
min_priceOption<Price>Price \| NoneNone最小有效报价/订单价格
margin_initOption<Decimal>Decimal \| None0初始保证金率
margin_maintOption<Decimal>Decimal \| None0维持保证金率
maker_feeOption<Decimal>Decimal \| None0Maker 费率,负值表示返佣
taker_feeOption<Decimal>Decimal \| None0Taker 费率,负值表示返佣
tick_schemeOption<Ustr>str \| NoneNone已注册的可变 tick 方案名称
infoOption<Params>dict \| NoneNone适配器附加元数据
ts_eventUnixNanosintRequired事件时间戳(纳秒)
ts_initUnixNanosintRequired初始化时间戳(纳秒)

注意:Python 构造参数名为instrument_id,而 Rust 内部将同一值存储为id。在 Python 侧访问时通过instrument.id属性(pyo3 绑定中#[pyo3(name = "id")]显式重命名),详见 crates/model/src/python/instruments/binary_option.rs。

字段语义要点

  • raw_symbol承载原生标识:以 Polymarket 为例,其合约 symbol 往往是长哈希串(条件 token ID),如文档示例中的0x12a0cb...-925449...,需原样透传,不得改写。
  • price_precision/size_precision必须与 increment 一致:源码在new_checked中调用check_equal_u8强制price_precision == price_increment.precisionsize_precision == size_increment.precision,不一致直接构造失败(见 binary_option.rs)。因此示例中price_increment = 0.001price_precision = 3size_increment = 0.01size_precision = 2
  • margin_init/margin_maint/maker_fee/taker_fee默认为 0:可选参数不传时经unwrap_or_default()落到Decimal(0)(binary_option.rs)。其中 maker/taker 费率按订单价值百分比计算,负值即返佣。
  • info是适配器元数据容器:以 JSON 可序列化字典形式存放交易所附加信息。Python 侧构造时传入dict,绑定层通过from_pydict转成 Rust 的Params;读取时再经 JSON 反序列化回dict(见 binary_option.rs 与py_info)。

行为特性

BinaryOptionInstrumenttrait 层面具有以下固定行为(全部可由 binary_option.rs 的实现直接验证):

  • Instrument class 为BinaryOptioninstrument_class()返回InstrumentClass::BinaryOption,与CurrencyPairCryptoPerpetual等并列。
  • 永不反向(never inverse)is_inverse()恒为false
  • 乘数与手数均为 1multiplier()返回Quantity::from(1)lot_size()返回Some(Quantity::from(1))
  • 无底层资产、无行权价、无期权种类underlying()strike_price()option_kind()isin()exchange()均返回None——二元合约本身就是标的。
  • 报价/结算货币一致quote_currency()settlement_currency()都返回currency字段;base_currency()None
  • 激活与到期时间存在activation_ns()expiration_ns()均返回Some(...)
  • 价格区间由交易所定义:很多交易所把二元结果报价在 0 到 1 之间,但合法价格范围(min_price/max_price)与 tick size 一律以交易所规定为准,模型本身不做假设。
  • 相等性与哈希仅看 IDPartialEqEqHash的实现只比较self.id,同一个合约在不同副本间可正确去重。

单元测试test_trait_accessors对这些行为做了断言(binary_option.rs),例如验证asset_class() == AssetClass::Alternative!is_inverse()price_precision() == 3size_precision() == 2

Rust 构造示例

Rust 侧推荐使用bon构建器模式(BinaryOption::builder()),必填字段在编译期强制,可选字段可省略并沿用默认值:

use jiff::Timestamp; use nautilus_core::UnixNanos; use nautilus_model::{ enums::AssetClass, identifiers::{InstrumentId, Symbol, Venue}, instruments::BinaryOption, types::{Currency, Price, Quantity}, }; use rust_decimal_macros::dec; use ustr::Ustr; let raw_symbol = Symbol::from( "0x12a0cb60174abc437bf1178367c72d11f069e1a3add20b148fb0ab4279b772b2-92544998123698303655208967887569360731013655782348975589292031774495159624905", ); let expiration: Timestamp = "2024-01-01T00:00:00Z".parse().unwrap(); let yes_outcome = BinaryOption::builder() .instrument_id(InstrumentId::new(raw_symbol, Venue::from("POLYMARKET"))) .raw_symbol(raw_symbol) .asset_class(AssetClass::Alternative) .currency(Currency::from("USDC")) .activation_ns(UnixNanos::default()) .expiration_ns(UnixNanos::from(expiration)) .price_precision(3) .size_precision(2) .price_increment(Price::from("0.001")) .size_increment(Quantity::from("0.01")) .outcome(Ustr::from("Yes")) .description(Ustr::from("Will the outcome of this market be 'Yes'?")) .min_quantity(Quantity::from("5")) .maker_fee(dec!(0)) .taker_fee(dec!(0)) .ts_event(UnixNanos::default()) .ts_init(UnixNanos::default()) .build() .unwrap();

构建期校验机制

build()内部走build_checkednew_checked,执行四类正确性检查(binary_option.rs):

  1. 精度一致性check_equal_u8(price_precision, price_increment.precision, ...)check_equal_u8(size_precision, size_increment.precision, ...)
  2. 正增量check_positive_price(price_increment)check_positive_quantity(size_increment)
  3. tick scheme 合法性check_tick_scheme(tick_scheme)验证可变 tick 方案名是否已注册;
  4. 任一检查失败即返回CorrectnessResult错误,unwrap()会 panic,生产代码建议显式处理。

测试test_new_checked_price_precision_mismatch专门构造了price_precision = 4price_increment = 0.001(精度 3)的不一致组合,断言构造返回Err;而test_builder_matches_new_checked则验证构建器结果与全位置参数构造结果完全一致,证明两条构造路径共享同一套校验逻辑(binary_option.rs)。

Python 构造示例

Python 侧通过 pyo3 绑定直接调用构造函数。ts_event/ts_init传纳秒整数,时间戳可用pandas.Timestamp(..., tz="UTC").value转换:

from decimal import Decimal import pandas as pd from nautilus_trader.model import AssetClass from nautilus_trader.model import BinaryOption from nautilus_trader.model import Currency from nautilus_trader.model import InstrumentId from nautilus_trader.model import Price from nautilus_trader.model import Quantity from nautilus_trader.model import Symbol from nautilus_trader.model import Venue raw_symbol = Symbol( "0x12a0cb60174abc437bf1178367c72d11f069e1a3add20b148fb0ab4279b772b2-92544998123698303655208967887569360731013655782348975589292031774495159624905", ) price_increment = Price.from_str("0.001") size_increment = Quantity.from_str("0.01") yes_outcome = BinaryOption( instrument_id=InstrumentId(raw_symbol, Venue("POLYMARKET")), raw_symbol=raw_symbol, asset_class=AssetClass.ALTERNATIVE, currency=Currency.from_str("USDC"), activation_ns=0, expiration_ns=pd.Timestamp("2024-01-01", tz="UTC").value, price_precision=price_increment.precision, size_precision=size_increment.precision, price_increment=price_increment, size_increment=size_increment, min_quantity=Quantity.from_int(5), maker_fee=Decimal(0), taker_fee=Decimal(0), outcome="Yes", description="Will the outcome of this market be 'Yes'?", ts_event=0, ts_init=0, )

Python 绑定的构造签名与序列化

Python 构造函数的完整签名定义在 crates/model/src/python/instruments/binary_option.rs:除 12 个必填参数外,outcomedescriptionmax_quantitymin_quantitymax_notionalmin_notionalmax_pricemin_pricemargin_initmargin_maintmaker_feetaker_feetick_schemeinfo均可选,默认与 Rust 侧一致。绑定层最终仍调用同一套 Rust 构建器,因此price_precisionprice_increment.precision不一致时同样会抛出异常。

模型还内置了字典序列化能力:

  • BinaryOption.to_dict()输出含typeidraw_symbolasset_classcurrencymargin_initmaker_feetaker_fee等全部字段的dictoutcome/description/数量/价格等可选字段按None处理,info序列化为嵌套dict);
  • BinaryOption.from_dict(values)反序列化还原对象,test_dict_round_trip验证了往返一致性(binary_option.rs)。

这也意味着BinaryOption可以随 Parquet/Arrow 等持久化链路存储,配合 docs/concepts/event_sourcing.md 实现事件溯源。

适配器中的 BinaryOption

仓库中已有多个实盘适配器创建或消费BinaryOption,是理解该模型真实用法的第一手资料:

  • Hyperliquid(二元与预测类市场):在 crates/adapters/hyperliquid/src/http/parse.rs 中通过BinaryOption::builder()构造,并将结构化元数据暴露为BinaryOption.info(同文件第 92 行注释);解析 HIP-4 标准的 "Yes"/"No" 标签后写入outcome字段(第 1999 行附近)。
  • Polymarket(预测市场结果):适配器在多个环节消费BinaryOption,例如 crates/adapters/polymarket/src/common/models.rs 中if let InstrumentAny::BinaryOption(opt)模式匹配提取合约;行情加载、持仓对账(reconciliation)、订单解析等模块均围绕该模型展开。
  • OKX(交易所自定义二元结果产品):在 crates/adapters/okx/src/common/parse.rs 中完成行情到BinaryOption的映射。

各适配器的完整集成说明见:

  • docs/integrations/hyperliquid.md
  • docs/integrations/okx.md
  • docs/integrations/polymarket.md

相关概念延伸

  • docs/concepts/order_book.md:覆盖二元市场的订单簿行为——二元合约同样以标准订单簿驱动,价格区间在 0~1 时 tick 语义由price_increment决定;
  • docs/concepts/data/:讲解引用这些合约的市场数据(行情、tick、bar)如何在 Nautilus Trader 中流转;
  • docs/concepts/instruments/:BinaryOption所在的工具族总览,可对照普通期权、期货等模型的差异。

小结

BinaryOption用一个结构体同时覆盖预测市场、二元期权与 Yes/No 合约三类场景,靠的是"通用字段 + 交易所自定义"的设计:通用性由 25 个标准字段与Instrumenttrait 保证,交易所差异则通过raw_symboloutcomedescriptioninfo与价格区间字段吸收。构造侧的精度一致性校验(price_precision/size_precision与 increment 强绑定)从源头杜绝脏数据进入交易链路,而 Rust builder 与 Python 构造函数共享同一套校验实现,确保了双语言行为一致。配合 Hyperliquid、Polymarket、OKX 等适配器的现成实现,开发者可以快速将二元合约纳入回测与实盘策略。

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

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

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

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

立即咨询