NAUTILUS / RUST source 3eb18933
Pages

Rust edition: this page follows the live DeepWiki structure but treats the current Rust crates as implementation authority. Non-Rust surfaces are identified at their boundary and are not presented as Rust APIs.

ExecutionEngine Architecture

Relevant Rust source files

  • crates/execution/src/engine/mod.rs
  • crates/execution/src/engine/config.rs
  • crates/execution/src/client/core.rs
  • crates/common/src/messages/execution/mod.rs

Purpose and Scope

The ExecutionEngine is the central orchestrator of NautilusTrader's execution stack, responsible for managing all interactions between strategies, execution clients, and trading venues. This document covers the engine's architecture, responsibilities, message flows, and integration patterns across both the Rust implementations.

The engine manages the entire order lifecycle from submission to completion, handling routing to appropriate execution clients, position management, and event processing

For information about:


Core Responsibilities

The ExecutionEngine manages five primary areas of responsibility within the trading system:

Responsibility Description
Order Lifecycle Management Tracks orders from initialization through terminal states, applying events and maintaining state consistency.
Client Registration & Routing Registers ExecutionClient instances and routes commands to the appropriate client based on venue or default routing.
Position Management Opens, updates, and closes positions based on OrderFilled events, respecting OMS type (NETTING vs HEDGING).
Event Publishing Publishes order and position events to the MessageBus for consumption by strategies and other components.
State Persistence Optionally snapshots order and position state to the cache database at configured intervals.

The engine employs a fan-in fan-out messaging pattern where commands funnel in from multiple strategies and events fan out to relevant subscribers


Component Registration

ExecutionClient Registration

The engine maintains a registry of ExecutionClient instances that handle venue-specific communication. Clients can be registered with venue-specific routing or as a default fallback.

Entity Map: Client Registration

ExecutionEngine routing approved commands to Interactive Brokers and reconciling reports into cache and portfolio state.

Registration Logic:

  • register_client(client): Registers a client. If client.venue is None, it may be set as the default client; otherwise, it adds venue-specific routing
  • register_default_client(client): Explicitly sets a client as the default routing target
  • register_venue_routing(client, venue): Maps a specific venue to a client, overriding any existing mapping

Strategy Registration

Strategies register their OMS type and external order claims with the engine during initialization.

Execution state records strategy OMS overrides and external-order claims at registration so later commands and venue reports resolve to the correct ownership policy.

  • _oms_overrides: Maps strategy IDs to their configured OMS type (NETTING/HEDGING)
  • _external_order_claims: Maps instrument IDs to strategies that claim responsibility for external orders on those instruments

Message Flow Architecture

Command Execution Flow

Commands flow from strategies through the engine to execution clients. The engine handles TradingCommand types such as SubmitOrder, ModifyOrder, and CancelOrder.

Entity Map: Execution Path

Command Handling:

  • execute(command): The entry point for all trading commands from the MessageBus. In Rust, handlers are registered via register_msgbus_handlers
  • _handle_submit_order: Validates the order and forwards it to the resolved ExecutionClient

Event Processing Flow

Events from venues flow back through the engine to update internal state and notify subscribers.

Execution-client events enter ExecutionEngine, apply to the cached order state machine, update or create positions, refresh portfolio projections, and publish typed results.


Execution Reconciliation

Execution reconciliation aligns the venue's actual order and position state with the system's internal state built from events. This is performed by the LiveExecutionEngine at startup or on-demand

Reconciliation Procedure

All adapter execution clients follow the same reconciliation procedure, calling methods to produce an ExecutionMassStatus :

  1. generate_order_status_reports: Fetches current order states.
  2. generate_fill_reports: Fetches trade history within the lookback window.
  3. generate_position_status_reports: Fetches current account positions.

Position Management

OMS Type Determination

The engine determines the appropriate OMS type (NETTING or HEDGING) for each fill by checking strategy overrides, then the order itself, and finally falling back to venue defaults.

  • HEDGING: Each order fill can open a new position with a unique PositionId.
  • NETTING: All fills for an instrument aggregate into a single position with ID format {instrument_id}-{strategy_id}.

Position State Updates

Position updates involve checking if a position exists, if it's currently flat, or if the incoming fill will cause a "flip" (e.g., from Long to Short). The PositionIdGenerator is used to create unique IDs for new positions


Configuration

The Rust ExecutionEngine is configured through ExecutionEngineConfig.

Parameter Type Description
snapshot_orders bool If order state snapshots should be persisted.
snapshot_positions bool If position state snapshots should be persisted.
snapshot_positions_interval_secs float Interval for periodic position snapshots.
allow_overfills bool If order fills exceeding order quantity are allowed (logs warning).
manage_own_order_books bool If the engine should maintain its own order books.

Performance Considerations

Topic String Caching

To minimize overhead during high-frequency trading, the engine caches formatted topic strings for the MessageBus.

# Caches for topic strings (ExecutionEngine class)
self._topic_cache_order_events: dict[StrategyId, str] = {}
self._topic_cache_position_events: dict[StrategyId, str] = {}
self._topic_cache_fill_events: dict[InstrumentId, str] = {}

Snapshot Anchoring

The Rust implementation supports a SnapshotAnchorer callback to anchor cache snapshot metadata in an external store, facilitating durable state recovery