nautilus_trading/strategy/
config.rs1use nautilus_core::serialization::{default_false, default_true};
17use nautilus_model::{
18 enums::{OmsType, TimeInForce},
19 identifiers::{InstrumentId, StrategyId},
20};
21use serde::{Deserialize, Serialize};
22
23#[derive(Clone, Debug, Deserialize, Serialize)]
25#[cfg_attr(
26 feature = "python",
27 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.trading")
28)]
29pub struct StrategyConfig {
30 pub strategy_id: Option<StrategyId>,
32 pub order_id_tag: Option<String>,
35 #[serde(default = "default_false")]
37 pub use_uuid_client_order_ids: bool,
38 #[serde(default = "default_true")]
40 pub use_hyphens_in_client_order_ids: bool,
41 pub oms_type: Option<OmsType>,
44 pub external_order_claims: Option<Vec<InstrumentId>>,
47 #[serde(default = "default_false")]
50 pub manage_contingent_orders: bool,
51 #[serde(default = "default_false")]
54 pub manage_gtd_expiry: bool,
55 #[serde(default = "default_false")]
59 pub manage_stop: bool,
60 #[serde(default = "default_market_exit_interval_ms")]
63 pub market_exit_interval_ms: u64,
64 #[serde(default = "default_market_exit_max_attempts")]
68 pub market_exit_max_attempts: u64,
69 #[serde(default = "default_market_exit_time_in_force")]
71 pub market_exit_time_in_force: TimeInForce,
72 #[serde(default = "default_true")]
74 pub market_exit_reduce_only: bool,
75 #[serde(default = "default_true")]
78 pub log_events: bool,
79 #[serde(default = "default_true")]
81 pub log_commands: bool,
82 #[serde(default = "default_true")]
84 pub log_rejected_due_post_only_as_warning: bool,
85}
86
87const fn default_market_exit_interval_ms() -> u64 {
88 100
89}
90
91const fn default_market_exit_max_attempts() -> u64 {
92 100
93}
94
95const fn default_market_exit_time_in_force() -> TimeInForce {
96 TimeInForce::Gtc
97}
98
99impl Default for StrategyConfig {
100 fn default() -> Self {
101 Self {
102 strategy_id: None,
103 order_id_tag: None,
104 use_uuid_client_order_ids: false,
105 use_hyphens_in_client_order_ids: true,
106 oms_type: None,
107 external_order_claims: None,
108 manage_contingent_orders: false,
109 manage_gtd_expiry: false,
110 manage_stop: false,
111 market_exit_interval_ms: default_market_exit_interval_ms(),
112 market_exit_max_attempts: default_market_exit_max_attempts(),
113 market_exit_time_in_force: TimeInForce::Gtc,
114 market_exit_reduce_only: true,
115 log_events: true,
116 log_commands: true,
117 log_rejected_due_post_only_as_warning: true,
118 }
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use rstest::rstest;
125
126 use super::*;
127
128 #[rstest]
129 fn test_strategy_config_default() {
130 let config = StrategyConfig::default();
131
132 assert!(config.strategy_id.is_none());
133 assert!(config.order_id_tag.is_none());
134 assert!(!config.use_uuid_client_order_ids);
135 assert!(config.use_hyphens_in_client_order_ids);
136 assert!(config.oms_type.is_none());
137 assert!(config.external_order_claims.is_none());
138 assert!(!config.manage_contingent_orders);
139 assert!(!config.manage_gtd_expiry);
140 assert!(!config.manage_stop);
141 assert_eq!(config.market_exit_interval_ms, 100);
142 assert_eq!(config.market_exit_max_attempts, 100);
143 assert_eq!(config.market_exit_time_in_force, TimeInForce::Gtc);
144 assert!(config.market_exit_reduce_only);
145 assert!(config.log_events);
146 assert!(config.log_commands);
147 assert!(config.log_rejected_due_post_only_as_warning);
148 }
149
150 #[rstest]
151 fn test_strategy_config_with_strategy_id() {
152 let strategy_id = StrategyId::from("TEST-001");
153 let config = StrategyConfig {
154 strategy_id: Some(strategy_id),
155 ..Default::default()
156 };
157
158 assert_eq!(config.strategy_id, Some(strategy_id));
159 }
160
161 #[rstest]
162 fn test_strategy_config_serialization() {
163 let config = StrategyConfig {
164 strategy_id: Some(StrategyId::from("TEST-001")),
165 order_id_tag: Some("TAG1".to_string()),
166 use_uuid_client_order_ids: true,
167 ..Default::default()
168 };
169
170 let json = serde_json::to_string(&config).unwrap();
171 let deserialized: StrategyConfig = serde_json::from_str(&json).unwrap();
172
173 assert_eq!(config.strategy_id, deserialized.strategy_id);
174 assert_eq!(config.order_id_tag, deserialized.order_id_tag);
175 assert_eq!(
176 config.use_uuid_client_order_ids,
177 deserialized.use_uuid_client_order_ids
178 );
179 }
180}