use crate::{MarketUpdate, Order, Fill, TradingMode, MarketDataSource, ExecutionHandler, TimeProvider, Side}; use crate::positions::PositionTracker; use crate::risk::RiskEngine; use crate::orderbook::OrderBookManager; use chrono::{DateTime, Utc}; use std::collections::{BTreeMap, VecDeque}; use std::sync::Arc; use parking_lot::RwLock; use serde::{Serialize, Deserialize}; pub mod engine; pub mod event; pub mod strategy; pub mod results; pub use engine::BacktestEngine; pub use event::{BacktestEvent, EventType}; pub use strategy::{Strategy, Signal, SignalType}; pub use results::{BacktestResult, BacktestMetrics}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CompletedTrade { pub symbol: String, pub side: Side, pub timestamp: DateTime, pub price: f64, pub quantity: f64, pub commission: f64, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BacktestConfig { pub name: String, pub symbols: Vec, pub start_time: DateTime, pub end_time: DateTime, pub initial_capital: f64, pub commission: f64, pub slippage: f64, pub data_frequency: String, } #[derive(Debug, Clone)] pub struct BacktestState { pub current_time: DateTime, pub portfolio_value: f64, pub cash: f64, pub equity_curve: Vec<(DateTime, f64)>, pub pending_orders: BTreeMap, pub completed_trades: Vec, } impl BacktestState { pub fn new(initial_capital: f64, start_time: DateTime) -> Self { Self { current_time: start_time, portfolio_value: initial_capital, cash: initial_capital, equity_curve: vec![(start_time, initial_capital)], pending_orders: BTreeMap::new(), completed_trades: Vec::new(), } } pub fn update_portfolio_value(&mut self, value: f64) { self.portfolio_value = value; self.equity_curve.push((self.current_time, value)); } pub fn add_pending_order(&mut self, order: Order) { self.pending_orders.insert(order.id.clone(), order); } pub fn remove_pending_order(&mut self, order_id: &str) -> Option { self.pending_orders.remove(order_id) } pub fn record_fill(&mut self, symbol: String, side: Side, fill: Fill) { self.completed_trades.push(CompletedTrade { symbol, side, timestamp: fill.timestamp, price: fill.price, quantity: fill.quantity, commission: fill.commission, }); } } // Event queue for deterministic replay #[derive(Debug)] pub struct EventQueue { events: VecDeque, } impl EventQueue { pub fn new() -> Self { Self { events: VecDeque::new(), } } pub fn push(&mut self, event: BacktestEvent) { // Insert in time order let pos = self.events.iter().position(|e| e.timestamp > event.timestamp) .unwrap_or(self.events.len()); self.events.insert(pos, event); } pub fn pop_until(&mut self, timestamp: DateTime) -> Vec { let mut events = Vec::new(); while let Some(event) = self.events.front() { if event.timestamp <= timestamp { events.push(self.events.pop_front().unwrap()); } else { break; } } events } pub fn is_empty(&self) -> bool { self.events.is_empty() } pub fn len(&self) -> usize { self.events.len() } pub fn peek_next(&self) -> Option<&BacktestEvent> { self.events.front() } }