跳到主要内容

实时交易

实时交易 in NautilusTrader enables traders to deploy their backtested 策略 in a 实时 trading 环境 with no code changes. This seamless transition from 回测 to 实时交易 is a core 功能 of the platform, ensuring consistency and 可靠性. However, there are key differences to be aware of between 回测 and 实时交易.

This 指南 provides an 概览 of the key aspects of 实时交易.

Platform differences

Windows signal handling differs from Unix-like systems. If you are running on Windows, please read the note on Windows signal handling for guidance on graceful shutdown behavior and Ctrl+C (SIGINT) 支持.

配置

When operating a 实时交易 system, configuring your 执行 engine and 策略 properly is essential for ensuring 可靠性, accuracy, and 性能. The following is an 概览 of the key 核心概念 and settings involved for live 配置.

TradingNodeConfig

The main 配置 class for 实时交易 systems is TradingNodeConfig, which inherits from NautilusKernelConfig and provides live-specific config options:

from nautilus_trader.config import TradingNodeConfig

config = TradingNodeConfig(
trader_id="MyTrader-001",

# Component configurations
cache: CacheConfig(),
message_bus: MessageBusConfig(),
data_engine=LiveDataEngineConfig(),
risk_engine=LiveRiskEngineConfig(),
exec_engine=LiveExecEngineConfig(),
portfolio=PortfolioConfig(),

# Client configurations
data_clients={
"BINANCE": BinanceDataClientConfig(),
},
exec_clients={
"BINANCE": BinanceExecClientConfig(),
},
)

Core 配置 parameters

SettingDefaultDescription
trader_id"TRADER-001"Unique trader identifier (name-tag format).
instance_idNoneOptional unique instance identifier.
timeout_connection30.0Connection timeout in seconds.
timeout_reconciliation10.0Reconciliation timeout in seconds.
timeout_portfolio10.0投资组合 initialization timeout.
timeout_disconnection10.0Disconnection timeout.
timeout_post_stop5.0Post-stop cleanup timeout.

缓存 数据库 配置

Configure 数据 持久化 with a backing 数据库:

from nautilus_trader.config import CacheConfig
from nautilus_trader.config import DatabaseConfig

cache_config = CacheConfig(
database=DatabaseConfig(
host="localhost",
port=6379,
username="nautilus",
password="pass",
timeout=2.0,
),
encoding="msgpack", # or "json"
timestamps_as_iso8601=True,
buffer_interval_ms=100,
flush_on_start=False,
)

MessageBus 配置

Configure message routing and external streaming:

from nautilus_trader.config import MessageBusConfig
from nautilus_trader.config import DatabaseConfig

message_bus_config = MessageBusConfig(
database=DatabaseConfig(timeout=2),
timestamps_as_iso8601=True,
use_instance_id=False,
types_filter=[QuoteTick, TradeTick], # Filter specific message types
stream_per_topic=False,
autotrim_mins=30, # Automatic message trimming
heartbeat_interval_secs=1,
)

Multi-venue 配置

实时交易 systems often connect to multiple venues. Here's an example of configuring both spot and futures markets for Binance:

config = TradingNodeConfig(
trader_id="MultiVenue-001",

# Multiple data clients for different market types
data_clients={
"BINANCE_SPOT": BinanceDataClientConfig(
account_type=BinanceAccountType.SPOT,
testnet=False,
),
"BINANCE_FUTURES": BinanceDataClientConfig(
account_type=BinanceAccountType.USDT_FUTURES,
testnet=False,
),
},

# Corresponding execution clients
exec_clients={
"BINANCE_SPOT": BinanceExecClientConfig(
account_type=BinanceAccountType.SPOT,
testnet=False,
),
"BINANCE_FUTURES": BinanceExecClientConfig(
account_type=BinanceAccountType.USDT_FUTURES,
testnet=False,
),
},
)

ExecutionEngine 配置

The LiveExecEngineConfig sets up the live 执行 engine, managing order processing, 执行 events, and reconciliation with trading venues. The following outlines the main 配置 options.

By configuring these parameters thoughtfully, you can ensure that your trading system operates efficiently, handles 订单 correctly, and remains resilient in the face of potential issues, such as lost events or conflicting 数据/information.

For full details see the LiveExecEngineConfig API Reference.

Reconciliation

Purpose: Ensures that the system state remains consistent with the trading venue by recovering any missed events, such as order and position status updates.

SettingDefaultDescription
reconciliationTrueActivates reconciliation at startup, aligning the system's internal state with the venue's state.
reconciliation_lookback_minsNoneSpecifies how far back (in minutes) the system requests past events to reconcile uncached state.
reconciliation_instrument_idsNoneAn include list of specific instrument IDs to consider for reconciliation.
filtered_client_order_idsNoneA list of 客户端 order IDs to filter from reconciliation (useful when the venue holds duplicates).

See Execution reconciliation for additional background.

Order filtering

Purpose: Manages which order events and reports should be processed by the system to avoid conflicts with other trading nodes and unnecessary data handling.

SettingDefaultDescription
filter_unclaimed_external_ordersFalseFilters out unclaimed external 订单 to prevent irrelevant 订单 from impacting the strategy.
filter_position_reportsFalseFilters out position status 报告, useful when multiple nodes trade the same account to avoid conflicts.

Continuous reconciliation

Purpose: Maintains accurate execution state through a continuous reconciliation loop that:

  • (1) Monitors in-flight 订单 for delays exceeding a configured threshold.
  • (2) Reconciles open 订单 with the venue at configurable intervals.
  • (3) Audits internal own order books against the venue's public books.

If an order's status cannot be reconciled after exhausting all retries, the engine resolves the order as follows:

In-flight order timeout resolution (when venue doesn't respond after max retries):

Current statusResolved toRationale
SUBMITTEDREJECTEDNo confirmation received from venue.
PENDING_UPDATECANCELEDModification remains unacknowledged.
PENDING_CANCELCANCELEDVenue never confirmed the cancellation.

Order consistency checks (when 缓存 state differs from venue state):

缓存 statusVenue statusResolutionRationale
ACCEPTEDNot foundREJECTEDOrder doesn't exist at venue, likely was never successfully placed.
ACCEPTEDCANCELEDCANCELEDVenue canceled the order (user action or venue-initiated).
ACCEPTEDEXPIREDEXPIREDOrder reached GTD expiration at venue.
ACCEPTEDREJECTEDREJECTEDVenue rejected after initial acceptance (rare but possible).
PARTIALLY_FILLEDCANCELEDCANCELEDOrder canceled at venue with fills preserved.
PARTIALLY_FILLEDNot foundCANCELEDOrder doesn't exist but had fills (reconciles fill history).
备注

Important reconciliation caveats:

  • "Not found" resolutions: These are only performed in full-history mode (open_check_open_only=False). In open-only mode (open_check_open_only=True, the default), these checks are intentionally skipped. This is because open-only mode uses venue-specific "open orders" endpoints which exclude closed orders by design, making it impossible to distinguish between genuinely missing orders and recently closed ones.
  • Recent order protection: The engine skips "missing" checks for orders with last event timestamp within the inflight_check_threshold_ms window (default 5 seconds). This prevents false positives from race conditions where orders may still be processing at the venue.
  • Targeted query safeguard: Before marking orders as REJECTED or CANCELED when "not found", the engine attempts a targeted single-order query to the venue. This helps prevent false negatives due to bulk query limitations or timing delays.
  • FILLED orders: When a FILLED order is "not found" at the venue, this is considered normal behavior (venues often don't track completed orders) and is ignored without generating warnings.

This ensures the trading 节点 maintains a consistent 执行 state even under unreliable conditions.

SettingDefaultDescription
inflight_check_interval_ms2,000 msDetermines how frequently the system checks in-flight order status. Set to 0 to disable.
inflight_check_threshold_ms5,000 msSets the time threshold after which an in-flight order triggers a venue status check. Adjust if colocated to avoid race conditions.
inflight_check_retries5 retriesSpecifies the number of retry attempts the engine will make to verify the status of an in-flight order with the venue, should the initial attempt fail.
open_check_interval_secsNoneDetermines how frequently (in seconds) open orders are checked at the venue. Set to None or 0.0 to disable. Recommended: 5-10 seconds, considering API rate limits.
open_check_open_onlyTrueWhen enabled, only open 订单 are requested during checks; if disabled, full order history is fetched (resource-intensive).
open_check_lookback_mins60 minLookback window (minutes) for order status polling during continuous reconciliation. Only 订单 modified within this window are considered.
open_check_missing_retries5 retriesMaximum retries before resolving an order that is open in 缓存 but not found at venue. Prevents false positives from race conditions.
reconciliation_startup_delay_secs10.0 sInitial delay (seconds) before starting continuous reconciliation loop. Provides time for system stabilization after startup.
own_books_audit_interval_secsNoneSets the interval (in seconds) between audits of own order books against public ones. Verifies synchronization and logs errors for inconsistencies.
注意

Important 配置 guidelines:

  • open_check_lookback_mins: Do not reduce below 60 minutes. This lookback window must be sufficiently generous for your venue's order history retention. Setting it too short can trigger false "missing order" resolutions even with built-in safeguards, as orders may appear missing when they're simply outside the query window.

  • reconciliation_startup_delay_secs: Do not reduce below 10 seconds for production systems. This delay allows the system to stabilize after startup, ensuring all connections are established and initial state is loaded before reconciliation begins. Reducing this too much can cause reconciliation to run against incomplete state.

Additional options

The following additional options provide further control over 执行 behavior:

SettingDefaultDescription
generate_missing_ordersTrueIf LIMIT order events will be generated during reconciliation to align position discrepancies. These 订单 use the strategy ID INTERNAL-DIFF and calculate precise prices to achieve target average 头寸.
snapshot_ordersFalseIf order snapshots should be taken on order events.
snapshot_positionsFalseIf position snapshots should be taken on position events.
snapshot_positions_interval_secsNoneThe interval (seconds) between position snapshots when enabled.
debugFalseEnable debug mode for additional 执行 日志记录.

内存 management

Purpose: Periodically purges closed orders, closed positions, and account events from the in-memory cache to optimize resource usage and performance during extended / HFT operations.

SettingDefaultDescription
purge_closed_orders_interval_minsNoneSets how frequently (in minutes) closed orders are purged from memory. Recommended: 10-15 minutes. Does not affect database records.
purge_closed_orders_buffer_minsNoneSpecifies how long (in minutes) an order must have been closed before purging. Recommended: 60 minutes to ensure processes complete.
purge_closed_positions_interval_minsNoneSets how frequently (in minutes) closed positions are purged from memory. Recommended: 10-15 minutes. Does not affect database records.
purge_closed_positions_buffer_minsNoneSpecifies how long (in minutes) a position must have been closed before purging. Recommended: 60 minutes to ensure processes complete.
purge_account_events_interval_minsNoneSets how frequently (in minutes) account events are purged from memory. Recommended: 10-15 minutes. Does not affect database records.
purge_account_events_lookback_minsNoneSpecifies how long (in minutes) an account event must have occurred before purging. Recommended: 60 minutes.
purge_from_databaseFalseIf enabled, purge operations will also delete 数据 from the backing 数据库 (Redis/PostgreSQL), not just 内存. Use with caution.

By configuring these 内存 management settings appropriately, you can prevent 内存 usage from growing indefinitely during long-running / HFT sessions while ensuring that recently closed 订单, closed 头寸, and account events remain available in 内存 for any ongoing operations that might require them.

Queue management

Purpose: Handles the internal buffering of order events to ensure smooth processing and to prevent system resource overloads.

SettingDefaultDescription
qsize100,000Sets the size of internal queue buffers, managing the flow of 数据 within the engine.
graceful_shutdown_on_exceptionFalseIf the system should perform a graceful shutdown when an unexpected 异常 occurs during message queue processing (does not include user actor/strategy exceptions).

Strategy 配置

The StrategyConfig class outlines the 配置 for trading 策略, ensuring that each strategy operates with the correct parameters and manages 订单 effectively. For a complete parameter list see the StrategyConfig API Reference.

Identification

Purpose: Provides unique identifiers for each strategy to prevent conflicts and ensure proper tracking of orders.

SettingDefaultDescription
strategy_idNoneA unique ID for the strategy, ensuring it can be distinctly identified.
order_id_tagNoneA unique tag for the strategy's 订单, differentiating them from multiple 策略.

订单管理

Purpose: Controls strategy-level order handling including position-ID processing, claiming relevant external orders, automating contingent order logic (OUO/OCO), and tracking GTD expirations.

SettingDefaultDescription
oms_typeNoneSpecifies the OMS type, for position ID handling and order processing flow.
use_uuid_client_order_idsFalseIf UUID4's should be used for 客户端 order ID values (required for some venues such as Coinbase Intx).
external_order_claimsNoneLists instrument IDs for external 订单 the strategy should claim, aiding accurate 订单管理.
manage_contingent_ordersFalseIf enabled, the strategy automatically manages contingent 订单, reducing 手册 intervention.
manage_gtd_expiryFalseIf enabled, the strategy manages GTD expirations, ensuring 订单 remain active as intended.

Windows signal handling

注意

Windows: asyncio event loops do not implement loop.add_signal_handler. As a result, the legacy TradingNode does not receive OS signals via asyncio on Windows. Use Ctrl+C (SIGINT) handling or programmatic shutdown; SIGTERM parity is not expected on Windows.

On Windows, asyncio event loops do not implement loop.add_signal_handler, so Unix-style signal integration is unavailable. As a result, TradingNode does not receive OS signals via asyncio on Windows and will not gracefully stop unless you intervene.

Recommended approaches on Windows:

  • Wrap run with a try/except KeyboardInterrupt and call 节点.stop() then 节点.dispose(). Ctrl+C on Windows raises KeyboardInterrupt in the main thread, providing a clean teardown path.
  • Alternatively, publish a ShutdownSystem command programmatically (or call shutdown_system(...) from an actor/组件) to trigger the same shutdown path.

The “inflight check loop task still pending” message is consistent with the lack of asyncio signal handling on Windows, i.e., the normal graceful shutdown path isn’t being triggered.

This is tracked as an 增强 request to 支持 Ctrl+C (SIGINT) for Windows in the legacy path. https://github.com/nautechsystems/nautilus_trader/issues/2785.

For the new v2 system, LiveNode already supports Ctrl+C cleanly via tokio::signal::ctrl_c() and a Python SIGINT bridge, so the runner stops and tasks are shut down cleanly.

Example pattern for Windows:

try:
node.run()
except KeyboardInterrupt:
pass
finally:
try:
node.stop()
finally:
node.dispose()

执行 reconciliation

执行 reconciliation is the process of aligning the external state of reality for 订单 and 头寸 (both closed and open) with the systems internal state built from events. This process is primarily applicable to 实时交易, which is why only the LiveExecutionEngine has reconciliation capability.

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.
提示

Best practice: Persist all execution events to the cache database to minimize reliance on venue history, ensuring full recovery even with short lookback windows.

Reconciliation 配置

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

提示

We recommend not setting a specific reconciliation_lookback_mins. This allows the requests made to the venues to utilize the maximum 执行 history available for reconciliation.

注意

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 执行 information under certain conditions, resulting in further information loss. This would not occur if all events were persisted in the 缓存 数据库.

Each strategy can also be configured to claim any external 订单 for an instrument ID generated during reconciliation using the external_order_claims 配置 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 订单 for a specific instrument.

订单 generated with strategy ID INTERNAL-DIFF during position reconciliation are internal to the engine and cannot be claimed via external_order_claims. They exist solely to align position discrepancies and should not be managed by user 策略.

For a full list of live trading options see the LiveExecEngineConfig API Reference.

Reconciliation procedure

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

  • generate_order_status_reports
  • generate_fill_reports
  • generate_position_status_reports

The system state is then reconciled with the 报告, which represent external "reality":

  • Duplicate Check:
    • Check for duplicate 客户端 order IDs and trade IDs.
    • Duplicate 客户端 order IDs cause reconciliation failure to prevent state corruption.
  • Order Reconciliation:
    • Generate and apply events necessary to 更新 订单 from any cached state to the current state.
    • If any trade 报告 are missing, inferred OrderFilled events are generated.
    • If any 客户端 order ID is not recognized or an order report lacks a 客户端 order ID, external order events are generated.
    • Fill report 数据 consistency is verified using tolerance-based comparisons for price and commission differences.
  • Position Reconciliation:
    • Ensure the net position per instrument matches the position 报告 returned from the venue using instrument precision handling.
    • If the position state resulting from order reconciliation does not match the external state, external order events will be generated to resolve discrepancies.
    • When generate_missing_orders is enabled (default: True), orders are generated with strategy ID INTERNAL-DIFF to align position discrepancies discovered during reconciliation.
    • A hierarchical price determination strategy ensures reconciliation can proceed even with limited 数据:
      1. Calculated reconciliation price (preferred): Uses the reconciliation price function to achieve target average positions
      2. Market mid-price: Falls back to current bid-ask midpoint if reconciliation price cannot be calculated
      3. Current position average: Uses existing position average price if no market data is available
      4. MARKET order (last resort): When no price information exists (no positions, no market data), a MARKET order is generated
    • LIMIT 订单 are used when a price can be determined (cases 1-3), ensuring accurate PnL calculations
    • MARKET 订单 are only used as a last resort when starting fresh with no available pricing 数据
    • Zero quantity differences after precision rounding are handled gracefully.
  • 异常 Handling:
    • Individual adapter failures do not abort the entire reconciliation process.
    • Missing order status 报告 are handled gracefully when fill 报告 arrive first.

If reconciliation fails, the system will not continue to start, and an error will be logged.

Common reconciliation scenarios

The scenarios below are split between startup reconciliation (mass status) and runtime/continuous checks (in-flight order checks, open-order polls, and own-books audits).

Startup reconciliation

ScenarioDescriptionSystem behavior
Order state discrepancyLocal order state differs from venue (e.g., local shows SUBMITTED, venue shows REJECTED).Updates local order to match venue state and emits missing events.
Missed fillsVenue fills an order but the engine misses the fill event.Generates missing OrderFilled events.
Multiple fillsOrder has multiple partial fills, some missed by the engine.Reconstructs complete fill history from venue 报告.
External 订单订单 exist on venue but not in local 缓存 (placed externally or from another system).Creates 订单 from venue 报告; tags them EXTERNAL.
Partially filled then canceledOrder partially filled then canceled by venue.Updates order state to CANCELED while preserving fill history.
Different fill 数据Venue 报告 different fill price/commission than cached.Preserves cached fill 数据; logs discrepancies from 报告.
Filtered 订单订单 marked for filtering via 配置.Skips reconciliation based on filtered_client_order_ids or instrument filters.
Duplicate 客户端 order IDsMultiple 订单 with same 客户端 order ID in venue 报告.Reconciliation fails to prevent state corruption.
Position quantity mismatch (long)Internal long position differs from external (e.g., internal: 100, external: 150).Generates BUY LIMIT order with calculated price when generate_missing_orders=True.
Position quantity mismatch (short)Internal short position differs from external (e.g., internal: -100, external: -150).Generates SELL LIMIT order with calculated price when generate_missing_orders=True.
Position reductionExternal position smaller than internal (e.g., internal: 150 long, external: 100 long).Generates opposite side LIMIT order with calculated price to reduce position.
Position side flipInternal position opposite of external (e.g., internal: 100 long, external: 50 short).Generates LIMIT order with calculated price to close internal and open external position.
INTERNAL-DIFF 订单Position reconciliation 订单 with strategy ID "INTERNAL-DIFF".Never filtered, regardless of filter_unclaimed_external_orders.

Runtime/continuous checks

ScenarioDescriptionSystem behavior
In-flight order timeoutIn-flight order remains unconfirmed beyond threshold.After inflight_check_retries, resolves to REJECTED to maintain consistent state.
Open 订单 check discrepancyPeriodic open-订单 poll detects a state change at the venue.At open_check_interval_secs, confirms status (respecting open_check_open_only) and applies transitions if changed.
Own books audit mismatchOwn order books diverge from venue public books.At own_books_audit_interval_secs, audits and logs inconsistencies for investigation.

Common reconciliation issues

  • Missing trade reports: Some venues filter out older trades, causing incomplete reconciliation. Increase reconciliation_lookback_mins or ensure all events are cached locally.
  • Position mismatches: If external orders predate the lookback window, positions may not align. Flatten the account before restarting the system to reset state.
  • Duplicate order IDs: Duplicate client order IDs in mass status reports will cause reconciliation failure. Ensure venue data integrity or contact support.
  • Precision differences: Small decimal differences in position quantities are handled automatically using instrument precision, but large discrepancies may indicate missing orders.
  • Out-of-order reports: Fill reports arriving before order status reports are deferred until order state is available.
提示

For persistent reconciliation issues, consider dropping cached state or flattening accounts before system restart.