Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Nautechsystems Nautilus trader BacktestNode Run

From Leeroopedia


Field Value
sources https://github.com/nautechsystems/nautilus_trader, https://nautilustrader.io/docs/
domains backtesting, orchestration, configuration-management, scenario-management
last_updated 2026-02-10 12:00 GMT

Overview

Concrete tool for configuration-driven multi-scenario backtest orchestration provided by NautilusTrader.

Description

BacktestNode is the top-level orchestrator class that accepts a list of BacktestRunConfig objects and manages the full lifecycle of backtest execution: validation, engine construction, data loading, simulation, and result collection.

The class coordinates three supporting configuration types:

  • BacktestRunConfig -- the top-level run specification combining venues, data, engine config, and run options.
  • BacktestEngineConfig -- the kernel-level settings including trader ID, sub-engine configurations, and lists of importable strategy/actor/exec-algorithm configurations.
  • BacktestVenueConfig and BacktestDataConfig -- venue and data specifications consumed during the build phase.

BacktestNode supports two data loading modes:

  • One-shot mode (chunk_size=None) -- All data is loaded into memory, sorted, and the engine runs a single pass. Fastest for datasets that fit in memory.
  • Streaming mode (chunk_size=N) -- Data is loaded in chunks of N records from a DataBackendSession. After each chunk, the engine runs incrementally and clears data, enabling backtests on datasets larger than available memory.

The run() method returns a list of BacktestResult objects, one per configuration. Individual run failures can be isolated (logged but not raised) or propagated, controlled by the raise_exception flag on each BacktestRunConfig.

After running, engines remain accessible via get_engines() (unless disposed), enabling post-run inspection of cache state, portfolios, and order history.

Usage

Import and use BacktestNode whenever you need to:

  • Execute one or more backtests from declarative configuration objects.
  • Run parameter sweeps or strategy comparisons without writing boilerplate engine setup code.
  • Process large datasets in streaming mode.
  • Collect backtest results for analysis in a research pipeline.
  • Inspect engine state after backtest completion.

Code Reference

Source Location

  • BacktestNode: nautilus_trader/backtest/node.py, lines 94-652.
  • BacktestRunConfig: nautilus_trader/backtest/config.py, lines 378-427.
  • BacktestEngineConfig: nautilus_trader/backtest/config.py, lines 324-376.

Signature

BacktestNode:

class BacktestNode:
    def __init__(self, configs: list[BacktestRunConfig]) -> None: ...

    @property
    def configs(self) -> list[BacktestRunConfig]: ...

    def get_engine(self, run_config_id: str) -> BacktestEngine | None: ...
    def get_engines(self) -> list[BacktestEngine]: ...
    def get_log_guard(self) -> nautilus_pyo3.LogGuard | LogGuard | None: ...

    def add_data_client_factory(self, name: str, factory: type[LiveDataClientFactory]) -> None: ...
    def build(self) -> None: ...
    def run(self) -> list[BacktestResult]: ...
    def dispose(self) -> None: ...

BacktestRunConfig:

class BacktestRunConfig(NautilusConfig, frozen=True):
    venues: list[BacktestVenueConfig]
    data: list[BacktestDataConfig]
    engine: BacktestEngineConfig | None = None
    chunk_size: int | None = None
    raise_exception: bool = False
    dispose_on_completion: bool = True
    start: str | int | None = None
    end: str | int | None = None
    data_clients: dict[str, type[LiveDataClientConfig]] | None = None

BacktestEngineConfig:

class BacktestEngineConfig(NautilusKernelConfig, frozen=True):
    environment: Environment = Environment.BACKTEST
    trader_id: TraderId = "BACKTESTER-001"
    cache: CacheConfig | None = CacheConfig(drop_instruments_on_reset=False)
    data_engine: DataEngineConfig | None = DataEngineConfig()
    risk_engine: RiskEngineConfig | None = RiskEngineConfig()
    exec_engine: ExecEngineConfig | None = ExecEngineConfig()
    run_analysis: bool = True

Import

from nautilus_trader.backtest.node import BacktestNode
from nautilus_trader.backtest.config import BacktestRunConfig
from nautilus_trader.backtest.config import BacktestEngineConfig
from nautilus_trader.backtest.config import BacktestVenueConfig
from nautilus_trader.backtest.config import BacktestDataConfig
from nautilus_trader.backtest.results import BacktestResult

I/O Contract

Inputs (BacktestNode.__init__)

Parameter Type Required Default Description
configs list[BacktestRunConfig] Yes -- One or more backtest run configurations to execute

Inputs (BacktestRunConfig)

Parameter Type Required Default Description
venues list[BacktestVenueConfig] Yes -- Venue configurations for the backtest run
data list[BacktestDataConfig] Yes -- Data configurations for the backtest run
engine None No None Engine configuration (uses defaults if None)
chunk_size None No None Streaming chunk size; None for one-shot mode
raise_exception bool No False Propagate exceptions instead of logging them
dispose_on_completion bool No True Dispose the engine after run (drops data and state)
start int | None No None Run start time (ISO 8601 or UNIX nanos); None for data start
end int | None No None Run end time (ISO 8601 or UNIX nanos); None for data end
data_clients None No None Optional external data client configurations

Inputs (BacktestEngineConfig)

Parameter Type Required Default Description
trader_id TraderId No "BACKTESTER-001" Trader ID (name-tag format)
cache None No CacheConfig(drop_instruments_on_reset=False) Cache configuration
data_engine None No DataEngineConfig() Data engine configuration
risk_engine None No RiskEngineConfig() Risk engine configuration
exec_engine None No ExecEngineConfig() Execution engine configuration
run_analysis bool No True Run post-backtest performance analysis
strategies list[ImportableStrategyConfig] No [] Strategy configurations (inherited from NautilusKernelConfig)
actors list[ImportableActorConfig] No [] Actor configurations (inherited from NautilusKernelConfig)

Outputs

Output Type Description
node.run() list[BacktestResult] List of backtest results, one per successfully executed run configuration
node.get_engines() list[BacktestEngine] All backtest engines created by the node (available if not disposed)
node.get_engine(id) None Engine for a specific run config ID
node.configs list[BacktestRunConfig] The loaded run configurations

Usage Examples

Minimal single-run backtest:

from nautilus_trader.backtest.node import BacktestNode
from nautilus_trader.backtest.config import (
    BacktestDataConfig,
    BacktestEngineConfig,
    BacktestRunConfig,
    BacktestVenueConfig,
)
from nautilus_trader.trading.config import ImportableStrategyConfig

venue = BacktestVenueConfig(
    name="SIM",
    oms_type="HEDGING",
    account_type="CASH",
    starting_balances=["1_000_000 USD"],
    base_currency="USD",
)

data = BacktestDataConfig(
    catalog_path="/data/catalog",
    data_cls="nautilus_trader.model.data:QuoteTick",
    instrument_id="EUR/USD.SIM",
    start_time="2024-01-01",
    end_time="2024-06-30",
)

strategy = ImportableStrategyConfig(
    strategy_path="nautilus_trader.examples.strategies.ema_cross:EMACross",
    config_path="nautilus_trader.examples.strategies.ema_cross:EMACrossConfig",
    config={
        "instrument_id": "EUR/USD.SIM",
        "bar_type": "EUR/USD.SIM-1-MINUTE-BID-INTERNAL",
        "fast_ema_period": 10,
        "slow_ema_period": 20,
        "trade_size": "1_000_000",
    },
)

engine_config = BacktestEngineConfig(strategies=[strategy])

run_config = BacktestRunConfig(
    venues=[venue],
    data=[data],
    engine=engine_config,
)

node = BacktestNode(configs=[run_config])
results = node.run()

Multi-scenario parameter sweep:

from nautilus_trader.backtest.node import BacktestNode
from nautilus_trader.backtest.config import (
    BacktestDataConfig,
    BacktestEngineConfig,
    BacktestRunConfig,
    BacktestVenueConfig,
)
from nautilus_trader.trading.config import ImportableStrategyConfig

venue = BacktestVenueConfig(
    name="SIM",
    oms_type="HEDGING",
    account_type="CASH",
    starting_balances=["1_000_000 USD"],
)

data = BacktestDataConfig(
    catalog_path="/data/catalog",
    data_cls="nautilus_trader.model.data:QuoteTick",
    instrument_id="EUR/USD.SIM",
)

configs = []
for fast, slow in [(5, 15), (10, 20), (15, 30), (20, 40)]:
    strategy = ImportableStrategyConfig(
        strategy_path="nautilus_trader.examples.strategies.ema_cross:EMACross",
        config_path="nautilus_trader.examples.strategies.ema_cross:EMACrossConfig",
        config={
            "instrument_id": "EUR/USD.SIM",
            "bar_type": "EUR/USD.SIM-1-MINUTE-BID-INTERNAL",
            "fast_ema_period": fast,
            "slow_ema_period": slow,
            "trade_size": "1_000_000",
        },
    )

    configs.append(
        BacktestRunConfig(
            venues=[venue],
            data=[data],
            engine=BacktestEngineConfig(strategies=[strategy]),
        )
    )

node = BacktestNode(configs=configs)
results = node.run()  # Returns 4 BacktestResult objects

Streaming mode for large datasets:

from nautilus_trader.backtest.node import BacktestNode
from nautilus_trader.backtest.config import (
    BacktestDataConfig,
    BacktestEngineConfig,
    BacktestRunConfig,
    BacktestVenueConfig,
)
from nautilus_trader.trading.config import ImportableStrategyConfig

run_config = BacktestRunConfig(
    venues=[
        BacktestVenueConfig(
            name="SIM",
            oms_type="HEDGING",
            account_type="CASH",
            starting_balances=["1_000_000 USD"],
        ),
    ],
    data=[
        BacktestDataConfig(
            catalog_path="/data/large_catalog",
            data_cls="nautilus_trader.model.data:TradeTick",
            instrument_id="BTCUSDT-PERP.BINANCE",
        ),
    ],
    engine=BacktestEngineConfig(
        strategies=[
            ImportableStrategyConfig(
                strategy_path="my_strategies.trend:TrendFollower",
                config_path="my_strategies.trend:TrendFollowerConfig",
                config={"instrument_id": "BTCUSDT-PERP.BINANCE"},
            ),
        ],
    ),
    chunk_size=100_000,  # Stream in 100k-record chunks
    dispose_on_completion=False,  # Keep engine for post-run inspection
)

node = BacktestNode(configs=[run_config])
results = node.run()

# Inspect engine state after run
engines = node.get_engines()
engine = engines[0]
print(engine.trader.generate_order_fills_report())

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment