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.

Backtesting System

Relevant Rust source files

  • crates/backtest/src/engine.rs
  • crates/backtest/src/node.rs
  • crates/backtest/src/config.rs
  • crates/backtest/src/exchange.rs

The Backtesting System enables you to test trading strategies against historical market data in a realistic simulation environment. The system processes historical data as discrete events in chronological order, simulating venue behavior with configurable models for order matching, execution latency, and trading fees.

Purpose and Scope

This page provides an overview of NautilusTrader's backtesting infrastructure, showing how the main components work together and how to run backtests. The system is designed with architecture parity between backtesting and live trading—the same strategy code runs unchanged in both environments.

Detailed documentation:

System Architecture

The backtesting system reuses the same core engines as live trading but replaces real-time data sources and venues with simulation components. This ensures strategies tested in backtesting behave identically when deployed live.

System Architecture Diagram

Backtest and live environments surrounding one shared Nautilus model, message bus, data, risk, execution, cache, portfolio and strategy core.

Shared vs Simulation-Specific Components

Component Purpose Shared with Live Trading
DataEngine Routes market data to subscribers ✅ Yes
ExecutionEngine Manages order lifecycle ✅ Yes
Portfolio Position and PnL tracking ✅ Yes
Cache In-memory data store ✅ Yes
MessageBus Event distribution ✅ Yes
BacktestEngine Orchestrates simulation ❌ Backtest only
TestClock Deterministic time ❌ Backtest only
OrderMatchingEngine Order matching ❌ Backtest only
SimulatedExchange Venue simulation ❌ Backtest only

Two API Levels

NautilusTrader provides two ways to run backtests, each suited for different use cases.

Low-Level API: BacktestEngine

The Rust BacktestEngine gives direct control over the simulation. Callers add venues, instruments, data, and strategies, then run the deterministic event loop. Batch loading and ordering behavior must follow the Rust engine API at the pinned revision.

When to use:

  • Your data fits in memory
  • You want fine-grained control over setup
  • You require high-performance Rust-native backtesting via the low-level API

High-Level API: BacktestNode

The BacktestNode orchestrates the management of multiple BacktestEngine instances It uses configuration objects (BacktestRunConfig) to define backtests handling data loading from the ParquetDataCatalog and managing the lifecycle of strategies and actors.

When to use:

  • Data exceeds available memory (streaming required)
  • You want to run multiple backtest configurations simultaneously
  • You need integrated performance reporting and tearsheets.

Core Components

BacktestEngine Core

The BacktestEngine orchestrates the simulation by managing time progression and data iteration. It utilizes a TimeEventAccumulator to handle scheduled events and a TestClock for deterministic time. It advances simulation state via _advance_time and processes venues through _process_and_settle_venues

For details, see BacktestEngine Core.

Simulated Exchange and Order Matching

Each venue is represented by a SimulatedExchange It maintains a collection of OrderMatchingEngine instances which use an OrderMatchingCore for order logic. This subsystem handles queue position tracking and liquidity consumption

For details, see Simulated Exchange and Order Matching.

Venue Configuration and Models

Simulation fidelity is controlled via configuration. SimulatedExchange supports configurable FillModelAny FeeModelHandle and LatencyModel These models allow for realistic simulation of slippage, trading costs, and network delays.

For details, see Venue Configuration and Models.

Event Processing Flow

The backtest processes historical data as discrete events in chronological order, maintaining the same event flow as live trading.

Main Event Loop Sequence

For each next timestamp, BacktestEngine advances TestClock, dispatches due timers, processes the ordered market datum, settles affected simulated exchanges, and publishes resulting order events. Strategies therefore observe the same typed data, commands, and events as live operation while the environment supplies deterministic time and simulated venue behavior.

Deterministic Behavior Guarantees

NautilusTrader's backtesting system provides strong determinism guarantees through:

  • TestClock: Time only advances when the engine processes the next data point or timer event
  • Fixed-Point Arithmetic: Using PriceRaw, QuantityRaw, and FIXED_PRECISION to avoid floating-point non-determinism
  • Single-Threaded Loop: The core engine loop processes events sequentially to ensure a consistent execution order