Skip to content

Execution

Loren1166 edited this page Sep 23, 2024 · 5 revisions

Execution 执行

NautilusTrader can handle trade execution and order management for multiple strategies and venues simultaneously (per instance). Several interacting components are involved in execution, making it crucial to understand the possible flows of execution messages (commands and events).

NautilusTrader 可以同时处理多个策略和交易平台的交易执行和订单管理(每个实例)。执行涉及多个交互组件,因此了解执行消息(命令和事件)的可能流程至关重要。

The main execution-related components include:

与执行相关的组件包括:

  • Strategy 策略
  • ExecAlgorithm (execution algorithms) 执行算法
  • OrderEmulator 订单模拟器
  • RiskEngine 风险引擎
  • ExecutionEngine or LiveExecutionEngine 执行引擎或实时执行引擎
  • ExecutionClient or LiveExecutionClient 执行客户端或实时执行客户端

Execution flow 执行流程

The Strategy base class inherits from Actor and so contains all of the common data related methods. It also provides methods for managing orders and trade execution:

Strategy 基类继承自 Actor,因此包含所有与数据相关的通用方法。它还提供了管理订单和交易执行的方法:

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

These methods create the necessary execution commands under the hood and send them on the message bus to the relevant components (point-to-point), as well as publishing any events (such as the initialization of new orders i.e. OrderInitialized events).

这些方法在后台创建必要的执行命令,并将它们通过消息总线发送到相关组件(点对点),以及发布任何事件(例如新订单的初始化,即 OrderInitialized 事件)。

The general execution flow looks like the following (each arrow indicates movement across the message bus):

一般执行流程如下所示(每个箭头表示跨消息总线的移动):

Strategy -> OrderEmulator -> ExecAlgorithm -> RiskEngine -> ExecutionEngine -> ExecutionClient

策略 -> 订单模拟器 -> 执行算法 -> 风险引擎 -> 执行引擎 -> 执行客户端

The OrderEmulator and ExecAlgorithm(s) components are optional in the flow, depending on individual order parameters (as explained below).

OrderEmulatorExecAlgorithm(s) 组件在流程中是可选的,具体取决于各个订单参数(如下所述)。

This diagram illustrates message flow (commands and events) across the Nautilus execution components.

此图说明了 Nautilus 执行组件之间的消息流(命令和事件)。

                  ┌───────────────────┐
                  │                   │
                  │                   │
                  │                   │
          ┌───────►   OrderEmulator   ├────────────┐
          │       │                   │            │
          │       │                   │            │
          │       │                   │            │
┌─────────┴──┐    └─────▲──────┬──────┘            │
│            │          │      │           ┌───────▼────────┐   ┌─────────────────────┐   ┌─────────────────────┐
│            │          │      │           │                │   │                     │   │                     │
│            ├──────────┼──────┼───────────►                ├───►                     ├───►                     │
│  Strategy  │          │      │           │                │   │                     │   │                     │
│            │          │      │           │   RiskEngine   │   │   ExecutionEngine   │   │   ExecutionClient   │
│            ◄──────────┼──────┼───────────┤                ◄───┤                     ◄───┤                     │
│            │          │      │           │                │   │                     │   │                     │
│            │          │      │           │                │   │                     │   │                     │
└─────────┬──┘    ┌─────┴──────▼──────┐    └───────▲────────┘   └─────────────────────┘   └─────────────────────┘
          │       │                   │            │
          │       │                   │            │
          │       │                   │            │
          └───────►   ExecAlgorithm   ├────────────┘
                  │                   │
                  │                   │
                  │                   │
                  └───────────────────┘

Order Management System (OMS) 订单管理系统 (OMS)

An order management system (OMS) type refers to the method used for assigning orders to positions and tracking those positions for an instrument. OMS types apply to both strategies and venues (simulated and real). Even if a venue doesn't explicitly state the method in use, an OMS type is always in effect. The OMS type for a component can be specified using the OmsType enum.

订单管理系统 (OMS) 类型是指用于将订单分配给头寸并跟踪Instrument的这些头寸的方法。OMS 类型适用于策略和交易平台(模拟和真实)。即使交易平台没有明确说明使用的方法,OMS 类型也始终有效。可以使用 OmsType 枚举指定组件的 OMS 类型。

The OmsType enum has three variants:

OmsType 枚举有三个变体:

  • UNSPECIFIED: The OMS type defaults based on where it is applied (details below). 未指定:OMS 类型根据应用位置的默认值(详细信息如下)。
  • NETTING: Positions are combined into a single position per instrument ID. 净额结算:头寸按每个Instrument ID 合并为单个头寸。
  • HEDGING: Multiple positions per instrument ID are supported (both long and short). 对冲:支持每个Instrument ID 的多个头寸(多头和空头)。

The table below describes different configuration combinations and their applicable scenarios. When the strategy and venue OMS types differ, the ExecutionEngine handles this by overriding or assigning position_id values for received OrderFilled events. A "virtual position" refers to a position ID that exists within the Nautilus system but not on the venue in reality.

下表描述了不同的配置组合及其适用场景。当策略和交易平台 OMS 类型不同时,ExecutionEngine 通过覆盖或分配接收到的 OrderFilled 事件的 position_id 值来处理此问题。“虚拟头寸”是指存在于 Nautilus 系统中但在交易平台实际上不存在的头寸 ID。

Strategy OMS Venue OMS Description
NETTING NETTING The strategy uses the venues native OMS type, with a single position ID per instrument ID. 策略使用交易平台的原生 OMS 类型,每个Instrument ID 只有一个头寸 ID。
HEDGING HEDGING The strategy uses the venues native OMS type, with multiple position IDs per instrument ID (both LONG and SHORT). 策略使用交易平台的原生 OMS 类型,每个Instrument ID 具有多个头寸 ID(多头和空头)。
NETTING HEDGING The strategy overrides the venues native OMS type. The venue tracks multiple positions per instrument ID, but Nautilus maintains a single position ID.
HEDGING NETTING The strategy overrides the venues native OMS type. The venue tracks a single position per instrument ID, but Nautilus maintains multiple position IDs.

Configuring OMS types separately for strategies and venues increases platform complexity but allows for a wide range of trading styles and preferences (see below).

为策略和交易平台单独配置 OMS 类型会增加平台的复杂性,但允许各种交易风格和偏好(见下文)。

OMS config examples:

OMS 配置示例:

  • Most cryptocurrency exchanges use a NETTING OMS type, representing a single position per market. It may be desirable for a trader to track multiple "virtual" positions for a strategy.

  • Some FX ECNs or brokers use a HEDGING OMS type, tracking multiple positions both LONG and SHORT. The trader may only care about the NET position per currency pair.

  • 大多数加密货币交易所使用 NETTING OMS 类型,表示每个市场只有一个头寸。交易者可能希望跟踪策略的多个“虚拟”头寸。

  • 一些外汇 ECN 或经纪商使用 HEDGING OMS 类型,跟踪多头和空头的多个头寸。交易者可能只关心每个货币对的净头寸。

info 信息

Nautilus does not yet support venue-side hedging modes such as Binance BOTH vs. LONG/SHORT where the venue nets per direction. It is advised to keep Binance account configurations as BOTH so that a single position is netted.

Nautilus 尚未支持交易平台端的对冲模式,例如 Binance 的 BOTH 与 LONG/SHORT,其中交易平台按方向净额结算。建议将 Binance 账户配置保留为 BOTH,以便净额结算单个头寸。

OMS configuration OMS 配置

If a strategy OMS type is not explicitly set using the oms_type configuration option, it will default to UNSPECIFIED. This means the ExecutionEngine will not override any venue position_ids, and the OMS type will follow the venue's OMS type.

如果没有使用 oms_type 配置选项显式设置策略 OMS 类型,则默认值为 UNSPECIFIED。这意味着 ExecutionEngine 不会覆盖任何交易平台的 position_ids,并且 OMS 类型将遵循交易平台的 OMS 类型。

tip 提示

When configuring a backtest, you can specify the oms_type for the venue. To enhance backtest accuracy, it is recommended to match this with the actual OMS type used by the venue in practice.

配置回测时,您可以为交易平台指定 oms_type。为了提高回测的准确性,建议将其与交易平台实际使用的 OMS 类型相匹配。

Risk engine 风险引擎

The RiskEngine is a core component of every Nautilus system, including backtest, sandbox, and live environments. Every order command and event passes through the RiskEngine unless specifically bypassed in the RiskEngineConfig.

RiskEngine 是每个 Nautilus 系统的核心组件,包括回测、沙盒和实时环境。除非在 RiskEngineConfig 中明确绕过,否则每个订单命令和事件都会经过 RiskEngine。

The RiskEngine includes several built-in pre-trade risk checks, including:

RiskEngine 包含几个内置的交易前风险检查,包括:

  • Price precisions correct for the instrument 价格精度是否正确
  • Prices are positive (unless an option type instrument) 价格是否为正数(除非是期权类型Instrument)
  • Quantity precisions correct for the instrument 数量精度是否正确
  • Below maximum notional for the instrument 是否低于该Instrument的最大名义价值
  • Within maximum or minimum quantity for the instrument 是否在该Instrument的最大或最小数量范围内
  • Only reducing position when a reduce_only execution instruction is specified for the order 仅在为订单指定了 reduce_only 执行指令时才减少头寸

If any risk check fails, an OrderDenied event is generated, effectively closing the order and preventing it from progressing further. This event includes a human-readable reason for the denial.

如果任何风险检查失败,将生成 OrderDenied 事件,有效地关闭订单并阻止其进一步进行。此事件包含拒绝的人类可读原因。

Trading state 交易状态

Additionally, the current trading state of a Nautilus system affects order flow.

此外,Nautilus 系统的当前交易状态会影响订单流。

The TradingState enum has three variants:

TradingState 枚举有三个变体:

  • ACTIVE: The system operates normally. 活动:系统正常运行。
  • HALTED: The system will not process further order commands until the state changes. 暂停:系统将不再处理进一步的订单命令,直到状态改变。
  • REDUCING: The system will only process cancels or commands that reduce open positions. 减少:系统将只处理取消或减少未平仓头寸的命令。

info 信息

See the RiskEngineConfig API Reference for further details.

有关更多详细信息,请参阅 RiskEngineConfig API 参考。

Execution algorithms 执行算法

The platform supports customized execution algorithm components and provides some built-in algorithms, such as the Time-Weighted Average Price (TWAP) algorithm.

该平台支持自定义执行算法组件,并提供一些内置算法,例如时间加权平均价格 (TWAP) 算法。

TWAP (Time-Weighted Average Price) TWAP(时间加权平均价格)

The TWAP execution algorithm aims to execute orders by evenly spreading them over a specified time horizon. The algorithm receives a primary order representing the total size and direction then splits this by spawning smaller child orders, which are then executed at regular intervals throughout the time horizon.

TWAP 执行算法旨在通过将订单均匀分布在指定的时间范围内来执行订单。该算法接收表示总规模和方向的主订单,然后通过生成较小的子订单将其拆分,然后在整个时间范围内定期执行这些子订单。

This helps to reduce the impact of the full size of the primary order on the market, by minimizing the concentration of trade size at any given time.

这有助于通过最小化任何给定时间的交易规模集中度来减少主订单的全部规模对市场的影响。

The algorithm will immediately submit the first order, with the final order submitted being the primary order at the end of the horizon period.

该算法将立即提交第一个订单,在时间范围结束时提交的最后一个订单是主订单。

Using the TWAP algorithm as an example (found in /examples/algorithms/twap.py), this example demonstrates how to initialize and register a TWAP execution algorithm directly with a BacktestEngine (assuming an engine is already initialized):

以 TWAP 算法为例(位于 /examples/algorithms/twap.py 中),此示例演示了如何直接使用 BacktestEngine 初始化和注册 TWAP 执行算法(假设引擎已经初始化):

from nautilus_trader.examples.strategies.ema_cross_twap import EMACrossTWAP
from nautilus_trader.examples.strategies.ema_cross_twap import EMACrossTWAPConfig

# Instantiate and add your execution algorithm
# 实例化并添加您的执行算法
exec_algorithm = TWAPExecAlgorithm()
engine.add_exec_algorithm(exec_algorithm)

For this particular algorithm, two parameters must be specified:
# 对于此特定算法,必须指定两个参数:

horizon_secs
interval_secs

The `horizon_secs` parameter determines the time period over which the algorithm will execute, while the `interval_secs` parameter sets the time between individual order executions. These parameters determine how a primary order is split into a series of spawned orders.
# `horizon_secs` 参数确定算法执行的时间段,而 `interval_secs` 参数设置各个订单执行之间的时间。这些参数决定了如何将主订单拆分为一系列生成的订单。

# Configure your strategy
# 配置您的策略
config = EMACrossTWAPConfig(
    instrument_id=ETHUSDT_BINANCE.id,
    bar_type=BarType.from_str("ETHUSDT.BINANCE-250-TICK-LAST-INTERNAL"),
    trade_size=Decimal("0.05"),
    fast_ema_period=10,
    slow_ema_period=20,
    twap_horizon_secs=10.0,  # <-- execution algorithm param 执行算法参数
    twap_interval_secs=2.5,  # <-- execution algorithm param 执行算法参数
)

# Instantiate and add your strategy
# 实例化并添加您的策略
strategy = EMACrossTWAP(config=config)

Alternatively, you can specify these parameters dynamically per order, determining them based on actual market conditions. In this case, the strategy configuration parameters could be provided to an execution model which determines the horizon and interval.

或者,您可以为每个订单动态指定这些参数,根据实际市场情况确定它们。在这种情况下,可以将策略配置参数提供给确定范围和间隔的执行模型。

info 信息

There is no limit to the number of execution algorithm parameters you can create. The parameters just need to be a dictionary with string keys and primitive values (values that can be serialized over the wire, such as ints, floats, and strings).

您可以创建的执行算法参数数量没有限制。参数只需要是一个字典,其中包含字符串键和原始值(可以通过网络序列化的值,例如整数、浮点数和字符串)。

Writing execution algorithms 编写执行算法

To implement a custom execution algorithm you must define a class which inherits from ExecAlgorithm.

要实现自定义执行算法,您必须定义一个继承自 ExecAlgorithm 的类。

An execution algorithm is a type of Actor, so it's capable of the following:

执行算法是一种 Actor,因此它能够执行以下操作:

  • Request and subscribe to data 请求和订阅数据
  • Access the Cache 访问缓存
  • Set time alerts and/or timers using a Clock 使用 Clock 设置时间警报和/或计时器

Additionally it can:

此外,它还可以:

  • Access the central Portfolio 访问中央投资组合
  • Spawn secondary orders from a received primary (original) order 从接收到的主(原始)订单生成辅助订单

Once an execution algorithm is registered, and the system is running, it will receive orders off the messages bus which are addressed to its ExecAlgorithmId via the exec_algorithm_id order parameter. The order may also carry the exec_algorithm_params being a dict[str, Any].

一旦注册了执行算法,并且系统正在运行,它将通过消息总线接收订单,这些订单通过 exec_algorithm_id 订单参数寻址到其 ExecAlgorithmId。订单还可以携带 exec_algorithm_params,它是一个 dict[str, Any]

warning 警告

Because of the flexibility of the exec_algorithm_params dictionary. It's important to thoroughly validate all of the key value pairs for correct operation of the algorithm (for starters that the dictionary is not None and all necessary parameters actually exist).

由于 exec_algorithm_params 字典的灵活性,彻底验证所有键值对以确保算法的正确操作非常重要(首先,字典不是 None 并且所有必要的参数实际上都存在)。

Received orders will arrive via the following on_order(...) method. These received orders are know as "primary" (original) orders when being handled by an execution algorithm.

收到的订单将通过以下 on_order(...) 方法到达。当由执行算法处理时,这些收到的订单被称为“主”(原始)订单。

from nautilus_trader.model.orders.base import Order

def on_order(self, order: Order) -> None:  # noqa (too complex)
    # Handle the order here
    # 在这里处理订单

When the algorithm is ready to spawn a secondary order, it can use one of the following methods:

当算法准备生成辅助订单时,可以使用以下方法之一:

  • spawn_market(...) (spawns a MARKET order) 生成市价订单
  • spawn_market_to_limit(...) (spawns a MARKET_TO_LIMIT order) 生成市价转限价订单
  • spawn_limit(...) (spawns a LIMIT order) 生成限价订单

note 注意

Additional order types will be implemented in future versions, as the need arises.

未来版本将根据需要实现其他订单类型。

Each of these methods takes the primary (original) Order as the first argument. The primary order quantity will be reduced by the quantity passed in (becoming the spawned orders quantity).

这些方法中的每一个都将主(原始)Order 作为第一个参数。主订单数量将减少传入的数量(成为生成的订单数量)。

warning 警告

There must be enough primary order quantity remaining (this is validated).

必须有足够的主订单数量剩余(这已经过验证)。

Once the desired number of secondary orders have been spawned, and the execution routine is over, the intention is that the algorithm will then finally send the primary (original) order.

一旦生成了所需数量的辅助订单,并且执行例程结束,那么算法的意图就是最终发送主(原始)订单。

Spawned orders 生成的订单

All secondary orders spawned from an execution algorithm will carry a exec_spawn_id which is simply the ClientOrderId of the primary (original) order, and whose client_order_id derives from this original identifier with the following convention:

从执行算法生成的所有辅助订单都将携带一个 exec_spawn_id,它只是主(原始)订单的 ClientOrderId,其 client_order_id 衍生自此原始标识符,并遵循以下约定:

  • exec_spawn_id (primary order client_order_id value) exec_spawn_id(主订单 client_order_id 值)
  • spawn_sequence (the sequence number for the spawned order) spawn_sequence(生成的订单的序列号)
  • {exec_spawn_id}-E{spawn_sequence}

e.g. O-20230404-001-000-E1 (for the first spawned order)

例如:O-20230404-001-000-E1(对于第一个生成的订单)

note 注意

The "primary" and "secondary" / "spawn" terminology was specifically chosen to avoid conflict or confusion with the "parent" and "child" contingent orders terminology (an execution algorithm may also deal with contingent orders).

特意选择了“主”和“辅助”/“生成”术语,以避免与“父”和“子”附带订单术语冲突或混淆(执行算法也可能处理附带订单)。

Managing execution algorithm orders 管理执行算法订单

The Cache provides several methods to aid in managing (keeping track of) the activity of an execution algorithm. Calling the below method will return all execution algorithm orders for the given query filters.

Cache 提供了几种方法来帮助管理(跟踪)执行算法的活动。调用以下方法将返回给定查询过滤器的所有执行算法订单。

def orders_for_exec_algorithm(
    self,
    exec_algorithm_id: ExecAlgorithmId,
    venue: Venue | None = None,
    instrument_id: InstrumentId | None = None,
    strategy_id: StrategyId | None = None,
    side: OrderSide = OrderSide.NO_ORDER_SIDE,
) -> list[Order]:
    ...

As well as more specifically querying the orders for a certain execution series/spawn. Calling the below method will return all orders for the given exec_spawn_id (if found).

以及更具体地查询某个执行系列/生成的订单。调用以下方法将返回给定 exec_spawn_id 的所有订单(如果找到)。

def orders_for_exec_spawn(self, exec_spawn_id: ClientOrderId) -> list[Order]:
    ...

note 注意

This also includes the primary (original) order.

这也包括主(原始)订单。

Execution reconciliation 执行对账

Execution reconciliation is the process of aligning the external state of reality for orders and positions (both closed and open) with the current system internal state built from events. This process is primarily applicable to live trading, which is why only the LiveExecutionEngine has reconciliation capability.

执行对账是将订单和头寸(已平仓和未平仓)的外部实际状态与从事件构建的当前系统内部状态进行匹配的过程。此过程主要适用于实时交易,这就是为什么只有 LiveExecutionEngine 具有对账功能的原因。

There are two main scenarios for reconciliation:

对账有两种主要情况:

  • Previous Cached Execution State: Where cached execution state exists, information from reports is used to generate missing events to align the state. 以前的缓存执行状态:如果存在缓存的执行状态,则使用来自报告的信息生成缺失的事件以对齐状态。
  • No Previous Cached Execution State: Where there is no cached state, all orders and positions that exist externally are generated from scratch. 没有以前的缓存执行状态:如果没有缓存状态,则从头开始生成所有外部存在的订单和头寸。

Reconciliation configuration 对账配置

Unless reconciliation is disabled by setting the reconciliation configuration parameter to false, the execution engine will perform the execution reconciliation procedure for each venue. Additionally, you can specify the lookback window for reconciliation by setting the reconciliation_lookback_mins configuration parameter.

除非通过将 reconciliation 配置参数设置为 false 来禁用对账,否则执行引擎将为每个交易平台执行执行对账过程。此外,您可以通过设置 reconciliation_lookback_mins 配置参数来指定对账的回溯窗口。

tip 提示

It's recommended not to set a specific reconciliation_lookback_mins. This allows the requests made to the venues to utilize the maximum execution history available for reconciliation.

建议不要设置特定的 reconciliation_lookback_mins。这允许向交易平台发出的请求利用可用于对账的最大执行历史记录。

warning 警告

If executions have occurred prior to the lookback window, any necessary events will be generated to align internal and external states. This may result in some information loss that could have been avoided with a longer lookback window.

如果在回溯窗口之前发生了执行,则将生成任何必要的事件以对齐内部和外部状态。这可能会导致一些信息丢失,而这些信息可以通过更长的回溯窗口避免。

Additionally, some venues may filter or drop execution information under certain conditions, resulting in further information loss. This would not occur if all events were persisted in the cache database.

此外,某些交易平台可能会在某些条件下过滤或删除执行信息,从而导致进一步的信息丢失。如果所有事件都持久化在缓存数据库中,则不会发生这种情况。

Each strategy can also be configured to claim any external orders for an instrument ID generated during reconciliation using the external_order_claims configuration parameter. This is useful in situations where, at system start, there is no cached state or it is desirable for a strategy to resume its operations and continue managing existing open orders at the venue for an instrument.

还可以将每个策略配置为使用 external_order_claims 配置参数声明对账期间生成的Instrument ID 的任何外部订单。这在系统启动时没有缓存状态或希望策略恢复其操作并继续管理交易平台中Instrument的现有未平仓订单的情况下非常有用。

info 信息

See the LiveExecEngineConfig API Reference for further details.

有关更多详细信息,请参阅 LiveExecEngineConfig API 参考。

Reconciliation procedure 对账程序

The reconciliation procedure is standardized for all adapter execution clients and uses the following methods to produce an execution mass status:

对账程序对所有适配器执行客户端都是标准化的,并使用以下方法生成执行批量状态:

  • generate_order_status_reports 生成订单状态报告
  • generate_fill_reports 生成成交报告
  • generate_position_status_reports 生成头寸状态报告

The system state is then reconciled with the reports, which represent the external reality:

然后将系统状态与报告进行对账,这些报告代表外部实际情况:

  • Duplicate Check: 重复检查:
    • Check for duplicate order IDs and trade IDs 检查重复的订单 ID 和交易 ID
  • Order Reconciliation: 订单对账:
    • Generate and apply events necessary to update orders from any cached state to the current state 生成并应用将订单从任何缓存状态更新到当前状态所需的事件
    • If any trade reports are missing, inferred OrderFilled events are generated 如果缺少任何交易报告,则生成推断的 OrderFilled 事件
    • If any client order ID is not recognized or an order report lacks a client order ID, external order events are generated 如果任何客户端订单 ID 未被识别或订单报告缺少客户端订单 ID,则生成外部订单事件
  • Position Reconciliation: 头寸对账:
    • Ensure the net position per instrument matches the position reports returned from the venue 确保每个Instrument的净头寸与从交易平台返回的头寸报告匹配
    • If the position state resulting from order reconciliation does not match the external state, external order events will be generated to resolve discrepancies 如果订单对账产生的头寸状态与外部状态不匹配,将生成外部订单事件以解决差异
  • If reconciliation fails, the system will not continue to start, and an error will be logged. 如果对账失败,系统将不会继续启动,并且会记录错误。

tip 提示

The current reconciliation procedure can experience state mismatches if the lookback window is misconfigured or if the venue omits certain order or trade reports due to filter conditions.

如果回溯窗口配置错误,或者交易平台由于过滤条件而省略了某些订单或交易报告,则当前的对账过程可能会遇到状态不匹配。

If you encounter reconciliation issues, drop any cached state or ensure the account is flat at system shutdown and startup.

如果您遇到对账问题,请删除任何缓存状态,或确保在系统关闭和启动时账户为平仓状态。

文档 (Documentation)
入门 (Getting Started)
概念 (Concepts)
教程 (Tutorials)
集成 (Integrations)
Python API
Rust API[未翻译]
开发者指南 (Developer Guide)
Clone this wiki locally