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(module = "nautilus_trader.core.nautilus_pyo3.trading", from_py_object)
37)]
38#[cfg_attr(
39 feature = "python",
40 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.trading")
41)]
42pub struct ExecutionAlgorithmConfig {
43 pub exec_algorithm_id: Option<ExecAlgorithmId>,
45 #[serde(default = "default_true")]
47 #[builder(default = true)]
48 pub log_events: bool,
49 #[serde(default = "default_true")]
51 #[builder(default = true)]
52 pub log_commands: bool,
53}
54
55impl Default for ExecutionAlgorithmConfig {
56 fn default() -> Self {
57 Self::builder().build()
58 }
59}
60
61#[cfg_attr(
63 feature = "python",
64 expect(
65 clippy::unsafe_derive_deserialize,
66 reason = "config deserializes plain fields; unsafe methods come from generated PyO3 integration"
67 )
68)]
69#[derive(Debug, Clone, Deserialize, Serialize)]
70#[serde(deny_unknown_fields)]
71#[cfg_attr(
72 feature = "python",
73 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.trading", from_py_object)
74)]
75#[cfg_attr(
76 feature = "python",
77 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.trading")
78)]
79pub struct ImportableExecAlgorithmConfig {
80 pub exec_algorithm_path: String,
82 pub config_path: String,
84 pub config: HashMap<String, serde_json::Value>,
86}
87
88#[cfg(test)]
89mod tests {
90 use rstest::rstest;
91
92 use super::*;
93
94 #[rstest]
95 fn test_config_default() {
96 let config = ExecutionAlgorithmConfig::default();
97
98 assert!(config.exec_algorithm_id.is_none());
99 assert!(config.log_events);
100 assert!(config.log_commands);
101 }
102
103 #[rstest]
104 fn test_config_with_id() {
105 let exec_algorithm_id = ExecAlgorithmId::new("TWAP");
106 let config = ExecutionAlgorithmConfig {
107 exec_algorithm_id: Some(exec_algorithm_id),
108 ..Default::default()
109 };
110
111 assert_eq!(config.exec_algorithm_id, Some(exec_algorithm_id));
112 }
113
114 #[rstest]
115 fn test_config_serialization() {
116 let config = ExecutionAlgorithmConfig {
117 exec_algorithm_id: Some(ExecAlgorithmId::new("TWAP")),
118 log_events: false,
119 log_commands: true,
120 };
121
122 let json = serde_json::to_string(&config).unwrap();
123 let deserialized: ExecutionAlgorithmConfig = serde_json::from_str(&json).unwrap();
124
125 assert_eq!(config.exec_algorithm_id, deserialized.exec_algorithm_id);
126 assert_eq!(config.log_events, deserialized.log_events);
127 assert_eq!(config.log_commands, deserialized.log_commands);
128 }
129}