-
Notifications
You must be signed in to change notification settings - Fork 0
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 执行客户端或实时执行客户端
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
andExecAlgorithm(s)
components are optional in the flow, depending on individual order parameters (as explained below).
OrderEmulator
和ExecAlgorithm(s)
组件在流程中是可选的,具体取决于各个订单参数(如下所述)。
This diagram illustrates message flow (commands and events) across the Nautilus execution components.
此图说明了 Nautilus 执行组件之间的消息流(命令和事件)。
┌───────────────────┐
│ │
│ │
│ │
┌───────► OrderEmulator ├────────────┐
│ │ │ │
│ │ │ │
│ │ │ │
┌─────────┴──┐ └─────▲──────┬──────┘ │
│ │ │ │ ┌───────▼────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ │ │ │ │ │ │ │ │ │
│ ├──────────┼──────┼───────────► ├───► ├───► │
│ Strategy │ │ │ │ │ │ │ │ │
│ │ │ │ │ RiskEngine │ │ ExecutionEngine │ │ ExecutionClient │
│ ◄──────────┼──────┼───────────┤ ◄───┤ ◄───┤ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │
└─────────┬──┘ ┌─────┴──────▼──────┐ └───────▲────────┘ └─────────────────────┘ └─────────────────────┘
│ │ │ │
│ │ │ │
│ │ │ │
└───────► ExecAlgorithm ├────────────┘
│ │
│ │
│ │
└───────────────────┘
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 receivedOrderFilled
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 类型,跟踪多头和空头的多个头寸。交易者可能只关心每个货币对的净头寸。
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,以便净额结算单个头寸。
If a strategy OMS type is not explicitly set using the
oms_type
configuration option, it will default toUNSPECIFIED
. This means the ExecutionEngine will not override any venueposition_ids
, and the OMS type will follow the venue's OMS type.如果没有使用
oms_type
配置选项显式设置策略 OMS 类型,则默认值为UNSPECIFIED
。这意味着 ExecutionEngine 不会覆盖任何交易平台的position_ids
,并且 OMS 类型将遵循交易平台的 OMS 类型。
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 类型相匹配。
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
事件,有效地关闭订单并阻止其进一步进行。此事件包含拒绝的人类可读原因。
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. 减少:系统将只处理取消或减少未平仓头寸的命令。
See the RiskEngineConfig API Reference for further details.
有关更多详细信息,请参阅 RiskEngineConfig API 参考。
The platform supports customized execution algorithm components and provides some built-in algorithms, such as the Time-Weighted Average Price (TWAP) algorithm.
该平台支持自定义执行算法组件,并提供一些内置算法,例如时间加权平均价格 (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 aBacktestEngine
(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.
或者,您可以为每个订单动态指定这些参数,根据实际市场情况确定它们。在这种情况下,可以将策略配置参数提供给确定范围和间隔的执行模型。
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).
您可以创建的执行算法参数数量没有限制。参数只需要是一个字典,其中包含字符串键和原始值(可以通过网络序列化的值,例如整数、浮点数和字符串)。
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 theexec_algorithm_id
order parameter. The order may also carry theexec_algorithm_params
being adict[str, Any]
.一旦注册了执行算法,并且系统正在运行,它将通过消息总线接收订单,这些订单通过
exec_algorithm_id
订单参数寻址到其ExecAlgorithmId
。订单还可以携带exec_algorithm_params
,它是一个dict[str, Any]
。
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 notNone
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) 生成限价订单
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
作为第一个参数。主订单数量将减少传入的数量(成为生成的订单数量)。
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.
一旦生成了所需数量的辅助订单,并且执行例程结束,那么算法的意图就是最终发送主(原始)订单。
All secondary orders spawned from an execution algorithm will carry a
exec_spawn_id
which is simply theClientOrderId
of the primary (original) order, and whoseclient_order_id
derives from this original identifier with the following convention:从执行算法生成的所有辅助订单都将携带一个
exec_spawn_id
,它只是主(原始)订单的ClientOrderId
,其client_order_id
衍生自此原始标识符,并遵循以下约定:
exec_spawn_id
(primary orderclient_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
(对于第一个生成的订单)
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).
特意选择了“主”和“辅助”/“生成”术语,以避免与“父”和“子”附带订单术语冲突或混淆(执行算法也可能处理附带订单)。
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]:
...
This also includes the primary (original) order.
这也包括主(原始)订单。
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. 没有以前的缓存执行状态:如果没有缓存状态,则从头开始生成所有外部存在的订单和头寸。
Unless reconciliation is disabled by setting the
reconciliation
configuration parameter tofalse
, the execution engine will perform the execution reconciliation procedure for each venue. Additionally, you can specify the lookback window for reconciliation by setting thereconciliation_lookback_mins
configuration parameter.除非通过将
reconciliation
配置参数设置为false
来禁用对账,否则执行引擎将为每个交易平台执行执行对账过程。此外,您可以通过设置reconciliation_lookback_mins
配置参数来指定对账的回溯窗口。
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
。这允许向交易平台发出的请求利用可用于对账的最大执行历史记录。
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的现有未平仓订单的情况下非常有用。
See the LiveExecEngineConfig API Reference for further details.
有关更多详细信息,请参阅 LiveExecEngineConfig API 参考。
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. 如果对账失败,系统将不会继续启动,并且会记录错误。
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.
如果您遇到对账问题,请删除任何缓存状态,或确保在系统关闭和启动时账户为平仓状态。