nautilus_common/messages/execution/
cancel.rs1use std::fmt::Display;
17
18use derive_builder::Builder;
19use nautilus_core::{Params, UUID4, UnixNanos};
20use nautilus_model::{
21 enums::OrderSide,
22 identifiers::{ClientId, ClientOrderId, InstrumentId, StrategyId, TraderId, VenueOrderId},
23};
24use serde::{Deserialize, Serialize};
25
26#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Builder)]
27#[serde(tag = "type")]
28pub struct CancelOrder {
29 pub trader_id: TraderId,
30 pub client_id: Option<ClientId>,
31 pub strategy_id: StrategyId,
32 pub instrument_id: InstrumentId,
33 pub client_order_id: ClientOrderId,
34 pub venue_order_id: Option<VenueOrderId>,
35 pub command_id: UUID4,
36 pub ts_init: UnixNanos,
37 pub params: Option<Params>,
38 #[builder(default)]
39 pub correlation_id: Option<UUID4>,
40 #[builder(default)]
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub causation_id: Option<UUID4>,
43}
44
45impl CancelOrder {
46 #[expect(clippy::too_many_arguments)]
48 #[must_use]
49 pub fn new(
50 trader_id: TraderId,
51 client_id: Option<ClientId>,
52 strategy_id: StrategyId,
53 instrument_id: InstrumentId,
54 client_order_id: ClientOrderId,
55 venue_order_id: Option<VenueOrderId>,
56 command_id: UUID4,
57 ts_init: UnixNanos,
58 params: Option<Params>,
59 correlation_id: Option<UUID4>,
60 ) -> Self {
61 Self {
62 trader_id,
63 client_id,
64 strategy_id,
65 instrument_id,
66 client_order_id,
67 venue_order_id,
68 command_id,
69 ts_init,
70 params,
71 correlation_id,
72 causation_id: None,
73 }
74 }
75}
76
77impl Display for CancelOrder {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 write!(
80 f,
81 "CancelOrder(instrument_id={}, client_order_id={}, venue_order_id={:?})",
82 self.instrument_id, self.client_order_id, self.venue_order_id,
83 )
84 }
85}
86
87#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Builder)]
88#[serde(tag = "type")]
89pub struct CancelAllOrders {
90 pub trader_id: TraderId,
91 pub client_id: Option<ClientId>,
92 pub strategy_id: StrategyId,
93 pub instrument_id: InstrumentId,
94 #[serde(with = "nautilus_model::enums::serde_option_order_side")]
95 pub order_side: Option<OrderSide>,
96 pub command_id: UUID4,
97 pub ts_init: UnixNanos,
98 pub params: Option<Params>,
99 #[builder(default)]
100 pub correlation_id: Option<UUID4>,
101 #[builder(default)]
102 #[serde(default, skip_serializing_if = "Option::is_none")]
103 pub causation_id: Option<UUID4>,
104}
105
106impl CancelAllOrders {
107 #[expect(clippy::too_many_arguments)]
109 #[must_use]
110 pub fn new(
111 trader_id: TraderId,
112 client_id: Option<ClientId>,
113 strategy_id: StrategyId,
114 instrument_id: InstrumentId,
115 order_side: Option<OrderSide>,
116 command_id: UUID4,
117 ts_init: UnixNanos,
118 params: Option<Params>,
119 correlation_id: Option<UUID4>,
120 ) -> Self {
121 Self {
122 trader_id,
123 client_id,
124 strategy_id,
125 instrument_id,
126 order_side,
127 command_id,
128 ts_init,
129 params,
130 correlation_id,
131 causation_id: None,
132 }
133 }
134}
135
136impl Display for CancelAllOrders {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138 let order_side = self
139 .order_side
140 .as_ref()
141 .map_or("NO_ORDER_SIDE", AsRef::as_ref);
142 write!(
143 f,
144 "CancelAllOrders(instrument_id={}, order_side={})",
145 self.instrument_id, order_side,
146 )
147 }
148}
149
150#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Builder)]
151#[serde(tag = "type")]
152pub struct BatchCancelOrders {
153 pub trader_id: TraderId,
154 pub client_id: Option<ClientId>,
155 pub strategy_id: StrategyId,
156 pub instrument_id: InstrumentId,
157 pub cancels: Vec<CancelOrder>,
158 pub command_id: UUID4,
159 pub ts_init: UnixNanos,
160 pub params: Option<Params>,
161 #[builder(default)]
162 pub correlation_id: Option<UUID4>,
163 #[builder(default)]
164 #[serde(default, skip_serializing_if = "Option::is_none")]
165 pub causation_id: Option<UUID4>,
166}
167
168impl BatchCancelOrders {
169 #[expect(clippy::too_many_arguments)]
171 #[must_use]
172 pub fn new(
173 trader_id: TraderId,
174 client_id: Option<ClientId>,
175 strategy_id: StrategyId,
176 instrument_id: InstrumentId,
177 cancels: Vec<CancelOrder>,
178 command_id: UUID4,
179 ts_init: UnixNanos,
180 params: Option<Params>,
181 correlation_id: Option<UUID4>,
182 ) -> Self {
183 Self {
184 trader_id,
185 client_id,
186 strategy_id,
187 instrument_id,
188 cancels,
189 command_id,
190 ts_init,
191 params,
192 correlation_id,
193 causation_id: None,
194 }
195 }
196}
197
198impl Display for BatchCancelOrders {
199 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
200 write!(
201 f,
202 "BatchCancelOrders(instrument_id={}, cancels=TBD)",
203 self.instrument_id,
204 )
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use rstest::rstest;
211
212 use super::*;
213
214 #[rstest]
215 #[case(Some(OrderSide::Buy), "BUY")]
216 #[case(None, "NO_ORDER_SIDE")]
217 fn test_cancel_all_orders_display(
218 #[case] order_side: Option<OrderSide>,
219 #[case] expected_order_side: &str,
220 ) {
221 let command = CancelAllOrders::new(
222 TraderId::from("TRADER-001"),
223 None,
224 StrategyId::from("S-001"),
225 InstrumentId::from("AUD/USD.SIM"),
226 order_side,
227 UUID4::new(),
228 UnixNanos::default(),
229 None,
230 None,
231 );
232
233 assert_eq!(
234 command.to_string(),
235 format!("CancelAllOrders(instrument_id=AUD/USD.SIM, order_side={expected_order_side})")
236 );
237 }
238}