nautilus_backtest/python/
result.rs1use std::collections::{BTreeMap, HashMap};
19
20use nautilus_core::UUID4;
21
22use crate::result::BacktestResult;
23
24#[pyo3_stub_gen::derive::gen_stub_pymethods]
25#[pyo3::pymethods]
26impl BacktestResult {
27 #[getter]
28 #[pyo3(name = "trader_id")]
29 fn py_trader_id(&self) -> &str {
30 &self.trader_id
31 }
32
33 #[getter]
34 #[pyo3(name = "machine_id")]
35 fn py_machine_id(&self) -> &str {
36 &self.machine_id
37 }
38
39 #[getter]
40 #[pyo3(name = "instance_id")]
41 const fn py_instance_id(&self) -> UUID4 {
42 self.instance_id
43 }
44
45 #[getter]
46 #[pyo3(name = "run_config_id")]
47 fn py_run_config_id(&self) -> Option<&str> {
48 self.run_config_id.as_deref()
49 }
50
51 #[getter]
52 #[pyo3(name = "run_id")]
53 const fn py_run_id(&self) -> Option<UUID4> {
54 self.run_id
55 }
56
57 #[getter]
58 #[pyo3(name = "run_started")]
59 fn py_run_started(&self) -> Option<u64> {
60 self.run_started.map(|timestamp| timestamp.as_u64())
61 }
62
63 #[getter]
64 #[pyo3(name = "run_finished")]
65 fn py_run_finished(&self) -> Option<u64> {
66 self.run_finished.map(|timestamp| timestamp.as_u64())
67 }
68
69 #[getter]
70 #[pyo3(name = "backtest_start")]
71 fn py_backtest_start(&self) -> Option<u64> {
72 self.backtest_start.map(|timestamp| timestamp.as_u64())
73 }
74
75 #[getter]
76 #[pyo3(name = "backtest_end")]
77 fn py_backtest_end(&self) -> Option<u64> {
78 self.backtest_end.map(|timestamp| timestamp.as_u64())
79 }
80
81 #[getter]
82 #[pyo3(name = "elapsed_time_secs")]
83 const fn py_elapsed_time_secs(&self) -> f64 {
84 self.elapsed_time_secs
85 }
86
87 #[getter]
88 #[pyo3(name = "iterations")]
89 const fn py_iterations(&self) -> usize {
90 self.iterations
91 }
92
93 #[getter]
94 #[pyo3(name = "total_events")]
95 const fn py_total_events(&self) -> usize {
96 self.total_events
97 }
98
99 #[getter]
100 #[pyo3(name = "total_orders")]
101 const fn py_total_orders(&self) -> usize {
102 self.total_orders
103 }
104
105 #[getter]
106 #[pyo3(name = "total_positions")]
107 const fn py_total_positions(&self) -> usize {
108 self.total_positions
109 }
110
111 #[getter]
112 #[pyo3(name = "summary")]
113 fn py_summary(&self) -> HashMap<String, String> {
114 self.summary
115 .iter()
116 .map(|(key, value)| (key.clone(), value.clone()))
117 .collect()
118 }
119
120 #[getter]
121 #[pyo3(name = "stats_pnls")]
122 fn py_stats_pnls(&self) -> HashMap<String, HashMap<String, f64>> {
123 self.stats_pnls
124 .iter()
125 .map(|(k, v)| {
126 (
127 k.clone(),
128 v.iter().map(|(k2, v2)| (k2.clone(), *v2)).collect(),
129 )
130 })
131 .collect()
132 }
133
134 #[getter]
135 #[pyo3(name = "stats_returns")]
136 fn py_stats_returns(&self) -> HashMap<String, f64> {
137 self.stats_returns
138 .iter()
139 .map(|(k, v)| (k.clone(), *v))
140 .collect()
141 }
142
143 #[getter]
144 #[pyo3(name = "stats_general")]
145 fn py_stats_general(&self) -> HashMap<String, f64> {
146 self.stats_general
147 .iter()
148 .map(|(k, v)| (k.clone(), *v))
149 .collect()
150 }
151
152 #[getter]
153 #[pyo3(name = "returns_series")]
154 fn py_returns_series(&self) -> BTreeMap<u64, f64> {
155 self.returns_series
156 .iter()
157 .map(|(timestamp, value)| (timestamp.as_u64(), *value))
158 .collect()
159 }
160
161 fn __repr__(&self) -> String {
162 format!(
163 "BacktestResult(trader_id='{}', elapsed={:.2}s, iterations={}, orders={}, positions={})",
164 self.trader_id,
165 self.elapsed_time_secs,
166 self.iterations,
167 self.total_orders,
168 self.total_positions,
169 )
170 }
171}