nautilus_trading/examples/strategies/grid_mm/
config.rs1use nautilus_model::{
19 identifiers::{InstrumentId, StrategyId},
20 types::Quantity,
21};
22
23use crate::strategy::StrategyConfig;
24
25#[derive(Debug, Clone)]
27#[cfg_attr(
28 feature = "python",
29 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.trading", from_py_object)
30)]
31pub struct GridMarketMakerConfig {
32 pub base: StrategyConfig,
34 pub instrument_id: InstrumentId,
36 pub trade_size: Option<Quantity>,
39 pub num_levels: usize,
41 pub grid_step_bps: u32,
44 pub skew_factor: f64,
46 pub max_position: Quantity,
48 pub requote_threshold_bps: u32,
51 pub expire_time_secs: Option<u64>,
54 pub on_cancel_resubmit: bool,
58}
59
60impl GridMarketMakerConfig {
61 #[must_use]
63 pub fn new(instrument_id: InstrumentId, max_position: Quantity) -> Self {
64 Self {
65 base: StrategyConfig {
66 strategy_id: Some(StrategyId::from("GRID_MM-001")),
67 order_id_tag: Some("001".to_string()),
68 ..Default::default()
69 },
70 instrument_id,
71 trade_size: None,
72 num_levels: 3,
73 grid_step_bps: 10,
74 skew_factor: 0.0,
75 max_position,
76 requote_threshold_bps: 5,
77 expire_time_secs: None,
78 on_cancel_resubmit: false,
79 }
80 }
81
82 #[must_use]
83 pub fn with_trade_size(mut self, trade_size: Quantity) -> Self {
84 self.trade_size = Some(trade_size);
85 self
86 }
87
88 #[must_use]
89 pub fn with_num_levels(mut self, num_levels: usize) -> Self {
90 self.num_levels = num_levels;
91 self
92 }
93
94 #[must_use]
95 pub fn with_grid_step_bps(mut self, bps: u32) -> Self {
96 self.grid_step_bps = bps;
97 self
98 }
99
100 #[must_use]
101 pub fn with_skew_factor(mut self, skew_factor: f64) -> Self {
102 self.skew_factor = skew_factor;
103 self
104 }
105
106 #[must_use]
107 pub fn with_requote_threshold_bps(mut self, bps: u32) -> Self {
108 self.requote_threshold_bps = bps;
109 self
110 }
111
112 #[must_use]
113 pub fn with_expire_time_secs(mut self, secs: u64) -> Self {
114 self.expire_time_secs = Some(secs);
115 self
116 }
117
118 #[must_use]
119 pub fn with_on_cancel_resubmit(mut self, enabled: bool) -> Self {
120 self.on_cancel_resubmit = enabled;
121 self
122 }
123
124 #[must_use]
125 pub fn with_strategy_id(mut self, strategy_id: StrategyId) -> Self {
126 self.base.strategy_id = Some(strategy_id);
127 self
128 }
129
130 #[must_use]
131 pub fn with_order_id_tag(mut self, tag: String) -> Self {
132 self.base.order_id_tag = Some(tag);
133 self
134 }
135}
136
137#[cfg(feature = "python")]
138#[pyo3::pymethods]
139impl GridMarketMakerConfig {
140 #[new]
141 #[pyo3(signature = (
142 instrument_id,
143 max_position,
144 strategy_id=None,
145 order_id_tag=None,
146 trade_size=None,
147 num_levels=3,
148 grid_step_bps=10,
149 skew_factor=0.0,
150 requote_threshold_bps=5,
151 expire_time_secs=None,
152 on_cancel_resubmit=false,
153 ))]
154 #[expect(clippy::too_many_arguments)]
155 fn py_new(
156 instrument_id: InstrumentId,
157 max_position: Quantity,
158 strategy_id: Option<StrategyId>,
159 order_id_tag: Option<String>,
160 trade_size: Option<Quantity>,
161 num_levels: usize,
162 grid_step_bps: u32,
163 skew_factor: f64,
164 requote_threshold_bps: u32,
165 expire_time_secs: Option<u64>,
166 on_cancel_resubmit: bool,
167 ) -> Self {
168 let mut config = Self::new(instrument_id, max_position)
169 .with_num_levels(num_levels)
170 .with_grid_step_bps(grid_step_bps)
171 .with_skew_factor(skew_factor)
172 .with_requote_threshold_bps(requote_threshold_bps)
173 .with_on_cancel_resubmit(on_cancel_resubmit);
174
175 if let Some(size) = trade_size {
176 config = config.with_trade_size(size);
177 }
178
179 if let Some(secs) = expire_time_secs {
180 config = config.with_expire_time_secs(secs);
181 }
182
183 if let Some(id) = strategy_id {
184 config.base.strategy_id = Some(id);
185 }
186
187 if let Some(tag) = order_id_tag {
188 config.base.order_id_tag = Some(tag);
189 }
190
191 config
192 }
193
194 #[getter]
195 fn instrument_id(&self) -> InstrumentId {
196 self.instrument_id
197 }
198
199 #[getter]
200 fn max_position(&self) -> Quantity {
201 self.max_position
202 }
203
204 #[getter]
205 fn trade_size(&self) -> Option<Quantity> {
206 self.trade_size
207 }
208
209 #[getter]
210 fn num_levels(&self) -> usize {
211 self.num_levels
212 }
213
214 #[getter]
215 fn grid_step_bps(&self) -> u32 {
216 self.grid_step_bps
217 }
218
219 #[getter]
220 fn skew_factor(&self) -> f64 {
221 self.skew_factor
222 }
223
224 #[getter]
225 fn requote_threshold_bps(&self) -> u32 {
226 self.requote_threshold_bps
227 }
228
229 #[getter]
230 fn expire_time_secs(&self) -> Option<u64> {
231 self.expire_time_secs
232 }
233
234 #[getter]
235 fn on_cancel_resubmit(&self) -> bool {
236 self.on_cancel_resubmit
237 }
238}