Skip to main content

BacktestEngine

Main entry point for running backtests.
pub struct BacktestEngine {
    config: BacktestConfig,
    data_manager: DataManager,
}
config
BacktestConfig
Backtest configuration and parameters
data_manager
DataManager
Data manager for loading market data
Methods:
impl BacktestEngine {
    pub async fn new(config: BacktestConfig) -> GbResult<Self>
    
    pub async fn load_market_data(&mut self, symbols: Vec<Symbol>) -> GbResult<()>
    
    pub async fn run_with_strategy(
        &mut self,
        strategy: Box<dyn Strategy>,
    ) -> GbResult<BacktestResult>
    
    pub async fn run(&mut self) -> GbResult<BacktestResult>
    
    pub fn get_config(&self) -> &BacktestConfig
}
Example:
use gb_types::{BacktestConfig, StrategyConfig, Symbol, Resolution};
use gb_engine::BacktestEngine;
use chrono::{Duration, Utc};
use rust_decimal::Decimal;

// Create backtest configuration
let strategy_config = StrategyConfig::new(
    "my_strategy".to_string(),
    "My Strategy".to_string()
);

let mut config = BacktestConfig::new("My Backtest".to_string(), strategy_config);
config.start_date = Utc::now() - Duration::days(365);
config.end_date = Utc::now();
config.initial_capital = Decimal::from(100000);
config.resolution = Resolution::Day;
config.symbols = vec![Symbol::equity("AAPL")];

// Create engine and run backtest
let mut engine = BacktestEngine::new(config).await?;
let strategy = Box::new(BuyAndHoldStrategy::new());
let result = engine.run_with_strategy(strategy).await?;

// Analyze results
println!("Total return: {:.2}%", result.performance_metrics.unwrap().total_return * Decimal::from(100));

Engine

Enhanced event-driven backtesting engine.
pub struct Engine {
    config: BacktestConfig,
    portfolio: Portfolio,
    strategy: Box<dyn Strategy>,
    current_time: DateTime<Utc>,
    market_data: HashMap<Symbol, Vec<Bar>>,
    pending_orders: Vec<Order>,
    strategy_metrics: StrategyMetrics,
    equity_curve: Vec<EquityCurvePoint>,
    equity_peak: Decimal,
}
Methods:
impl Engine {
    pub async fn new(
        config: BacktestConfig,
        data_manager: &mut DataManager,
        strategy: Box<dyn Strategy>,
    ) -> GbResult<Self>
    
    pub async fn run(&mut self) -> GbResult<BacktestResult>
}
Example:
let mut data_manager = DataManager::new().await?;
let strategy = Box::new(MovingAverageCrossoverStrategy::new(10, 20));

let mut engine = Engine::new(config, &mut data_manager, strategy).await?;
let result = engine.run().await?;

Backtest configuration

BacktestConfig

Backtest configuration and parameters.
pub struct BacktestConfig {
    pub id: BacktestId,
    pub name: String,
    pub description: String,
    pub start_date: DateTime<Utc>,
    pub end_date: DateTime<Utc>,
    pub initial_capital: Decimal,
    pub symbols: Vec<Symbol>,
    pub resolution: Resolution,
    pub strategy_config: StrategyConfig,
    pub execution_settings: ExecutionSettings,
    pub data_settings: DataSettings,
    pub created_at: DateTime<Utc>,
}
name
String
Backtest name
start_date
DateTime<Utc>
Backtest start date
end_date
DateTime<Utc>
Backtest end date
initial_capital
Decimal
Starting capital
symbols
Vec<Symbol>
Symbols to backtest
resolution
Resolution
Data resolution
strategy_config
StrategyConfig
Strategy configuration
execution_settings
ExecutionSettings
Execution and slippage settings
Methods:
impl BacktestConfig {
    pub fn new(name: String, strategy_config: StrategyConfig) -> Self
    pub fn with_symbols(mut self, symbols: Vec<Symbol>) -> Self
    pub fn with_date_range(mut self, start: DateTime<Utc>, end: DateTime<Utc>) -> Self
    pub fn with_capital(mut self, capital: Decimal) -> Self
    pub fn with_resolution(mut self, resolution: Resolution) -> Self
}

ExecutionSettings

Execution settings for realistic trading simulation.
pub struct ExecutionSettings {
    pub commission_per_share: Decimal,
    pub commission_percentage: Decimal,
    pub minimum_commission: Decimal,
    pub slippage_model: SlippageModel,
    pub latency_model: LatencyModel,
    pub market_impact_model: MarketImpactModel,
}
commission_per_share
Decimal
Per-share commission (default: $0.001)
commission_percentage
Decimal
Percentage commission (default: 0.05%)
minimum_commission
Decimal
Minimum commission per order (default: $1.00)
slippage_model
SlippageModel
Slippage model (Linear, SquareRoot, etc.)

SlippageModel

Slippage model for order execution.
pub enum SlippageModel {
    None,
    Fixed { basis_points: u32 },
    Linear { basis_points: u32 },
    SquareRoot { factor: Decimal },
    VolumeWeighted { min_bps: u32, max_bps: u32 },
}
Default: Linear { basis_points: 5 } (5 basis points)

Backtest results

BacktestResult

Backtest result with comprehensive metrics.
pub struct BacktestResult {
    pub id: BacktestId,
    pub config: BacktestConfig,
    pub status: BacktestStatus,
    pub start_time: DateTime<Utc>,
    pub end_time: Option<DateTime<Utc>>,
    pub duration_seconds: Option<u64>,
    pub final_portfolio: Option<Portfolio>,
    pub strategy_metrics: Option<StrategyMetrics>,
    pub performance_metrics: Option<PerformanceMetrics>,
    pub equity_curve: Vec<EquityCurvePoint>,
    pub trade_log: Vec<TradeRecord>,
    pub error_message: Option<String>,
    pub metadata: HashMap<String, serde_json::Value>,
}
final_portfolio
Option<Portfolio>
Final portfolio state
strategy_metrics
Option<StrategyMetrics>
Strategy-specific metrics
performance_metrics
Option<PerformanceMetrics>
Portfolio performance metrics
equity_curve
Vec<EquityCurvePoint>
Equity curve over time
Methods:
impl BacktestResult {
    pub fn new(config: BacktestConfig) -> Self
    pub fn mark_started(&mut self)
    pub fn mark_completed(&mut self, portfolio: Portfolio, metrics: StrategyMetrics)
    pub fn mark_failed(&mut self, error: String)
}

PerformanceMetrics

Performance metrics for backtest evaluation.
pub struct PerformanceMetrics {
    pub total_return: Decimal,
    pub annualized_return: Decimal,
    pub volatility: Decimal,
    pub sharpe_ratio: Option<Decimal>,
    pub sortino_ratio: Option<Decimal>,
    pub calmar_ratio: Option<Decimal>,
    pub max_drawdown: Decimal,
    pub max_drawdown_duration_days: Option<u32>,
    pub var_95: Option<Decimal>,
    pub cvar_95: Option<Decimal>,
    pub win_rate: Decimal,
    pub profit_factor: Option<Decimal>,
    pub total_trades: u64,
    pub total_commissions: Decimal,
}
total_return
Decimal
Total return over backtest period
annualized_return
Decimal
Annualized return
volatility
Decimal
Annualized volatility (standard deviation of returns)
sharpe_ratio
Option<Decimal>
Sharpe ratio (risk-adjusted return)
sortino_ratio
Option<Decimal>
Sortino ratio (downside risk-adjusted return)
max_drawdown
Decimal
Maximum drawdown from peak
var_95
Option<Decimal>
Value at Risk (95% confidence)
cvar_95
Option<Decimal>
Conditional Value at Risk (95% confidence)
Methods:
impl PerformanceMetrics {
    pub fn calculate(portfolio: &Portfolio) -> Self
    pub fn calculate_with_trades(portfolio: &Portfolio, trades: &[TradeRecord]) -> Self
}

EquityCurvePoint

Point on the equity curve.
pub struct EquityCurvePoint {
    pub timestamp: DateTime<Utc>,
    pub portfolio_value: Decimal,
    pub cash: Decimal,
    pub positions_value: Decimal,
    pub total_pnl: Decimal,
    pub daily_return: Option<Decimal>,
    pub cumulative_return: Decimal,
    pub drawdown: Decimal,
}

Market simulator

MarketSimulator

Comprehensive market simulator for realistic backtesting.
pub struct MarketSimulator {
    events: BTreeMap<DateTime<Utc>, Vec<TimestampedEvent>>,
    current_data: HashMap<Symbol, Bar>,
    current_events: VecDeque<TimestampedEvent>,
    current_time: Option<DateTime<Utc>>,
    start_time: Option<DateTime<Utc>>,
    end_time: Option<DateTime<Utc>>,
    symbols: Vec<Symbol>,
    resolution: Resolution,
    market_hours: MarketHours,
}
Methods:
impl MarketSimulator {
    pub fn new() -> Self
    pub fn with_market_hours(mut self, market_hours: MarketHours) -> Self
    pub fn with_resolution(mut self, resolution: Resolution) -> Self
    
    pub fn add_data_feed(&mut self, symbol: Symbol, bars: Vec<Bar>) -> GbResult<()>
    pub fn initialize(&mut self) -> GbResult<()>
    
    pub fn next_events(&mut self) -> GbResult<Vec<TimestampedEvent>>
    pub fn get_current_data(&self, symbol: &Symbol) -> Option<&Bar>
    pub fn get_all_current_data(&self) -> &HashMap<Symbol, Bar>
    
    pub fn current_time(&self) -> Option<DateTime<Utc>>
    pub fn is_complete(&self) -> bool
    pub fn progress(&self) -> f64
    pub fn reset(&mut self)
    pub fn get_stats(&self) -> SimulationStats
    
    pub fn is_market_open(&self, time: DateTime<Utc>) -> bool
    
    pub async fn run_with_callback<F, Fut>(&mut self, callback: F) -> GbResult<()>
    where
        F: FnMut(DateTime<Utc>, Vec<TimestampedEvent>) -> Fut,
        Fut: std::future::Future<Output = GbResult<()>>,
}
Example:
let mut simulator = MarketSimulator::new()
    .with_market_hours(MarketHours::for_asset_class(AssetClass::Equity))
    .with_resolution(Resolution::Day);

// Add data feeds
simulator.add_data_feed(Symbol::equity("AAPL"), aapl_bars)?;
simulator.add_data_feed(Symbol::equity("GOOGL"), googl_bars)?;

// Initialize and run
simulator.initialize()?;

while !simulator.is_complete() {
    let events = simulator.next_events()?;
    
    for event in events {
        // Process each market event
        println!("Event at {}: {:?}", event.timestamp, event.event);
    }
}

MarketHours

Market hours configuration.
pub struct MarketHours {
    pub open_hour: u32,
    pub close_hour: u32,
    pub weekend_trading: bool,
    pub round_the_clock: bool,
}
Methods:
impl MarketHours {
    pub fn for_asset_class(asset_class: AssetClass) -> Self
}
Defaults by asset class:
  • Crypto: 24/7 trading (0-24 hours, weekends enabled)
  • Forex: 24h weekdays (0-24 hours, no weekends)
  • Equity: US market hours (14-21 UTC, no weekends)

Build docs developers (and LLMs) love