nautilus_trading/algorithm/
config.rs1use std::collections::HashMap;
19
20use nautilus_core::serialization::default_true;
21use nautilus_model::identifiers::ExecAlgorithmId;
22use serde::{Deserialize, Serialize};
23
24#[cfg_attr(
26 feature = "python",
27 expect(
28 clippy::unsafe_derive_deserialize,
29 reason = "config deserializes plain fields; unsafe methods come from generated PyO3 integration"
30 )
31)]
32#[derive(Clone, Debug, Deserialize, Serialize, bon::Builder)]
33#[serde(deny_unknown_fields)]
34#[cfg_attr(
35 feature = "python",
36 pyo3::pyclass(
37 module = "nautilus_trader.core.nautilus_pyo3.trading",
38 subclass,
39 from_py_object
40 )
41)]
42#[cfg_attr(
43 feature = "python",
44 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.trading")
45)]
46pub struct ExecutionAlgorithmConfig {
47 pub exec_algorithm_id: Option<ExecAlgorithmId>,
49 #[serde(default = "default_true")]
51 #[builder(default = true)]
52 pub log_events: bool,
53 #[serde(default = "default_true")]
55 #[builder(default = true)]
56 pub log_commands: bool,
57}
58
59impl Default for ExecutionAlgorithmConfig {
60 fn default() -> Self {
61 Self::builder().build()
62 }
63}
64
65#[cfg_attr(
67 feature = "python",
68 expect(
69 clippy::unsafe_derive_deserialize,
70 reason = "config deserializes plain fields; unsafe methods come from generated PyO3 integration"
71 )
72)]
73#[derive(Debug, Clone, Deserialize, Serialize)]
74#[serde(deny_unknown_fields)]
75#[cfg_attr(
76 feature = "python",
77 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.trading", from_py_object)
78)]
79#[cfg_attr(
80 feature = "python",
81 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.trading")
82)]
83pub struct ImportableExecAlgorithmConfig {
84 pub exec_algorithm_path: String,
86 pub config_path: String,
88 pub config: HashMap<String, serde_json::Value>,
90}
91
92#[cfg(test)]
93mod tests {
94 use rstest::rstest;
95
96 use super::*;
97
98 #[rstest]
99 fn test_config_default() {
100 let config = ExecutionAlgorithmConfig::default();
101
102 assert!(config.exec_algorithm_id.is_none());
103 assert!(config.log_events);
104 assert!(config.log_commands);
105 }
106
107 #[rstest]
108 fn test_config_with_id() {
109 let exec_algorithm_id = ExecAlgorithmId::new("TWAP");
110 let config = ExecutionAlgorithmConfig {
111 exec_algorithm_id: Some(exec_algorithm_id),
112 ..Default::default()
113 };
114
115 assert_eq!(config.exec_algorithm_id, Some(exec_algorithm_id));
116 }
117
118 #[rstest]
119 fn test_config_serialization() {
120 let config = ExecutionAlgorithmConfig {
121 exec_algorithm_id: Some(ExecAlgorithmId::new("TWAP")),
122 log_events: false,
123 log_commands: true,
124 };
125
126 let json = serde_json::to_string(&config).unwrap();
127 let deserialized: ExecutionAlgorithmConfig = serde_json::from_str(&json).unwrap();
128
129 assert_eq!(config.exec_algorithm_id, deserialized.exec_algorithm_id);
130 assert_eq!(config.log_events, deserialized.log_events);
131 assert_eq!(config.log_commands, deserialized.log_commands);
132 }
133}