Phase 2: Core Components

Module 08: Execution Engine — The Lifecycle of an OrderFrom initial submission to final execution report

1. Role of the Execution Engine

The ExecutionEngine is the order-management control layer. It does not communicate directly with external exchanges; instead, it routes commands via the ExecutionClient adapter layer.

flowchart LR
                        subgraph input["📝 Command Input"]
                        direction TB
                        submit["SubmitOrder"]
                        cancel["CancelOrder"]
                        modify["ModifyOrder"]
                        end

                        ee["⚙️ ExecutionEngine<br/>Central Command Hub"]

                        subgraph output["⚡ Event Output"]
                        direction TB
                        accepted["OrderAccepted"]
                        filled["OrderFilled"]
                        rejected["OrderRejected"]
                        end

                        subgraph adapt["🔌 Adapters & Exchanges"]
                        direction TB
                        binance["Binance Client"]
                        ib["IB Client"]
                        sim["Simulator"]
                        end

                        input ==> ee
                        ee ==> adapt
                        adapt ==> ee
                        ee ==> output

                        style ee fill:#0f1419,stroke:#4fc3f7,stroke-width:2px
                        style input fill:#0f1419,stroke:#ab47bc,stroke-width:1px
                        style output fill:#0f1419,stroke:#ef5350,stroke-width:1px
Figure 1: The Execution Engine receives commands, routes them to exchanges, and reports events

2. The Full Order Lifecycle

sequenceDiagram
                        participant S as 🎯 Strategy
                        participant RE as 🛡️ RiskEngine
                        participant EE as ⚙️ ExecutionEngine
                        participant EC as 🔌 ExecutionClient
                        participant EX as 🏦 Exchange
                        participant Cache as 💾 Cache
                        participant Port as 💰 Portfolio

                        S->>RE: SubmitOrder(Market BUY 1 BTC)
                        Note over RE: Risk Check Passed ✅
                        RE->>EE: Forward Command
                        EE->>EE: Emit OrderSubmitted Event
                        EE->>Cache: Update State → SUBMITTED
                        EE->>EC: Route to Binance Adapter
                        EC->>EX: REST API Order Placement

                        EX-->>EC: Order Acceptance Confirmation
                        EC->>EE: OrderAccepted Event
                        EE->>Cache: Update State → ACCEPTED

                        EX-->>EC: Execution Report
                        EC->>EE: OrderFilled Event
                        EE->>Cache: Update State → FILLED
                        EE->>Port: Update Position & PnL
                        EE->>S: Broadcast Fill Notification (via MessageBus)
Figure 2: The end-to-end flow of an order from strategy to exchange and back

3. Order Command API

The following are the most frequently used order operations within a strategy:

# Market Order — Immediate Execution
order = self.order_factory.market(
    instrument_id=btc_usdt_id,
    order_side=OrderSide.BUY,
    quantity=Quantity.from_str("0.01"),
)
self.submit_order(order)

# Limit Order — Resting Liquidity
order = self.order_factory.limit(
    instrument_id=btc_usdt_id,
    order_side=OrderSide.BUY,
    quantity=Quantity.from_str("0.01"),
    price=Price.from_str("48000.00"),
    time_in_force=TimeInForce.GTC,
)
self.submit_order(order)

# Stop Market Order — Loss Mitigation
order = self.order_factory.stop_market(
    instrument_id=btc_usdt_id,
    order_side=OrderSide.SELL,
    quantity=Quantity.from_str("0.01"),
    trigger_price=Price.from_str("45000.00"),
)
self.submit_order(order)

# Cancel Order
self.cancel_order(order)

# Modify Order (Price or Quantity Update)
self.modify_order(order, price=Price.from_str("47500.00"))

# Cancel All Orders
self.cancel_all_orders(instrument_id=btc_usdt_id)

4. Contingency Orders

NautilusTrader supports three types of order contingency strategies:

🔗

OTO — One Triggers Other

When Order A executes, Order B is automatically triggered.
Example: Automatically placing a stop-loss after a long entry.

⚖️

OCO — One Cancels Other

If either Order A or B is executed, the other is automatically canceled.
Example: Stop-loss and take-profit brackets triggering mutually exclusive execution.

🎯

OUO — One Updates Other

When Order A partially executes, the quantity of Order B is automatically updated.
Example: Dynamically matching stop-loss quantity with the open position size.

5. Simulated Exchange

In backtesting and sandbox environments, the ExecutionClient interfaces with a SimulatedExchange rather than a live venue:

FeatureSimulated ExchangeLive Exchange
Matching EngineBuilt-in matching logicExchange’s matching engine
Latency SimulationConfigurable fixed latencyLive network latency
CommissionsCalculated via configuration modelsActually charged by the exchange
SlippageConfigurable slippage modelsLive market slippage (adverse selection)
Partial FillsSimulated based on order book depthLive market depth queue execution

6. Interactive Exercise

🧠 Exercise: Designing Contingency Orders

You want to buy BTC at 50,000, while simultaneously setting a stop-loss at 48,000 and a take-profit at 55,000 (where the execution of one cancels the other). Which order types and contingency structures should you use?

Steps:

  1. Place a Limit BUY Order @ 50,000 (Master Order).
  2. Configure an OTO condition: The execution of the Master Order triggers the following two child orders.
  3. Child Order A: Stop Market SELL @ 48,000 (StopMarketOrder).
  4. Child Order B: Limit SELL @ 55,000 (LimitOrder).
  5. Configure an OCO link between Child Orders A and B: The execution of either will automatically cancel the other.

💡 This represents the classic “entry + stop-loss + take-profit” trio, commonly referred to as a Bracket Order.

7. Module Key Takeaways

📋 Key Points
  1. Execution Engine: Manages the entire lifecycle of all orders without interfacing directly with exchanges.
  2. Commands → Routing → Events: Strategies submit commands, the engine routes them to adapters, and adapters report execution events.
  3. Contingency Orders: Supports OTO (trigger), OCO (cancel), and OUO (update) mechanisms for advanced logic.
  4. Simulated Exchange: Fully emulates live exchange matching dynamics during backtesting.
  5. Order Factory: Orders must be constructed exclusively using self.order_factory.