finance_query/backtesting/portfolio/result.rs
1//! Portfolio backtest results.
2
3use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6
7use crate::backtesting::result::{BacktestResult, EquityPoint, PerformanceMetrics};
8
9/// Snapshot of capital allocation at a single point in time.
10#[non_exhaustive]
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct AllocationSnapshot {
13 /// Timestamp (Unix seconds)
14 pub timestamp: i64,
15
16 /// Uninvested cash at this point
17 pub cash: f64,
18
19 /// Market value of each open position (symbol → value)
20 pub positions: HashMap<String, f64>,
21}
22
23impl AllocationSnapshot {
24 /// Total portfolio value (cash + all positions).
25 pub fn total_equity(&self) -> f64 {
26 self.cash + self.positions.values().sum::<f64>()
27 }
28}
29
30/// Results of a multi-symbol portfolio backtest.
31#[non_exhaustive]
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct PortfolioResult {
34 /// Per-symbol backtest results.
35 ///
36 /// Each value is the standalone result for that symbol's trades as if the
37 /// strategy had been run in isolation (same trades, same P&L, same metrics).
38 pub symbols: HashMap<String, BacktestResult>,
39
40 /// Combined portfolio equity curve over the entire backtest period.
41 pub portfolio_equity_curve: Vec<EquityPoint>,
42
43 /// Aggregate performance metrics computed from the combined equity curve
44 /// and all trades across all symbols.
45 pub portfolio_metrics: PerformanceMetrics,
46
47 /// Starting capital shared across all symbols.
48 pub initial_capital: f64,
49
50 /// Final portfolio value (cash + open position values).
51 pub final_equity: f64,
52
53 /// Capital allocation snapshots recorded at each master timeline step.
54 ///
55 /// Use this to visualise how capital was distributed over time.
56 pub allocation_history: Vec<AllocationSnapshot>,
57}