news 2026/9/12 16:25:36

NautilusTrader 执行体系全解析:从订单提交、风险管理到成交修正的完整链路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NautilusTrader 执行体系全解析:从订单提交、风险管理到成交修正的完整链路

NautilusTrader 执行体系全解析:从订单提交、风险管理到成交修正的完整链路

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

导读

NautilusTrader 是一套生产级的 Rust 原生事件驱动交易引擎。执行(Execution)子系统是其核心:它负责协调订单提交、风险校验、交易所成交、对账(reconciliation)与持仓更新,让多个策略、多个交易所(venue)在同一套确定性消息流中协同工作。本文以 docs/concepts/execution/index.md 为骨架,结合 crates/execution 与 crates/risk 的源码实现,系统讲解执行链路中的各个组件、OMS 类型、风险引擎规则、取消路由、命令结果分类、订单拒绝原因码,以及超额成交(overfill)与成交修正(fill correction)等高级话题。读完本文,你将能回答"一个订单命令从策略发出到交易所成交,中间经过了哪些组件、哪几条路由、哪些校验"这一核心问题,并掌握相关的配置项与排查依据。


一、执行组件全景

执行子系统主要由以下组件构成:

组件职责
Strategy交易策略,负责发起订单与执行相关的命令
ExecutionAlgorithm执行算法,负责将主订单拆分为更小的派生订单(如 TWAP)
OrderEmulator订单模拟器,支持在本地模拟订单生命周期(如模拟滑点、盘口)
RiskEngine风险引擎,位于提交与修改路径上,执行风险校验
ExecutionEngine执行引擎,核心编排器,管理订单、持仓与对账
ExecutionClient执行客户端,与具体交易所适配器交互,负责命令下发与事件上报

其中ExecutionEngine的配置结构体定义在 crates/execution/src/engine/config.rs,包含load_cachemanage_own_order_bookssnapshot_orderssnapshot_positionscarry_replay_events_on_reopenallow_overfillsexternal_clients等字段;RiskEngineConfig定义在 crates/risk/src/engine/config.rs,两者都是 Rust 原生实现并通过 Pyo3 绑定暴露给 Python(见 crates/execution/src/python/config.rs 与 crates/risk/src/python/config.rs)。


二、执行流程(Execution flow)

Strategy在数据 actor 能力之上,增加了管理与执行相关的方法:

  • submit_order(...)
  • submit_order_list(...)
  • modify_order(...)
  • cancel_order(...)
  • cancel_orders(...)
  • cancel_all_orders(...)
  • close_position(...)
  • close_all_positions(...)
  • query_account(...)
  • query_order(...)

这些方法通过消息总线发送点对点的执行命令;订单创建时还会发布OrderInitialized等事件。策略侧的方法声明可参见 crates/trading/src/strategy/mod.rs 与 crates/trading/src/strategy/binding.rs(StrategyBinding负责把self.submit_order(...)连接到后端实现)。

2.1 命令的分流规则

不同命令走不同路由:

  • submit_order(...):模拟订单(emulated)路由到OrderEmulator;设置了exec_algorithm_id时路由到ExecutionAlgorithm;其余情况路由到RiskEngine
  • submit_order_list(...):与上面相同的分支逻辑(取决于是否模拟以及exec_algorithm_id)。
  • modify_order(...):模拟订单路由到OrderEmulator;订单带有exec_algorithm_id且仍在本地系统中活跃时路由到ExecutionAlgorithm;其余情况路由到RiskEngine
  • 取消与查询命令:根据命令与订单状态,可直接路由到OrderEmulatorExecutionAlgorithmExecutionEngine

2.2 新订单的下游路径

新订单通常进入以下路径之一:

Strategy -> OrderEmulator 或 ExecutionAlgorithm 或 RiskEngine

其下游流转为:

OrderEmulator -> ExecutionAlgorithm 或 ExecutionEngine ExecutionAlgorithm -> RiskEngine -> ExecutionEngine -> ExecutionClient

用 mermaid 图表示如下(原文档图示的复现):

执行路径先按"模拟"与"算法"两个维度分支,再汇聚到执行引擎与客户端。OrderEmulator发出OrderReleased事件给RiskEngine继续走正常风险校验路径,这是模拟订单与真实订单在风险校验上的统一点。


三、订单管理系统(OMS)

订单管理系统类型(OmsType)决定了某个品种的订单如何映射到持仓。策略与交易所(无论是模拟还是实盘)各自使用OmsType枚举定义的类型。该枚举定义在 crates/model/src/enums.rs,三个变体为:

  • UNSPECIFIED:策略沿用交易所的 OMS 类型。
  • NETTING:每个品种、每个策略合并为一个持仓。
  • HEDGING:每个品种、每个策略可以同时存在多个持仓。

当策略与交易所的 OMS 类型不一致时,ExecutionEngine会在OrderFilled事件上赋值或覆盖position_id。NautilusTrader 中存在"虚拟持仓"(virtual position),但它不是交易所侧独立的持仓。

策略 OMS 与交易所 OMS 的组合结果如下:

策略 OMS交易所 OMS结果
NETTINGNETTING每个品种和策略一个持仓
HEDGINGHEDGING每个品种和策略多个持仓
NETTINGHEDGING跨交易所持仓合并为一个虚拟持仓
HEDGINGNETTING针对交易所单一净持仓维护多个虚拟持仓

如果某个成交(fill)解析到缓存中属于不同品种的持仓,ExecutionEngine会记录错误并丢弃该成交;订单保持非终态,后续合法成交仍可被应用。

3.1 OMS 配置

当策略省略oms_type或使用UNSPECIFIED时,ExecutionEngine沿用交易所的 OMS 类型,且不覆盖交易所的position_id。在回测中,应把回测交易所配置为被建模交易所所使用的 OMS 类型。

交易所的持仓模式可能需要适配器级配置,例如 Binance Futures 对冲模式。

3.2 自定义持仓 ID 与 NETTING

自定义持仓 ID 仅在HEDGINGOMS 下有效。NETTING下每个品种与策略只有一个持仓,其确定性 ID 形式为{instrument_id}-{strategy_id}。这一点在源码中有直接印证:crates/execution/src/engine/mod.rs 的determine_netting_position_id实现为PositionId::new(format!("{}-{}", fill.instrument_id, fill.strategy_id))

ExecutionEngine在提交时强制执行该规则:如果生效的 OMS 解析为NETTING,且submit_order(或submit_order_list)传入的position_id不匹配{instrument_id}-{strategy_id},订单会被拒绝并产生OrderDenied事件说明不匹配。

这条规则仍允许常见的平仓习惯:Strategy.close_position(position)转发position.id,在NETTING下它恰好就是那个确定性 ID,因此会被接受。若想用任意 ID 标记或划分持仓,请将策略配置为oms_type=HEDGING

对于submit_order_list,只要提供了position_id,引擎还会拒绝任何混合品种的订单列表(无论 OMS 类型)——一个持仓只属于一个品种,因此组合会被拒绝并给出明确的OrderDenied原因。混合品种订单列表的更多注意事项见 订单列表。

3.3 NETTING 周期间的持仓重放

NETTING下,引擎在平仓与重新开仓的周期之间复用同一个持仓 ID,因此该持仓的重放日志会累积该 ID 上曾经应用过的所有成交。ExecutionEngineConfig.carry_replay_events_on_reopen控制该日志在重新开仓后是否保留:

carry_replay_events_on_reopen行为
False(默认)只保留当前周期的状态,限制每次成交的成本
True保留早期周期的成交使其可被修正,但持仓状态可能增长

实盘交易固定将该选项置为TrueLiveExecutionEngineConfig始终携带重放日志,这样引用早期周期的交易所OrderFillVoided事件仍能被解析。模拟交易所从不发出 fill void,因此回测采用有界的默认值。当使用自定义或外部执行客户端、且它可能修正来自先前周期的成交时,需要显式启用该选项;否则引擎找不到匹配的持仓片段,会拒绝该修正。

已实现盈亏(Realized-PnL)快照会跟随修正。一个触及早期周期的 fill void 会跨周期边界重建持仓,从而移动其归档快照所描述的边界,引擎会将这些快照结算进修正后历史自身的已关闭周期中,保证已实现盈亏对每个周期只统计一次。仅局限于当前周期的 void 不会破坏归档。详见 Position snapshotting。

源码佐证:crates/execution/src/engine/config.rs 注释说明"Enable to keep fills from earlier cycles correctable by anOrderFillVoided";crates/execution/src/engine/mod.rs 中carry_replay_events_on_reopentrue时引擎会克隆先前持仓以携带跨周期的重放状态。


四、风险引擎(RiskEngine)

RiskEngine是每个 Nautilus 系统(回测、沙箱、实盘)的组成部分。它位于提交与修改路径上,同时也会收到来自OrderEmulatorOrderReleased等订单事件。取消与查询命令直接路由到其他执行组件,不经过RiskEngine

除非在RiskEngineConfig中显式bypass,否则引擎会校验:

  • 品种的价格与触发价精度。
  • 价格为正(除非品种允许负价格:期权、期货价差、期权价差、现货大宗商品)。
  • 数量精度与基础数量最小/最大值边界。
  • GTD 订单未过期。
  • reduce_only订单不会增大被引用的持仓。
  • 引擎级max_notional_per_order限额与品种的min_notionalmax_notional字段。
  • 非保证金账户的现金账户余额影响。
  • 提交与修改的速率限制。
  • 交易状态限制(ACTIVEHALTEDREDUCING)。

提交时的风险校验失败会生成带标准化 原因码 的OrderDenied事件;修改时的失败则生成OrderModifyRejected事件。

4.1 整仓条件退出(Whole-position conditional exits)

部分执行客户端支持"条件退出":触发时由交易所根据当前持仓决定平仓数量。Nautilus 的订单仍会携带一个占位数量(placeholder quantity)供本地校验。RiskEngineConfigLiveRiskEngineConfig上的full_position_exit_venues设置用于标识执行客户端强制执行上述语义的交易所,默认为空。源码中该字段为AHashSet<Venue>,见 crates/risk/src/engine/config.rs。

订单只有在满足以下全部条件时才享有占位数量豁免:

  • 订单单独提交,而非在订单列表中。
  • 其交易所列于full_position_exit_venues
  • 使用受支持的期货或永续合约品种。
  • 是带触发价的StopMarketMarketIfTouched订单,且close_position=true
  • 占位数量为正且设置reduce_only=true
  • 命令、订单与被引用的缓存持仓使用相同的品种与持仓 ID。
  • 被引用的持仓处于开启状态、订单方向与之相反,且占位数量不超过持仓数量。

对符合条件的退出订单,风险引擎的校验处理如下:

风险校验处理方式
数量精度与正数性强制执行
价格与触发价精度与正数性强制执行
GTD 过期、交易状态限制、提交速率限制强制执行
持仓敞口、保证金与余额视为减仓处理
品种最小/最大数量对占位数量跳过
品种最小/最大名义价值对占位名义价值跳过
配置的max_notional_per_order对占位名义价值跳过
不满足条件的订单全部常规风险校验照常适用

只有当下游执行客户端确实强制执行整仓平仓时,才应将该交易所加入白名单。受支持的配置示例见 Binance Futures 平仓订单。

:::warning 模拟交易所不会解释close_position,也不会用当前持仓数量替换占位数量。因此不要把模拟回测交易所加入full_position_exit_venues;回测退出请改用显式数量加reduce_only来建模。 :::

4.2 交易状态(Trading state)

交易状态依次变得更严格:

状态数值允许的命令
ACTIVE1提交、修改、取消、查询命令正常运行
REDUCING2符合条件的单独 reduce-only 提交、取消与查询
HALTED3仅取消与查询,不允许新提交与修改

REDUCING状态下,只有当订单设置reduce_only=true、命令与订单指向同一品种、提供的持仓 ID 与订单缓存的开启持仓一致时,单独的SubmitOrder才被允许;订单方向必须与持仓相反,且提交数量不得超过缓存持仓数量。订单列表与修改命令一律被拒绝。

风险引擎在转发命令前应用这些规则。启用RiskEngineConfig.bypass后交易状态不再被强制;执行客户端仍遵循 reduce-only send-or-reject 契约。

RiskEngineConfig的完整配置细节可参考 Python API 参考文档中的nautilus_trader.risk.RiskEngineConfig


五、执行算法(Execution algorithms)

ExecutionAlgorithm接收由exec_algorithm_id选中的主订单(primary order),并可将其拆分为更小的派生订单(spawned orders)。NautilusTrader 支持自定义算法,并内置了原生 Rust 实现的 TWAP。

TWAP 配置、自定义算法、派生订单行为与缓存查询,详见 执行算法。


六、取消全部路由(Cancel-all routing)

Strategy.cancel_all_orders(...)支持策略范围与宽泛两种取消模式:

strategy_only策略输出范围下游路由
True每个匹配订单一个CancelOrder与调用策略关联的匹配订单每个订单走其常规取消路由
False一个根CancelAllOrders(即使本地没有匹配)解析出的单个执行客户端与账户上的匹配订单执行引擎创建所需子命令

宽泛模式在策略检查其缓存之前就进行委托,因此即使 NautilusTrader 本地没有匹配订单,命令也能到达解析出的执行客户端。这允许交易所的批量取消端点删除"存在于交易所但本地缓存缺失"的订单;当适配器提供此类端点时,单条命令还能减少取消请求量。

6.1 本地客户端解析顺序

对于本地执行客户端,ExecutionEngine按以下顺序把根命令解析到恰好一个客户端:

  1. 显式指定的client_id(当它标识一个已注册的本地客户端时)。
  2. 为该品种交易所注册的客户端。
  3. 默认执行客户端。

随后引擎为选中的客户端及其账户创建全新的子命令:

  • 一个覆盖该执行客户端匹配交易所订单的CancelAllOrders
  • 一个覆盖OrderEmulator匹配模拟订单的CancelAllOrders
  • 每个符合条件的活跃本地执行算法订单一个CancelOrder

流程如下(原文档图示的复现):

6.2 子命令与归属规则

宽泛模式在扇出之前只选择一个客户端,绝不会向所有执行客户端广播。若要在多个客户端上取消,需要对每个客户端分别调用一次cancel_all_orders(...)

每个子命令都有新的命令 ID,复制根参数,与根操作关联,并把根命令记录为自身的 cause。品种与可选方向过滤适用于每一条本地路由。选中的执行账户还界定了匹配引擎的取消范围,包括SUBMITTED及其他可取消的在途状态订单。

客户端归属(client ownership)适用于本地模拟订单与执行算法订单:

  • 已归属其他客户端的订单保持不动。
  • 根命令省略client_id时,引擎在本地取消前会把匹配的未归属订单归属给选中的客户端。
  • 根命令提供client_id时,未归属订单保持不动——引擎无法推断它们属于该显式客户端。
  • 模拟订单匹配其交易品种,即使触发价来自另一个品种。

显式配置的外部执行客户端会原样收到根命令;边界之后的所有扇出由外部客户端自行负责。


七、命令结果分类(Command outcomes)

执行命令区分三类结果:确定的本地失败、确定的交易所结果、未知的实盘结果。未知结果保持"在途"状态,等待流更新、轮询、查询或对账来推进;重试耗尽后可以应用一个合成的终端对账事件。

证据类别、投递与重试限制、持久化边界、终端对账来源,详见 执行策略:命令结果;持续对账流程见 执行对账:运行时检查。


八、订单拒绝原因码(Order denied reasons)

本地拒绝(OrderDenied)携带标准化的CATEGORY_CONDITION原因码,并可能附带诊断后缀;只有前导码是规范性的。消息使用这些形式:

  • CODE:拒绝不需要诊断后缀。
  • CODE: value:一个类型化值或自由文本诊断。
  • CODE: key=value, key=value:多个类型化值需要消歧义。
  • CODE: value; free text:一个类型化值后跟自由文本诊断。

下表覆盖执行算法与客户端以及风险、执行引擎发出的本地拒绝。这些码是本地被拒订单的事实来源。交易所确认的OrderRejected事件携带的是交易所提供的含义;合成对账拒绝使用 终端对账来源 中记录的原因。适配器在发出前会去除协议包装并限制不可信的交易所文本,而不会用标准化本地拒绝码替换它。

价格与数量校验也可以在OrderModifyRejected上发出以下带码原因:

  • PRICE_PRECISION_EXCEEDS_MAXIMUM
  • PRICE_NOT_POSITIVE
  • QUANTITY_PRECISION_EXCEEDS_MAXIMUM
  • QUANTITY_EXCEEDS_MAXIMUM
  • QUANTITY_BELOW_MINIMUM

对于价格类原因,fieldPRICETRIGGER_PRICE,指明被拒的命令字段。其他修改拒绝原因保持自由文本;OrderDeniedCode不对它们分类。

OrderRejected.due_post_only仅在交易所证据证明 post-only 订单会穿过或立即成交时为true;其他交易所拒绝保持false

下表由OrderDeniedReason枚举(crates/model)生成。重新生成命令:cargo test -p nautilus-model regenerate_order_denied_reasons_doc -- --ignored

CodeDescription
PRICE_PRECISION_EXCEEDS_MAXIMUMThe price precision exceeds the instrument maximum.
PRICE_NOT_POSITIVEThe price is not positive.
QUANTITY_PRECISION_EXCEEDS_MAXIMUMThe quantity precision exceeds the instrument maximum.
QUANTITY_CONVERSION_FAILEDThe order quantity could not be converted for risk checks.
QUANTITY_EXCEEDS_MAXIMUMThe effective order quantity exceeds the instrument maximum.
QUANTITY_BELOW_MINIMUMThe effective order quantity is below the instrument minimum.
INVALID_MAX_NOTIONAL_PER_ORDERThe configured maximum notional per order is invalid.
MISSING_EXPIRE_TIMEA GTD order is missing its expire time.
EXPIRE_TIME_IN_PASTThe order's expire time is in the past.
MISSING_TRAILING_OFFSET_TYPEThe order is missing a required trailing offset type.
UNSUPPORTED_TRAILING_OFFSET_TYPEThe order's trailing offset type is not supported.
MISSING_TRIGGER_TYPEThe order is missing a required trigger type.
MISSING_TRAILING_OFFSETThe order is missing a required trailing offset.
INSTRUMENT_NOT_FOUNDThe instrument was not found in the cache.
POSITION_NOT_FOUNDThe position for a reduce-only order was not found.
MARKET_PRICE_UNAVAILABLENo market price is available for the order risk check.
TRAILING_STOP_CALCULATION_FAILEDThe trailing stop trigger price could not be calculated.
NOTIONAL_CALCULATION_FAILEDThe order notional value could not be calculated.
NOTIONAL_BELOW_MINIMUMThe order notional is below the instrument minimum.
NOTIONAL_EXCEEDS_MAXIMUMThe order notional exceeds the instrument maximum.
NOTIONAL_EXCEEDS_MAX_PER_ORDERThe order notional exceeds the configured maximum per order.
NOTIONAL_EXCEEDS_FREE_BALANCEThe order notional exceeds the account free balance.
INITIAL_MARGIN_CALCULATION_FAILEDThe order initial margin could not be calculated.
INITIAL_MARGIN_EXCEEDS_FREE_BALANCEThe order initial margin exceeds the account free balance.
BETTING_BALANCE_LOCKED_CALCULATION_FAILEDThe balance to lock for the betting order could not be calculated.
CUMULATIVE_NOTIONAL_EXCEEDS_FREE_BALANCEThe cumulative order notional exceeds the account free balance.
CUMULATIVE_INITIAL_MARGIN_CALCULATION_FAILEDThe cumulative initial margin could not be calculated.
CUMULATIVE_INITIAL_MARGIN_EXCEEDS_FREE_BALANCEThe cumulative initial margin exceeds the account free balance.
REDUCE_ONLY_WOULD_INCREASE_POSITIONA reduce-only order would increase the position.
ORDER_LIST_INCOMPLETEThe order list is missing orders in the cache.
ORDER_LIST_DENIEDThe order was denied because its order list failed risk checks.
TRADING_HALTEDTrading is halted; new submissions and modifications are denied.
TRADING_STATE_REDUCINGTrading is reducing; only eligible reduce-only submissions are permitted.
RATE_LIMIT_EXCEEDEDThe order submission rate limit was exceeded.
STREAM_RECONCILINGThe execution stream is unavailable or recovering; retry after recovery.
NO_EXECUTION_CLIENTNo execution client was found for the routed command.
CLIENT_VENUE_MISMATCHThe execution client does not handle the order venue.
SUBMIT_FAILEDSubmitting the order to the execution client failed.
INVALID_CLIENT_ORDER_IDThe client order ID is invalid for the venue.
INVALID_POSITION_IDThe supplied position ID is invalid for the order submission.
UNSUPPORTED_ORDER_LISTThe venue does not support the requested order list.
UNSUPPORTED_ORDER_TYPEThe order type is not supported.
UNSUPPORTED_REDUCE_ONLYThe execution client or venue does not support the requested reduce-only instruction.
UNSUPPORTED_TIME_IN_FORCEThe order's time in force is not supported.
UNSUPPORTED_TP_SLThe venue does not support the requested take-profit/stop-loss parameters.
VALIDATION_FAILEDThe order failed validation before submission.

九、自有订单簿(Own order books)

启用manage_own_order_books后,ExecutionEngine会为每个品种维护你方在途订单的按订单簿(MBO/L3)视图。策略可以从公开盘口中减去这些订单,以估算净可用流动性。生命周期、查询、过滤与审计见 自有订单簿。

9.1 安全取消查询

在查询自有订单簿中的取消候选时,应从status过滤器中排除PENDING_CANCEL

:::warning 包含PENDING_CANCEL可能导致重复的取消请求,并反复选中那些已等待确认的订单。 :::


十、超额成交(Overfills)

超额成交指订单累计成交数量超过其原始数量。例如,总成交 110 单位相对于 100 单位的订单超额 10 单位。

10.1 超额成交如何产生

当上报数量超过订单数量时,引擎观察到超额成交。这可能是真实的交易所结果、不同 trade ID 下的重复投递,或交易所报告不一致——仅凭数量无法识别原因。

实盘成交可通过两个渠道到达:

  • 通过 WebSocket 实时到达的成交事件。
  • 周期性对账轮询交易所的成交历史与持仓状态。

稳定的trade_id让引擎能跨两个渠道对同一成交去重。如果逻辑上的同一成交以不同 ID 到达,引擎会把它们当作不同的报告。连续对账的配置见 配置实盘交易:连续对账。

10.2 系统行为

ExecutionEngine在应用每个成交事件前,会比较订单当前的filled_qty加上入站的last_qty与原始quantity,以检查潜在超额成交。源码可见 crates/execution/src/engine/mod.rs:calculate_overfill为正时,若allow_overfills=false则记录警告并拒绝该成交(提示可在ExecutionEngineConfig中开启allow_overfills),若为true则记录警告并应用。

allow_overfills配置选项(默认False)控制处理方式:

allow_overfills行为
False记录日志并拒绝该成交,保持订单当前状态
True记录警告、应用该成交,并在overfill_qty中跟踪超额部分

允许超额时,订单的overfill_qty字段跟踪超额数量;订单转入FILLED状态,leaves_qty被钳制为零。

10.3 重复成交检测

Order模型对每个trade_id只允许应用一个成交。Order.apply()在相同 ID 已存在于订单上时返回错误。接口定义于 crates/model/src/orders/mod.rs 的Ordertrait,各订单类型(如 market.rs、limit.rs)分别实现apply

核心引擎路径

应用成交前,ExecutionEngine调用Order.is_duplicate_fill(),比较:

  • trade_id
  • order_side
  • last_px
  • last_qty

完全匹配则跳过并记录警告。若trade_id匹配但其他字段不同,四字段检查不会将其归类为完全重复;随后Order.apply()会拒绝被复用的 ID,引擎记录日志并丢弃该成交。crates/execution/src/engine/mod.rs 中validate_fill_for_order调用is_duplicate_fill并对重复成交发出警告跳过。

对账路径

对账路径在生成OrderFilled事件前检查trade_id;当该 ID 已存在于订单上时丢弃报告,无论其价格或数量如何。

合成与推断的对账成交使用确定性 ID。重启后重放相同输入会产生相同的trade_id,从而被去重。

10.4 配置

实盘交易可在LiveExecutionEngineConfig中开启超额容忍:

from nautilus_trader.config import LiveExecutionEngineConfig config = LiveExecutionEngineConfig( allow_overfills=True, )

:::warning 请根据交易所的执行契约选择该设置。默认False保护本地状态,但合法交易所超额成交后可能留下差异;True会应用超额数量,且不能替代重复成交检测。请使用执行对账检测差异。 :::


十一、成交修正(Fill corrections)

部分交易所后续会减少或作废一笔成交。Nautilus 将其记录为OrderFillVoided事件,绝不以反向成交表示。事件标识原始交易,携带累计作废数量与费用修正。

执行引擎在把修正发布给策略与执行算法前,会重建受影响的订单与持仓,并刷新组合持仓与 PnL 缓存。支持成交修正的适配器会在 void 后请求一次权威账户刷新。

适配器必须先发布被引用的成交,然后才能进行重新打开的修正或使订单保持可执行的局部修正。若本地没有该成交,非重新打开的修正会使整个订单进入终态——即使voided_qty小于订单数量。后续的 working 状态报告不会重新打开VOIDED。完整契约见OrderFillVoided契约。

11.1 作废成交如何产生

作废是交易所对其已报告交易采取的行动。其原因跨资产类别反复出现:

  • 错误执行审查:交易所作废一笔与成交时市场严重不一致的打印,或由交易所系统故障导致的成交。
  • 结算失败:已撮合交易未能结算,成交从未产生经济效果。
  • 事件失效:底层事件被放弃或对手方被撤出,撮合后的持仓不承担敞口。
  • 交易后重述:交易所在清算期间重述交易的数量或费用。

该事件不重述成交价格,因此交易所的价格调整无法用单次修正表达。

不同交易所的 break 到达客户端的方式不同。FIX 交易所通过ExecType <150>H(trade cancel)与G(trade correct)值发出信号;带外通知的交易所则让 break 通过执行对账浮现。

11.2 交易所参考

各交易所公布其采取行动的条件(原文中的外部链接此处从略,仅保留机制与说明):

交易所机制说明
NasdaqClearly erroneous transactions(规则 11890)明显错误交易政策
NYSEClearly erroneous executions(规则 7.10)明显错误执行审查
Cboe US equitiesClearly erroneous executions(BZX 规则 11.17)明显错误执行表格
CME GroupTrade cancellations and price adjustments(规则 588)交易取消与价格调整
BetfairVoided bets,以累计作废规模(sv)报告Stream API 对作废投注的处理
Polymarket链上回滚或重组后的FAILED交易状态user channel

Nautilus 适配器在交易所通过其消费的流发布作废时发出OrderFillVoided:Betfair 来自订单变更消息的sv字段,Polymarket 来自 user channel 的交易状态。


十二、相关指南

  • 事件(Events):订单与持仓事件类型及其分发。
  • 执行算法:TWAP、自定义算法与派生订单。
  • 执行策略:投递、状态、持久化与恢复边界。
  • 执行对账:实盘状态恢复与运行时一致性检查。
  • 订单簿:公开与自有订单簿行为。
  • 订单(Orders):订单类型与管理。
  • 持仓(Positions):从执行结果跟踪持仓。
  • 策略(Strategies):策略侧订单提交。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 16:24:20

ESP32与HC-SR501人体感应模块零基础实战:从原理到感应灯

如果你第一次接触 ESP32&#xff0c;又恰好想做个“人一来就有反应”的装置——比如进门自动亮灯、感应报警器、或者统计房间里有没有人——那你大概率会搜到一块叫HC-SR501的小板子。它非常便宜&#xff0c;几块钱一块&#xff0c;圆形白色透镜&#xff0c;翠绿色的电路板&…

作者头像 李华
网站建设 2026/9/12 16:22:46

AI辅助学术写作:2025届毕业生的高效工具链

1. 2025届学术写作的AI革命2025届毕业生正面临学术写作范式的重大变革。我最近指导了几位本科生使用AI工具完成毕业论文&#xff0c;从开题到答辩仅用传统方法1/3的时间就达到了优秀水平。这并非个例——根据Nature最新调研&#xff0c;85%的顶尖高校教授已接受AI辅助的学术论文…

作者头像 李华
网站建设 2026/9/12 16:22:08

组合优化与凸优化实验指南:从梯度下降到拉格朗日对偶的实践路径

简介&#xff1a;哈工大组合优化与凸优化研究生课程实验资料包&#xff0c;面向修读该课程的研究生以及希望系统入门优化领域的算法工程师。资料以动手实验为主线&#xff0c;配合详尽的实验报告和说明书&#xff0c;帮助读者将拉格朗日对偶、KKT条件、梯度下降、牛顿法等理论概…

作者头像 李华