1#![allow(dead_code)]
18#![allow(unused_variables)]
19
20use std::{collections::HashMap, time::Duration};
21
22use nautilus_common::{
23 cache::CacheConfig, enums::Environment, logging::logger::LoggerConfig,
24 msgbus::database::MessageBusConfig,
25};
26use nautilus_core::{UUID4, UnixNanos};
27use nautilus_data::engine::config::DataEngineConfig;
28use nautilus_execution::engine::config::ExecutionEngineConfig;
29use nautilus_model::{
30 data::BarSpecification,
31 enums::{AccountType, BookType, OmsType},
32 identifiers::{ClientId, InstrumentId, TraderId},
33 types::Currency,
34};
35use nautilus_persistence::config::StreamingConfig;
36use nautilus_portfolio::config::PortfolioConfig;
37use nautilus_risk::engine::config::RiskEngineConfig;
38use nautilus_system::config::NautilusKernelConfig;
39use ustr::Ustr;
40
41#[derive(Debug, Clone)]
43pub struct BacktestEngineConfig {
44 pub environment: Environment,
46 pub trader_id: TraderId,
48 pub load_state: bool,
50 pub save_state: bool,
52 pub logging: LoggerConfig,
54 pub instance_id: Option<UUID4>,
56 pub timeout_connection: Duration,
58 pub timeout_reconciliation: Duration,
60 pub timeout_portfolio: Duration,
62 pub timeout_disconnection: Duration,
64 pub delay_post_stop: Duration,
66 pub timeout_shutdown: Duration,
68 pub cache: Option<CacheConfig>,
70 pub msgbus: Option<MessageBusConfig>,
72 pub data_engine: Option<DataEngineConfig>,
74 pub risk_engine: Option<RiskEngineConfig>,
76 pub exec_engine: Option<ExecutionEngineConfig>,
78 pub portfolio: Option<PortfolioConfig>,
80 pub streaming: Option<StreamingConfig>,
82 pub bypass_logging: bool,
84 pub run_analysis: bool,
86}
87
88impl BacktestEngineConfig {
89 #[must_use]
90 #[allow(clippy::too_many_arguments)]
91 pub fn new(
92 environment: Environment,
93 trader_id: TraderId,
94 load_state: Option<bool>,
95 save_state: Option<bool>,
96 bypass_logging: Option<bool>,
97 run_analysis: Option<bool>,
98 timeout_connection: Option<u64>,
99 timeout_reconciliation: Option<u64>,
100 timeout_portfolio: Option<u64>,
101 timeout_disconnection: Option<u64>,
102 delay_post_stop: Option<u64>,
103 timeout_shutdown: Option<u64>,
104 logging: Option<LoggerConfig>,
105 instance_id: Option<UUID4>,
106 cache: Option<CacheConfig>,
107 msgbus: Option<MessageBusConfig>,
108 data_engine: Option<DataEngineConfig>,
109 risk_engine: Option<RiskEngineConfig>,
110 exec_engine: Option<ExecutionEngineConfig>,
111 portfolio: Option<PortfolioConfig>,
112 streaming: Option<StreamingConfig>,
113 ) -> Self {
114 Self {
115 environment,
116 trader_id,
117 load_state: load_state.unwrap_or(false),
118 save_state: save_state.unwrap_or(false),
119 logging: logging.unwrap_or_default(),
120 instance_id,
121 timeout_connection: Duration::from_secs(timeout_connection.unwrap_or(60)),
122 timeout_reconciliation: Duration::from_secs(timeout_reconciliation.unwrap_or(30)),
123 timeout_portfolio: Duration::from_secs(timeout_portfolio.unwrap_or(10)),
124 timeout_disconnection: Duration::from_secs(timeout_disconnection.unwrap_or(10)),
125 delay_post_stop: Duration::from_secs(delay_post_stop.unwrap_or(10)),
126 timeout_shutdown: Duration::from_secs(timeout_shutdown.unwrap_or(5)),
127 cache,
128 msgbus,
129 data_engine,
130 risk_engine,
131 exec_engine,
132 portfolio,
133 streaming,
134 bypass_logging: bypass_logging.unwrap_or(false),
135 run_analysis: run_analysis.unwrap_or(true),
136 }
137 }
138}
139
140impl NautilusKernelConfig for BacktestEngineConfig {
141 fn environment(&self) -> Environment {
142 self.environment
143 }
144
145 fn trader_id(&self) -> TraderId {
146 self.trader_id
147 }
148
149 fn load_state(&self) -> bool {
150 self.load_state
151 }
152
153 fn save_state(&self) -> bool {
154 self.save_state
155 }
156
157 fn logging(&self) -> LoggerConfig {
158 self.logging.clone()
159 }
160
161 fn instance_id(&self) -> Option<UUID4> {
162 self.instance_id
163 }
164
165 fn timeout_connection(&self) -> Duration {
166 self.timeout_connection
167 }
168
169 fn timeout_reconciliation(&self) -> Duration {
170 self.timeout_reconciliation
171 }
172
173 fn timeout_portfolio(&self) -> Duration {
174 self.timeout_portfolio
175 }
176
177 fn timeout_disconnection(&self) -> Duration {
178 self.timeout_disconnection
179 }
180
181 fn delay_post_stop(&self) -> Duration {
182 self.delay_post_stop
183 }
184
185 fn timeout_shutdown(&self) -> Duration {
186 self.timeout_shutdown
187 }
188
189 fn cache(&self) -> Option<CacheConfig> {
190 self.cache.clone()
191 }
192
193 fn msgbus(&self) -> Option<MessageBusConfig> {
194 self.msgbus.clone()
195 }
196
197 fn data_engine(&self) -> Option<DataEngineConfig> {
198 self.data_engine.clone()
199 }
200
201 fn risk_engine(&self) -> Option<RiskEngineConfig> {
202 self.risk_engine.clone()
203 }
204
205 fn exec_engine(&self) -> Option<ExecutionEngineConfig> {
206 self.exec_engine.clone()
207 }
208
209 fn portfolio(&self) -> Option<PortfolioConfig> {
210 self.portfolio.clone()
211 }
212
213 fn streaming(&self) -> Option<StreamingConfig> {
214 self.streaming.clone()
215 }
216}
217
218impl Default for BacktestEngineConfig {
219 fn default() -> Self {
220 Self {
221 environment: Environment::Backtest,
222 trader_id: TraderId::default(),
223 load_state: false,
224 save_state: false,
225 logging: LoggerConfig::default(),
226 instance_id: None,
227 timeout_connection: Duration::from_secs(60),
228 timeout_reconciliation: Duration::from_secs(30),
229 timeout_portfolio: Duration::from_secs(10),
230 timeout_disconnection: Duration::from_secs(10),
231 delay_post_stop: Duration::from_secs(10),
232 timeout_shutdown: Duration::from_secs(5),
233 cache: None,
234 msgbus: None,
235 data_engine: None,
236 risk_engine: None,
237 exec_engine: None,
238 portfolio: None,
239 streaming: None,
240 bypass_logging: false,
241 run_analysis: true,
242 }
243 }
244}
245
246#[derive(Debug, Clone)]
248pub struct BacktestVenueConfig {
249 name: Ustr,
251 oms_type: OmsType,
253 account_type: AccountType,
255 book_type: BookType,
257 starting_balances: Vec<String>,
259 routing: bool,
261 frozen_account: bool,
263 reject_stop_orders: bool,
265 support_gtd_orders: bool,
267 support_contingent_orders: bool,
270 use_position_ids: bool,
272 use_random_ids: bool,
274 use_reduce_only: bool,
276 bar_execution: bool,
278 bar_adaptive_high_low_ordering: bool,
285 trade_execution: bool,
287 base_currency: Option<Currency>,
289 default_leverage: Option<f64>,
291 leverages: Option<HashMap<Currency, f64>>,
293 price_protection_points: u32,
296}
297
298impl BacktestVenueConfig {
299 #[allow(clippy::too_many_arguments)]
300 #[must_use]
301 pub fn new(
302 name: Ustr,
303 oms_type: OmsType,
304 account_type: AccountType,
305 book_type: BookType,
306 routing: Option<bool>,
307 frozen_account: Option<bool>,
308 reject_stop_orders: Option<bool>,
309 support_gtd_orders: Option<bool>,
310 support_contingent_orders: Option<bool>,
311 use_position_ids: Option<bool>,
312 use_random_ids: Option<bool>,
313 use_reduce_only: Option<bool>,
314 bar_execution: Option<bool>,
315 bar_adaptive_high_low_ordering: Option<bool>,
316 trade_execution: Option<bool>,
317 starting_balances: Vec<String>,
318 base_currency: Option<Currency>,
319 default_leverage: Option<f64>,
320 leverages: Option<HashMap<Currency, f64>>,
321 price_protection_points: Option<u32>,
322 ) -> Self {
323 Self {
324 name,
325 oms_type,
326 account_type,
327 book_type,
328 routing: routing.unwrap_or(false),
329 frozen_account: frozen_account.unwrap_or(false),
330 reject_stop_orders: reject_stop_orders.unwrap_or(true),
331 support_gtd_orders: support_gtd_orders.unwrap_or(true),
332 support_contingent_orders: support_contingent_orders.unwrap_or(true),
333 use_position_ids: use_position_ids.unwrap_or(true),
334 use_random_ids: use_random_ids.unwrap_or(false),
335 use_reduce_only: use_reduce_only.unwrap_or(true),
336 bar_execution: bar_execution.unwrap_or(true),
337 bar_adaptive_high_low_ordering: bar_adaptive_high_low_ordering.unwrap_or(false),
338 trade_execution: trade_execution.unwrap_or(false),
339 starting_balances,
340 base_currency,
341 default_leverage,
342 leverages,
343 price_protection_points: price_protection_points.unwrap_or(0),
344 }
345 }
346}
347
348#[derive(Debug, Clone)]
349pub struct BacktestDataConfig {
351 catalog_path: String,
353 catalog_fs_protocol: Option<String>,
355 instrument_id: Option<InstrumentId>,
357 start_time: Option<UnixNanos>,
359 end_time: Option<UnixNanos>,
361 filter_expr: Option<String>,
363 client_id: Option<ClientId>,
365 metadata: Option<HashMap<String, String>>,
367 bar_spec: Option<BarSpecification>,
369}
370
371impl BacktestDataConfig {
372 #[allow(clippy::too_many_arguments)]
373 #[must_use]
374 pub const fn new(
375 catalog_path: String,
376 catalog_fs_protocol: Option<String>,
377 instrument_id: Option<InstrumentId>,
378 start_time: Option<UnixNanos>,
379 end_time: Option<UnixNanos>,
380 filter_expr: Option<String>,
381 client_id: Option<ClientId>,
382 metadata: Option<HashMap<String, String>>,
383 bar_spec: Option<BarSpecification>,
384 ) -> Self {
385 Self {
386 catalog_path,
387 catalog_fs_protocol,
388 instrument_id,
389 start_time,
390 end_time,
391 filter_expr,
392 client_id,
393 metadata,
394 bar_spec,
395 }
396 }
397}
398
399#[derive(Debug, Clone)]
402pub struct BacktestRunConfig {
403 venues: Vec<BacktestVenueConfig>,
405 data: Vec<BacktestDataConfig>,
407 engine: BacktestEngineConfig,
409 chunk_size: Option<usize>,
412 dispose_on_completion: bool,
416 start: Option<UnixNanos>,
419 end: Option<UnixNanos>,
422}
423
424impl BacktestRunConfig {
425 #[must_use]
426 pub fn new(
427 venues: Vec<BacktestVenueConfig>,
428 data: Vec<BacktestDataConfig>,
429 engine: BacktestEngineConfig,
430 chunk_size: Option<usize>,
431 dispose_on_completion: Option<bool>,
432 start: Option<UnixNanos>,
433 end: Option<UnixNanos>,
434 ) -> Self {
435 Self {
436 venues,
437 data,
438 engine,
439 chunk_size,
440 dispose_on_completion: dispose_on_completion.unwrap_or(true),
441 start,
442 end,
443 }
444 }
445}