Broker & Simulation Engine
Relevant source files
The following files were used as context for generating this wiki page:
The Broker & Simulation Engine serves as the central interface between trading strategies and the execution venue, whether that venue is a live market or a simulated backtesting environment. It manages the lifecycle of orders, tracks account cash and portfolio value, handles commission schemes, and models market frictions like slippage.
In backtesting mode, the engine simulates market behavior by matching submitted orders against historical price bars. In live trading mode, it acts as a proxy, translating internal order commands into API calls for external providers like Interactive Brokers and synchronizing real-time account updates.
Sources: backtrader/broker.py:34-45, backtrader/brokers/bbroker.py:46-60
Architecture Overview
The system is built on a hierarchical structure where BrokerBase defines the essential API, and specific implementations handle simulation or live connectivity.
The architecture uses a metaclass MetaBroker to ensure method translations (e.g., mapping get_cash to getcash) are handled automatically across subclasses.
Sources: backtrader/broker.py:34-60, backtrader/brokers/bbroker.py:46-75, backtrader/stores/ibstore.py:126-150
The Simulation Engine (BackBroker)
The BackBroker class is the primary simulation engine. It operates on a "bar-by-bar" basis, where each iteration of the Cerebro engine triggers the broker's next() method to process pending orders and update financial state.
Order Execution Logic
The simulation engine supports several order types, each with specific matching logic:
- Market: Executed using the
openprice of the next available bar. - Close: Executed using the
closeprice of the session's last bar. - Limit: Executed if the price reaches the limit or better.
- Stop: Triggered if the market reaches a specific stop price, converting to a market order.
- StopLimit: Triggered at a stop price, converting to a limit order.
Advanced Simulation Modes
- Cheat-on-Close (CoC): Allows the broker to execute a market order using the closing price of the same bar on which the order was created, effectively "cheating" by knowing the close before the next bar begins.
- Cheat-on-Open (CoO): Similar to CoC, but matches orders using the opening price of the current bar.
Sources: backtrader/brokers/bbroker.py:108-112, backtrader/brokers/bbroker.py:730-745
Commission and Financial Modeling
Financial accuracy is maintained via CommInfoBase objects, which define how costs and profits are calculated for different asset classes.
Commission Schemes
The engine distinguishes between "Stock-like" (percentage-based) and "Futures-like" (fixed-margin) assets.
| Parameter | Type | Description |
|---|---|---|
commission | float | Percentage (0.01 = 1%) or monetary units. |
mult | float | Multiplier applied to asset for profit/loss (e.g., 10 for some futures). |
margin | float | Monetary units needed to hold a position (Futures only). |
stocklike | bool | If True, uses price-based percentage commissions. |
interest | float | Yearly interest rate charged for short selling. |
Sources: backtrader/comminfo.py:34-85, backtrader/comminfo.py:107-118
Slippage Modeling
Slippage simulates market friction where the execution price differs from the requested price due to lack of liquidity or volatility. BackBroker supports:
- Percentage Slippage:
price * (1 + slip_perc) - Fixed Slippage:
price + slip_fixed - Slippage Limits: Options like
slip_limitensure that slippage does not push the execution price beyond the high/low of the bar.
Sources: backtrader/brokers/bbroker.py:126-155, backtrader/brokers/bbroker.py:1015-1045
Order Lifecycle and Notifications
The broker manages a state machine for every order. Strategies receive notifications via notify_order whenever a state transition occurs.
Live Broker Integration
Live brokers, such as the one managed by IBStore for Interactive Brokers, bypass the historical matching logic. They use background threads to listen for execution details and commission reports from the actual broker API.
Key components of live integration include:
- Ticker ID Mapping: Linking internal request IDs to external API IDs.
- Account Synchronization: Real-time updates for
NetLiquidationandTotalCashBalance. - Execution Mapping: Handling
execDetailsandcommissionReportmessages to update internal positions.
Sources: backtrader/stores/ibstore.py:228-260, backtrader/stores/ibstore.py:1175-1210
Configuration and Usage
The broker is typically configured via the Cerebro instance or command-line arguments in the btrun module.
# Configuration via btrun (internal parser)
def setbroker(args, cerebro):
broker = cerebro.getbroker()
if args.cash is not None:
broker.setcash(args.cash)
if args.commission is not None:
broker.setcommission(commission=args.commission, margin=args.margin)
if args.slip_perc is not None:
broker.set_slippage_perc(args.slip_perc)
Sources: backtrader/btrun/btrun.py:218-245
The simulation engine is designed to be highly deterministic, ensuring that backtests can be reproduced exactly given the same data and parameters. This is achieved by strict sequencing of order activation, matching, and cash adjustment within the next() loop of the BackBroker.
Sources: backtrader/brokers/bbroker.py:1124-1160