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_portfolio::config::PortfolioConfig;
36use nautilus_risk::engine::config::RiskEngineConfig;
37use nautilus_system::config::{NautilusKernelConfig, StreamingConfig};
38use ustr::Ustr;
39
40#[derive(Debug, Clone)]
42pub struct BacktestEngineConfig {
43 pub environment: Environment,
45 pub trader_id: TraderId,
47 pub load_state: bool,
49 pub save_state: bool,
51 pub logging: LoggerConfig,
53 pub instance_id: Option<UUID4>,
55 pub timeout_connection: Duration,
57 pub timeout_reconciliation: Duration,
59 pub timeout_portfolio: Duration,
61 pub timeout_disconnection: Duration,
63 pub delay_post_stop: Duration,
65 pub timeout_shutdown: Duration,
67 pub cache: Option<CacheConfig>,
69 pub msgbus: Option<MessageBusConfig>,
71 pub data_engine: Option<DataEngineConfig>,
73 pub risk_engine: Option<RiskEngineConfig>,
75 pub exec_engine: Option<ExecutionEngineConfig>,
77 pub portfolio: Option<PortfolioConfig>,
79 pub streaming: Option<StreamingConfig>,
81 pub bypass_logging: bool,
83 pub run_analysis: bool,
85}
86
87impl BacktestEngineConfig {
88 #[must_use]
89 #[allow(clippy::too_many_arguments)]
90 pub fn new(
91 environment: Environment,
92 trader_id: TraderId,
93 load_state: Option<bool>,
94 save_state: Option<bool>,
95 bypass_logging: Option<bool>,
96 run_analysis: Option<bool>,
97 timeout_connection: Option<u64>,
98 timeout_reconciliation: Option<u64>,
99 timeout_portfolio: Option<u64>,
100 timeout_disconnection: Option<u64>,
101 delay_post_stop: Option<u64>,
102 timeout_shutdown: Option<u64>,
103 logging: Option<LoggerConfig>,
104 instance_id: Option<UUID4>,
105 cache: Option<CacheConfig>,
106 msgbus: Option<MessageBusConfig>,
107 data_engine: Option<DataEngineConfig>,
108 risk_engine: Option<RiskEngineConfig>,
109 exec_engine: Option<ExecutionEngineConfig>,
110 portfolio: Option<PortfolioConfig>,
111 streaming: Option<StreamingConfig>,
112 ) -> Self {
113 Self {
114 environment,
115 trader_id,
116 load_state: load_state.unwrap_or(false),
117 save_state: save_state.unwrap_or(false),
118 logging: logging.unwrap_or_default(),
119 instance_id,
120 timeout_connection: Duration::from_secs(timeout_connection.unwrap_or(60)),
121 timeout_reconciliation: Duration::from_secs(timeout_reconciliation.unwrap_or(30)),
122 timeout_portfolio: Duration::from_secs(timeout_portfolio.unwrap_or(10)),
123 timeout_disconnection: Duration::from_secs(timeout_disconnection.unwrap_or(10)),
124 delay_post_stop: Duration::from_secs(delay_post_stop.unwrap_or(10)),
125 timeout_shutdown: Duration::from_secs(timeout_shutdown.unwrap_or(5)),
126 cache,
127 msgbus,
128 data_engine,
129 risk_engine,
130 exec_engine,
131 portfolio,
132 streaming,
133 bypass_logging: bypass_logging.unwrap_or(false),
134 run_analysis: run_analysis.unwrap_or(true),
135 }
136 }
137}
138
139impl NautilusKernelConfig for BacktestEngineConfig {
140 fn environment(&self) -> Environment {
141 self.environment
142 }
143
144 fn trader_id(&self) -> TraderId {
145 self.trader_id
146 }
147
148 fn load_state(&self) -> bool {
149 self.load_state
150 }
151
152 fn save_state(&self) -> bool {
153 self.save_state
154 }
155
156 fn logging(&self) -> LoggerConfig {
157 self.logging.clone()
158 }
159
160 fn instance_id(&self) -> Option<UUID4> {
161 self.instance_id
162 }
163
164 fn timeout_connection(&self) -> Duration {
165 self.timeout_connection
166 }
167
168 fn timeout_reconciliation(&self) -> Duration {
169 self.timeout_reconciliation
170 }
171
172 fn timeout_portfolio(&self) -> Duration {
173 self.timeout_portfolio
174 }
175
176 fn timeout_disconnection(&self) -> Duration {
177 self.timeout_disconnection
178 }
179
180 fn delay_post_stop(&self) -> Duration {
181 self.delay_post_stop
182 }
183
184 fn timeout_shutdown(&self) -> Duration {
185 self.timeout_shutdown
186 }
187
188 fn cache(&self) -> Option<CacheConfig> {
189 self.cache.clone()
190 }
191
192 fn msgbus(&self) -> Option<MessageBusConfig> {
193 self.msgbus.clone()
194 }
195
196 fn data_engine(&self) -> Option<DataEngineConfig> {
197 self.data_engine.clone()
198 }
199
200 fn risk_engine(&self) -> Option<RiskEngineConfig> {
201 self.risk_engine.clone()
202 }
203
204 fn exec_engine(&self) -> Option<ExecutionEngineConfig> {
205 self.exec_engine.clone()
206 }
207
208 fn portfolio(&self) -> Option<PortfolioConfig> {
209 self.portfolio.clone()
210 }
211
212 fn streaming(&self) -> Option<StreamingConfig> {
213 self.streaming.clone()
214 }
215}
216
217impl Default for BacktestEngineConfig {
218 fn default() -> Self {
219 Self {
220 environment: Environment::Backtest,
221 trader_id: TraderId::default(),
222 load_state: false,
223 save_state: false,
224 logging: LoggerConfig::default(),
225 instance_id: None,
226 timeout_connection: Duration::from_secs(60),
227 timeout_reconciliation: Duration::from_secs(30),
228 timeout_portfolio: Duration::from_secs(10),
229 timeout_disconnection: Duration::from_secs(10),
230 delay_post_stop: Duration::from_secs(10),
231 timeout_shutdown: Duration::from_secs(5),
232 cache: None,
233 msgbus: None,
234 data_engine: None,
235 risk_engine: None,
236 exec_engine: None,
237 portfolio: None,
238 streaming: None,
239 bypass_logging: false,
240 run_analysis: true,
241 }
242 }
243}
244
245#[derive(Debug, Clone)]
247pub struct BacktestVenueConfig {
248 name: Ustr,
250 oms_type: OmsType,
252 account_type: AccountType,
254 book_type: BookType,
256 starting_balances: Vec<String>,
258 routing: bool,
260 frozen_account: bool,
262 reject_stop_orders: bool,
264 support_gtd_orders: bool,
266 support_contingent_orders: bool,
269 use_position_ids: bool,
271 use_random_ids: bool,
273 use_reduce_only: bool,
275 bar_execution: bool,
277 bar_adaptive_high_low_ordering: bool,
284 trade_execution: bool,
286 base_currency: Option<Currency>,
288 default_leverage: Option<f64>,
290 leverages: Option<HashMap<Currency, f64>>,
292 price_protection_points: u32,
295}
296
297impl BacktestVenueConfig {
298 #[allow(clippy::too_many_arguments)]
299 #[must_use]
300 pub fn new(
301 name: Ustr,
302 oms_type: OmsType,
303 account_type: AccountType,
304 book_type: BookType,
305 routing: Option<bool>,
306 frozen_account: Option<bool>,
307 reject_stop_orders: Option<bool>,
308 support_gtd_orders: Option<bool>,
309 support_contingent_orders: Option<bool>,
310 use_position_ids: Option<bool>,
311 use_random_ids: Option<bool>,
312 use_reduce_only: Option<bool>,
313 bar_execution: Option<bool>,
314 bar_adaptive_high_low_ordering: Option<bool>,
315 trade_execution: Option<bool>,
316 starting_balances: Vec<String>,
317 base_currency: Option<Currency>,
318 default_leverage: Option<f64>,
319 leverages: Option<HashMap<Currency, f64>>,
320 price_protection_points: Option<u32>,
321 ) -> Self {
322 Self {
323 name,
324 oms_type,
325 account_type,
326 book_type,
327 routing: routing.unwrap_or(false),
328 frozen_account: frozen_account.unwrap_or(false),
329 reject_stop_orders: reject_stop_orders.unwrap_or(true),
330 support_gtd_orders: support_gtd_orders.unwrap_or(true),
331 support_contingent_orders: support_contingent_orders.unwrap_or(true),
332 use_position_ids: use_position_ids.unwrap_or(true),
333 use_random_ids: use_random_ids.unwrap_or(false),
334 use_reduce_only: use_reduce_only.unwrap_or(true),
335 bar_execution: bar_execution.unwrap_or(true),
336 bar_adaptive_high_low_ordering: bar_adaptive_high_low_ordering.unwrap_or(false),
337 trade_execution: trade_execution.unwrap_or(false),
338 starting_balances,
339 base_currency,
340 default_leverage,
341 leverages,
342 price_protection_points: price_protection_points.unwrap_or(0),
343 }
344 }
345}
346
347#[derive(Debug, Clone)]
348pub struct BacktestDataConfig {
350 catalog_path: String,
352 catalog_fs_protocol: Option<String>,
354 instrument_id: Option<InstrumentId>,
356 start_time: Option<UnixNanos>,
358 end_time: Option<UnixNanos>,
360 filter_expr: Option<String>,
362 client_id: Option<ClientId>,
364 metadata: Option<HashMap<String, String>>,
366 bar_spec: Option<BarSpecification>,
368}
369
370impl BacktestDataConfig {
371 #[allow(clippy::too_many_arguments)]
372 #[must_use]
373 pub const fn new(
374 catalog_path: String,
375 catalog_fs_protocol: Option<String>,
376 instrument_id: Option<InstrumentId>,
377 start_time: Option<UnixNanos>,
378 end_time: Option<UnixNanos>,
379 filter_expr: Option<String>,
380 client_id: Option<ClientId>,
381 metadata: Option<HashMap<String, String>>,
382 bar_spec: Option<BarSpecification>,
383 ) -> Self {
384 Self {
385 catalog_path,
386 catalog_fs_protocol,
387 instrument_id,
388 start_time,
389 end_time,
390 filter_expr,
391 client_id,
392 metadata,
393 bar_spec,
394 }
395 }
396}
397
398#[derive(Debug, Clone)]
401pub struct BacktestRunConfig {
402 venues: Vec<BacktestVenueConfig>,
404 data: Vec<BacktestDataConfig>,
406 engine: BacktestEngineConfig,
408 chunk_size: Option<usize>,
411 dispose_on_completion: bool,
415 start: Option<UnixNanos>,
418 end: Option<UnixNanos>,
421}
422
423impl BacktestRunConfig {
424 #[must_use]
425 pub fn new(
426 venues: Vec<BacktestVenueConfig>,
427 data: Vec<BacktestDataConfig>,
428 engine: BacktestEngineConfig,
429 chunk_size: Option<usize>,
430 dispose_on_completion: Option<bool>,
431 start: Option<UnixNanos>,
432 end: Option<UnixNanos>,
433 ) -> Self {
434 Self {
435 venues,
436 data,
437 engine,
438 chunk_size,
439 dispose_on_completion: dispose_on_completion.unwrap_or(true),
440 start,
441 end,
442 }
443 }
444}