1use std::fmt::Display;
17
18use indexmap::IndexMap;
19use nautilus_core::{UnixNanos, UUID4};
20use rust_decimal::Decimal;
21use serde::{Deserialize, Serialize};
22use ustr::Ustr;
23
24use super::{
25 base::{Order, OrderError},
26 limit::LimitOrder,
27 limit_if_touched::LimitIfTouchedOrder,
28 market::MarketOrder,
29 market_if_touched::MarketIfTouchedOrder,
30 market_to_limit::MarketToLimitOrder,
31 stop_limit::StopLimitOrder,
32 stop_market::StopMarketOrder,
33 trailing_stop_limit::TrailingStopLimitOrder,
34 trailing_stop_market::TrailingStopMarketOrder,
35};
36use crate::{
37 enums::{
38 ContingencyType, LiquiditySide, OrderSide, OrderSideSpecified, OrderStatus, OrderType,
39 PositionSide, TimeInForce, TrailingOffsetType, TriggerType,
40 },
41 events::OrderEventAny,
42 identifiers::{
43 AccountId, ClientOrderId, ExecAlgorithmId, InstrumentId, OrderListId, PositionId,
44 StrategyId, TradeId, TraderId, VenueOrderId,
45 },
46 types::{Currency, Money, Price, Quantity},
47};
48
49#[derive(Clone, Debug, Serialize, Deserialize)]
50pub enum OrderAny {
51 Limit(LimitOrder),
52 LimitIfTouched(LimitIfTouchedOrder),
53 Market(MarketOrder),
54 MarketIfTouched(MarketIfTouchedOrder),
55 MarketToLimit(MarketToLimitOrder),
56 StopLimit(StopLimitOrder),
57 StopMarket(StopMarketOrder),
58 TrailingStopLimit(TrailingStopLimitOrder),
59 TrailingStopMarket(TrailingStopMarketOrder),
60}
61
62impl Default for OrderAny {
63 fn default() -> Self {
64 Self::Limit(LimitOrder::default())
65 }
66}
67
68impl OrderAny {
69 pub fn apply(&mut self, event: OrderEventAny) -> Result<(), OrderError> {
71 match self {
72 OrderAny::Limit(order) => order.apply(event),
73 OrderAny::LimitIfTouched(order) => order.apply(event),
74 OrderAny::Market(order) => order.apply(event),
75 OrderAny::MarketIfTouched(order) => order.apply(event),
76 OrderAny::MarketToLimit(order) => order.apply(event),
77 OrderAny::StopLimit(order) => order.apply(event),
78 OrderAny::StopMarket(order) => order.apply(event),
79 OrderAny::TrailingStopLimit(order) => order.apply(event),
80 OrderAny::TrailingStopMarket(order) => order.apply(event),
81 }
82 }
83
84 #[must_use]
85 pub fn from_limit(order: LimitOrder) -> Self {
86 Self::Limit(order)
87 }
88
89 #[must_use]
90 pub fn from_limit_if_touched(order: LimitIfTouchedOrder) -> Self {
91 Self::LimitIfTouched(order)
92 }
93
94 #[must_use]
95 pub fn from_market(order: MarketOrder) -> Self {
96 Self::Market(order)
97 }
98
99 #[must_use]
100 pub fn from_market_if_touched(order: MarketIfTouchedOrder) -> Self {
101 Self::MarketIfTouched(order)
102 }
103
104 #[must_use]
105 pub fn from_market_to_limit(order: MarketToLimitOrder) -> Self {
106 Self::MarketToLimit(order)
107 }
108
109 #[must_use]
110 pub fn from_stop_limit(order: StopLimitOrder) -> Self {
111 Self::StopLimit(order)
112 }
113
114 #[must_use]
115 pub fn from_stop_market(order: StopMarketOrder) -> Self {
116 Self::StopMarket(order)
117 }
118
119 #[must_use]
120 pub fn from_trailing_stop_limit(order: StopLimitOrder) -> Self {
121 Self::StopLimit(order)
122 }
123
124 #[must_use]
125 pub fn from_trailing_stop_market(order: StopMarketOrder) -> Self {
126 Self::StopMarket(order)
127 }
128
129 pub fn from_events(events: Vec<OrderEventAny>) -> anyhow::Result<Self> {
130 if events.is_empty() {
131 anyhow::bail!("No order events provided to create OrderAny");
132 }
133
134 let init_event = events.first().unwrap();
136 match init_event {
137 OrderEventAny::Initialized(init) => {
138 let mut order = Self::from(init.clone());
139 for event in events.into_iter().skip(1) {
141 println!("Applying event: {:?}", event);
143 order.apply(event).unwrap();
144 }
145 Ok(order)
146 }
147 _ => {
148 anyhow::bail!("First event must be `OrderInitialized`");
149 }
150 }
151 }
152
153 pub fn events(&self) -> Vec<&OrderEventAny> {
154 match self {
155 Self::Limit(order) => order.events(),
156 Self::LimitIfTouched(order) => order.events(),
157 Self::Market(order) => order.events(),
158 Self::MarketIfTouched(order) => order.events(),
159 Self::MarketToLimit(order) => order.events(),
160 Self::StopLimit(order) => order.events(),
161 Self::StopMarket(order) => order.events(),
162 Self::TrailingStopLimit(order) => order.events(),
163 Self::TrailingStopMarket(order) => order.events(),
164 }
165 }
166
167 #[must_use]
168 pub fn last_event(&self) -> &OrderEventAny {
169 match self {
170 Self::Limit(order) => order.last_event(),
171 Self::LimitIfTouched(order) => order.last_event(),
172 Self::Market(order) => order.last_event(),
173 Self::MarketIfTouched(order) => order.last_event(),
174 Self::MarketToLimit(order) => order.last_event(),
175 Self::StopLimit(order) => order.last_event(),
176 Self::StopMarket(order) => order.last_event(),
177 Self::TrailingStopLimit(order) => order.last_event(),
178 Self::TrailingStopMarket(order) => order.last_event(),
179 }
180 }
181
182 #[must_use]
183 pub fn trader_id(&self) -> TraderId {
184 match self {
185 Self::Limit(order) => order.trader_id,
186 Self::LimitIfTouched(order) => order.trader_id,
187 Self::Market(order) => order.trader_id,
188 Self::MarketIfTouched(order) => order.trader_id,
189 Self::MarketToLimit(order) => order.trader_id,
190 Self::StopLimit(order) => order.trader_id,
191 Self::StopMarket(order) => order.trader_id,
192 Self::TrailingStopLimit(order) => order.trader_id,
193 Self::TrailingStopMarket(order) => order.trader_id,
194 }
195 }
196
197 #[must_use]
198 pub fn strategy_id(&self) -> StrategyId {
199 match self {
200 Self::Limit(order) => order.strategy_id,
201 Self::LimitIfTouched(order) => order.strategy_id,
202 Self::Market(order) => order.strategy_id,
203 Self::MarketIfTouched(order) => order.strategy_id,
204 Self::MarketToLimit(order) => order.strategy_id,
205 Self::StopLimit(order) => order.strategy_id,
206 Self::StopMarket(order) => order.strategy_id,
207 Self::TrailingStopLimit(order) => order.strategy_id,
208 Self::TrailingStopMarket(order) => order.strategy_id,
209 }
210 }
211
212 #[must_use]
213 pub fn instrument_id(&self) -> InstrumentId {
214 match self {
215 Self::Limit(order) => order.instrument_id,
216 Self::LimitIfTouched(order) => order.instrument_id,
217 Self::Market(order) => order.instrument_id,
218 Self::MarketIfTouched(order) => order.instrument_id,
219 Self::MarketToLimit(order) => order.instrument_id,
220 Self::StopLimit(order) => order.instrument_id,
221 Self::StopMarket(order) => order.instrument_id,
222 Self::TrailingStopLimit(order) => order.instrument_id,
223 Self::TrailingStopMarket(order) => order.instrument_id,
224 }
225 }
226
227 #[must_use]
228 pub fn client_order_id(&self) -> ClientOrderId {
229 match self {
230 Self::Limit(order) => order.client_order_id,
231 Self::LimitIfTouched(order) => order.client_order_id,
232 Self::Market(order) => order.client_order_id,
233 Self::MarketIfTouched(order) => order.client_order_id,
234 Self::MarketToLimit(order) => order.client_order_id,
235 Self::StopLimit(order) => order.client_order_id,
236 Self::StopMarket(order) => order.client_order_id,
237 Self::TrailingStopLimit(order) => order.client_order_id,
238 Self::TrailingStopMarket(order) => order.client_order_id,
239 }
240 }
241
242 #[must_use]
243 pub fn account_id(&self) -> Option<AccountId> {
244 match self {
245 Self::Limit(order) => order.account_id,
246 Self::LimitIfTouched(order) => order.account_id,
247 Self::Market(order) => order.account_id,
248 Self::MarketIfTouched(order) => order.account_id,
249 Self::MarketToLimit(order) => order.account_id,
250 Self::StopLimit(order) => order.account_id,
251 Self::StopMarket(order) => order.account_id,
252 Self::TrailingStopLimit(order) => order.account_id,
253 Self::TrailingStopMarket(order) => order.account_id,
254 }
255 }
256
257 #[must_use]
258 pub fn venue_order_id(&self) -> Option<VenueOrderId> {
259 match self {
260 Self::Limit(order) => order.venue_order_id,
261 Self::LimitIfTouched(order) => order.venue_order_id,
262 Self::Market(order) => order.venue_order_id,
263 Self::MarketIfTouched(order) => order.venue_order_id,
264 Self::MarketToLimit(order) => order.venue_order_id,
265 Self::StopLimit(order) => order.venue_order_id,
266 Self::StopMarket(order) => order.venue_order_id,
267 Self::TrailingStopLimit(order) => order.venue_order_id,
268 Self::TrailingStopMarket(order) => order.venue_order_id,
269 }
270 }
271
272 #[must_use]
273 pub fn position_id(&self) -> Option<PositionId> {
274 match self {
275 Self::Limit(order) => order.position_id,
276 Self::LimitIfTouched(order) => order.position_id,
277 Self::Market(order) => order.position_id,
278 Self::MarketIfTouched(order) => order.position_id,
279 Self::MarketToLimit(order) => order.position_id,
280 Self::StopLimit(order) => order.position_id,
281 Self::StopMarket(order) => order.position_id,
282 Self::TrailingStopLimit(order) => order.position_id,
283 Self::TrailingStopMarket(order) => order.position_id,
284 }
285 }
286
287 #[must_use]
288 pub fn order_list_id(&self) -> Option<OrderListId> {
289 match self {
290 Self::Limit(order) => order.order_list_id(),
291 Self::LimitIfTouched(order) => order.order_list_id(),
292 Self::Market(order) => order.order_list_id(),
293 Self::MarketIfTouched(order) => order.order_list_id(),
294 Self::MarketToLimit(order) => order.order_list_id(),
295 Self::StopLimit(order) => order.order_list_id(),
296 Self::StopMarket(order) => order.order_list_id(),
297 Self::TrailingStopLimit(order) => order.order_list_id(),
298 Self::TrailingStopMarket(order) => order.order_list_id(),
299 }
300 }
301
302 #[must_use]
303 pub fn last_trade_id(&self) -> Option<TradeId> {
304 match self {
305 Self::Limit(order) => order.last_trade_id,
306 Self::LimitIfTouched(order) => order.last_trade_id,
307 Self::Market(order) => order.last_trade_id,
308 Self::MarketIfTouched(order) => order.last_trade_id,
309 Self::MarketToLimit(order) => order.last_trade_id,
310 Self::StopLimit(order) => order.last_trade_id,
311 Self::StopMarket(order) => order.last_trade_id,
312 Self::TrailingStopLimit(order) => order.last_trade_id,
313 Self::TrailingStopMarket(order) => order.last_trade_id,
314 }
315 }
316
317 #[must_use]
318 pub fn init_id(&self) -> UUID4 {
319 match self {
320 Self::Limit(order) => order.init_id,
321 Self::LimitIfTouched(order) => order.init_id,
322 Self::Market(order) => order.init_id,
323 Self::MarketIfTouched(order) => order.init_id,
324 Self::MarketToLimit(order) => order.init_id,
325 Self::StopLimit(order) => order.init_id,
326 Self::StopMarket(order) => order.init_id,
327 Self::TrailingStopLimit(order) => order.init_id,
328 Self::TrailingStopMarket(order) => order.init_id,
329 }
330 }
331
332 #[must_use]
333 pub fn ts_init(&self) -> UnixNanos {
334 match self {
335 Self::Limit(order) => order.ts_init,
336 Self::LimitIfTouched(order) => order.ts_init,
337 Self::Market(order) => order.ts_init,
338 Self::MarketIfTouched(order) => order.ts_init,
339 Self::MarketToLimit(order) => order.ts_init,
340 Self::StopLimit(order) => order.ts_init,
341 Self::StopMarket(order) => order.ts_init,
342 Self::TrailingStopLimit(order) => order.ts_init,
343 Self::TrailingStopMarket(order) => order.ts_init,
344 }
345 }
346
347 #[must_use]
348 pub fn ts_last(&self) -> UnixNanos {
349 match self {
350 Self::Limit(order) => order.ts_last,
351 Self::LimitIfTouched(order) => order.ts_last,
352 Self::Market(order) => order.ts_last,
353 Self::MarketIfTouched(order) => order.ts_last,
354 Self::MarketToLimit(order) => order.ts_last,
355 Self::StopLimit(order) => order.ts_last,
356 Self::StopMarket(order) => order.ts_last,
357 Self::TrailingStopLimit(order) => order.ts_last,
358 Self::TrailingStopMarket(order) => order.ts_last,
359 }
360 }
361
362 #[must_use]
363 pub fn exec_algorithm_id(&self) -> Option<ExecAlgorithmId> {
364 match self {
365 Self::Limit(order) => order.exec_algorithm_id,
366 Self::LimitIfTouched(order) => order.exec_algorithm_id,
367 Self::Market(order) => order.exec_algorithm_id,
368 Self::MarketIfTouched(order) => order.exec_algorithm_id,
369 Self::MarketToLimit(order) => order.exec_algorithm_id,
370 Self::StopLimit(order) => order.exec_algorithm_id,
371 Self::StopMarket(order) => order.exec_algorithm_id,
372 Self::TrailingStopLimit(order) => order.exec_algorithm_id,
373 Self::TrailingStopMarket(order) => order.exec_algorithm_id,
374 }
375 }
376
377 #[must_use]
378 pub fn exec_algorithm_params(&self) -> Option<IndexMap<Ustr, Ustr>> {
379 match self {
380 Self::Limit(order) => order.exec_algorithm_params.clone(),
381 Self::LimitIfTouched(order) => order.exec_algorithm_params.clone(),
382 Self::Market(order) => order.exec_algorithm_params.clone(),
383 Self::MarketIfTouched(order) => order.exec_algorithm_params.clone(),
384 Self::MarketToLimit(order) => order.exec_algorithm_params.clone(),
385 Self::StopLimit(order) => order.exec_algorithm_params.clone(),
386 Self::StopMarket(order) => order.exec_algorithm_params.clone(),
387 Self::TrailingStopLimit(order) => order.exec_algorithm_params.clone(),
388 Self::TrailingStopMarket(order) => order.exec_algorithm_params.clone(),
389 }
390 }
391
392 #[must_use]
393 pub fn exec_spawn_id(&self) -> Option<ClientOrderId> {
394 match self {
395 Self::Limit(order) => order.exec_spawn_id,
396 Self::LimitIfTouched(order) => order.exec_spawn_id,
397 Self::Market(order) => order.exec_spawn_id,
398 Self::MarketIfTouched(order) => order.exec_spawn_id,
399 Self::MarketToLimit(order) => order.exec_spawn_id,
400 Self::StopLimit(order) => order.exec_spawn_id,
401 Self::StopMarket(order) => order.exec_spawn_id,
402 Self::TrailingStopLimit(order) => order.exec_spawn_id,
403 Self::TrailingStopMarket(order) => order.exec_spawn_id,
404 }
405 }
406
407 #[must_use]
408 pub fn order_side(&self) -> OrderSide {
409 match self {
410 Self::Limit(order) => order.side,
411 Self::LimitIfTouched(order) => order.side,
412 Self::Market(order) => order.side,
413 Self::MarketIfTouched(order) => order.side,
414 Self::MarketToLimit(order) => order.side,
415 Self::StopLimit(order) => order.side,
416 Self::StopMarket(order) => order.side,
417 Self::TrailingStopLimit(order) => order.side,
418 Self::TrailingStopMarket(order) => order.side,
419 }
420 }
421
422 #[must_use]
423 pub fn order_side_specified(&self) -> OrderSideSpecified {
424 match self {
425 Self::Limit(order) => order.side.as_specified(),
426 Self::LimitIfTouched(order) => order.side.as_specified(),
427 Self::Market(order) => order.side.as_specified(),
428 Self::MarketIfTouched(order) => order.side.as_specified(),
429 Self::MarketToLimit(order) => order.side.as_specified(),
430 Self::StopLimit(order) => order.side.as_specified(),
431 Self::StopMarket(order) => order.side.as_specified(),
432 Self::TrailingStopLimit(order) => order.side.as_specified(),
433 Self::TrailingStopMarket(order) => order.side.as_specified(),
434 }
435 }
436
437 #[must_use]
438 pub fn order_type(&self) -> OrderType {
439 match self {
440 Self::Limit(order) => order.order_type,
441 Self::LimitIfTouched(order) => order.order_type,
442 Self::Market(order) => order.order_type,
443 Self::MarketIfTouched(order) => order.order_type,
444 Self::MarketToLimit(order) => order.order_type,
445 Self::StopLimit(order) => order.order_type,
446 Self::StopMarket(order) => order.order_type,
447 Self::TrailingStopLimit(order) => order.order_type,
448 Self::TrailingStopMarket(order) => order.order_type,
449 }
450 }
451
452 #[must_use]
453 pub fn quantity(&self) -> Quantity {
454 match self {
455 Self::Limit(order) => order.quantity,
456 Self::LimitIfTouched(order) => order.quantity,
457 Self::Market(order) => order.quantity,
458 Self::MarketIfTouched(order) => order.quantity,
459 Self::MarketToLimit(order) => order.quantity,
460 Self::StopLimit(order) => order.quantity,
461 Self::StopMarket(order) => order.quantity,
462 Self::TrailingStopLimit(order) => order.quantity,
463 Self::TrailingStopMarket(order) => order.quantity,
464 }
465 }
466
467 #[must_use]
468 pub fn liquidity_side(&self) -> Option<LiquiditySide> {
469 match self {
470 Self::Limit(order) => order.liquidity_side,
471 Self::LimitIfTouched(order) => order.liquidity_side,
472 Self::Market(order) => order.liquidity_side,
473 Self::MarketIfTouched(order) => order.liquidity_side,
474 Self::MarketToLimit(order) => order.liquidity_side,
475 Self::StopLimit(order) => order.liquidity_side,
476 Self::StopMarket(order) => order.liquidity_side,
477 Self::TrailingStopLimit(order) => order.liquidity_side,
478 Self::TrailingStopMarket(order) => order.liquidity_side,
479 }
480 }
481
482 #[must_use]
483 pub fn time_in_force(&self) -> TimeInForce {
484 match self {
485 Self::Limit(order) => order.time_in_force,
486 Self::LimitIfTouched(order) => order.time_in_force,
487 Self::Market(order) => order.time_in_force,
488 Self::MarketIfTouched(order) => order.time_in_force,
489 Self::MarketToLimit(order) => order.time_in_force,
490 Self::StopLimit(order) => order.time_in_force,
491 Self::StopMarket(order) => order.time_in_force,
492 Self::TrailingStopLimit(order) => order.time_in_force,
493 Self::TrailingStopMarket(order) => order.time_in_force,
494 }
495 }
496
497 #[must_use]
498 pub fn expire_time(&self) -> Option<UnixNanos> {
499 match self {
500 Self::Limit(order) => order.expire_time,
501 Self::LimitIfTouched(order) => order.expire_time,
502 Self::Market(_) => None,
503 Self::MarketIfTouched(order) => order.expire_time,
504 Self::MarketToLimit(order) => order.expire_time,
505 Self::StopLimit(order) => order.expire_time,
506 Self::StopMarket(order) => order.expire_time,
507 Self::TrailingStopLimit(order) => order.expire_time,
508 Self::TrailingStopMarket(order) => order.expire_time,
509 }
510 }
511
512 #[must_use]
513 pub fn status(&self) -> OrderStatus {
514 match self {
515 Self::Limit(order) => order.status,
516 Self::LimitIfTouched(order) => order.status,
517 Self::Market(order) => order.status,
518 Self::MarketIfTouched(order) => order.status,
519 Self::MarketToLimit(order) => order.status,
520 Self::StopLimit(order) => order.status,
521 Self::StopMarket(order) => order.status,
522 Self::TrailingStopLimit(order) => order.status,
523 Self::TrailingStopMarket(order) => order.status,
524 }
525 }
526
527 #[must_use]
528 pub fn filled_qty(&self) -> Quantity {
529 match self {
530 Self::Limit(order) => order.filled_qty(),
531 Self::LimitIfTouched(order) => order.filled_qty(),
532 Self::Market(order) => order.filled_qty(),
533 Self::MarketIfTouched(order) => order.filled_qty(),
534 Self::MarketToLimit(order) => order.filled_qty(),
535 Self::StopLimit(order) => order.filled_qty(),
536 Self::StopMarket(order) => order.filled_qty(),
537 Self::TrailingStopLimit(order) => order.filled_qty(),
538 Self::TrailingStopMarket(order) => order.filled_qty(),
539 }
540 }
541
542 #[must_use]
543 pub fn leaves_qty(&self) -> Quantity {
544 match self {
545 Self::Limit(order) => order.leaves_qty(),
546 Self::LimitIfTouched(order) => order.leaves_qty(),
547 Self::Market(order) => order.leaves_qty(),
548 Self::MarketIfTouched(order) => order.leaves_qty(),
549 Self::MarketToLimit(order) => order.leaves_qty(),
550 Self::StopLimit(order) => order.leaves_qty(),
551 Self::StopMarket(order) => order.leaves_qty(),
552 Self::TrailingStopLimit(order) => order.leaves_qty(),
553 Self::TrailingStopMarket(order) => order.leaves_qty(),
554 }
555 }
556
557 #[must_use]
558 pub fn tags(&self) -> Option<Vec<Ustr>> {
559 match self {
560 Self::Limit(order) => order.tags.clone(),
561 Self::LimitIfTouched(order) => order.tags.clone(),
562 Self::Market(order) => order.tags.clone(),
563 Self::MarketIfTouched(order) => order.tags.clone(),
564 Self::MarketToLimit(order) => order.tags.clone(),
565 Self::StopLimit(order) => order.tags.clone(),
566 Self::StopMarket(order) => order.tags.clone(),
567 Self::TrailingStopLimit(order) => order.tags.clone(),
568 Self::TrailingStopMarket(order) => order.tags.clone(),
569 }
570 }
571
572 #[must_use]
573 pub fn emulation_trigger(&self) -> Option<TriggerType> {
574 match self {
575 Self::Limit(order) => order.emulation_trigger,
576 Self::LimitIfTouched(order) => order.emulation_trigger,
577 Self::Market(order) => order.emulation_trigger,
578 Self::MarketIfTouched(order) => order.emulation_trigger,
579 Self::MarketToLimit(order) => order.emulation_trigger,
580 Self::StopLimit(order) => order.emulation_trigger,
581 Self::StopMarket(order) => order.emulation_trigger,
582 Self::TrailingStopLimit(order) => order.emulation_trigger,
583 Self::TrailingStopMarket(order) => order.emulation_trigger,
584 }
585 }
586
587 #[must_use]
588 pub fn trigger_instrument_id(&self) -> Option<InstrumentId> {
589 match self {
590 Self::Limit(order) => order.trigger_instrument_id(),
591 Self::LimitIfTouched(order) => order.trigger_instrument_id(),
592 Self::Market(order) => order.trigger_instrument_id(),
593 Self::MarketIfTouched(order) => order.trigger_instrument_id(),
594 Self::MarketToLimit(order) => order.trigger_instrument_id(),
595 Self::StopLimit(order) => order.trigger_instrument_id(),
596 Self::StopMarket(order) => order.trigger_instrument_id(),
597 Self::TrailingStopLimit(order) => order.trigger_instrument_id(),
598 Self::TrailingStopMarket(order) => order.trigger_instrument_id(),
599 }
600 }
601
602 #[must_use]
603 pub fn avg_px(&self) -> Option<f64> {
604 match self {
605 Self::Limit(order) => order.avg_px,
606 Self::LimitIfTouched(order) => order.avg_px,
607 Self::Market(order) => order.avg_px,
608 Self::MarketIfTouched(order) => order.avg_px,
609 Self::MarketToLimit(order) => order.avg_px,
610 Self::StopLimit(order) => order.avg_px,
611 Self::StopMarket(order) => order.avg_px,
612 Self::TrailingStopLimit(order) => order.avg_px,
613 Self::TrailingStopMarket(order) => order.avg_px,
614 }
615 }
616
617 #[must_use]
618 pub fn slippage(&self) -> Option<f64> {
619 match self {
620 Self::Limit(order) => order.slippage,
621 Self::LimitIfTouched(order) => order.slippage,
622 Self::Market(order) => order.slippage,
623 Self::MarketIfTouched(order) => order.slippage,
624 Self::MarketToLimit(order) => order.slippage,
625 Self::StopLimit(order) => order.slippage,
626 Self::StopMarket(order) => order.slippage,
627 Self::TrailingStopLimit(order) => order.slippage,
628 Self::TrailingStopMarket(order) => order.slippage,
629 }
630 }
631
632 #[must_use]
633 pub fn commissions(&self) -> IndexMap<Currency, Money> {
634 match self {
635 Self::Limit(order) => order.commissions.clone(),
636 Self::LimitIfTouched(order) => order.commissions.clone(),
637 Self::Market(order) => order.commissions.clone(),
638 Self::MarketIfTouched(order) => order.commissions.clone(),
639 Self::MarketToLimit(order) => order.commissions.clone(),
640 Self::StopLimit(order) => order.commissions.clone(),
641 Self::StopMarket(order) => order.commissions.clone(),
642 Self::TrailingStopLimit(order) => order.commissions.clone(),
643 Self::TrailingStopMarket(order) => order.commissions.clone(),
644 }
645 }
646
647 #[must_use]
648 pub fn display_qty(&self) -> Option<Quantity> {
649 match self {
650 Self::Limit(order) => order.display_qty(),
651 Self::LimitIfTouched(order) => order.display_qty(),
652 Self::Market(order) => order.display_qty(),
653 Self::MarketIfTouched(order) => order.display_qty(),
654 Self::MarketToLimit(order) => order.display_qty(),
655 Self::StopLimit(order) => order.display_qty(),
656 Self::StopMarket(order) => order.display_qty(),
657 Self::TrailingStopLimit(order) => order.display_qty(),
658 Self::TrailingStopMarket(order) => order.display_qty(),
659 }
660 }
661
662 #[must_use]
663 pub fn is_buy(&self) -> bool {
664 match self {
665 Self::Limit(order) => order.is_buy(),
666 Self::LimitIfTouched(order) => order.is_buy(),
667 Self::Market(order) => order.is_buy(),
668 Self::MarketIfTouched(order) => order.is_buy(),
669 Self::MarketToLimit(order) => order.is_buy(),
670 Self::StopLimit(order) => order.is_buy(),
671 Self::StopMarket(order) => order.is_buy(),
672 Self::TrailingStopLimit(order) => order.is_buy(),
673 Self::TrailingStopMarket(order) => order.is_buy(),
674 }
675 }
676
677 #[must_use]
678 pub fn is_sell(&self) -> bool {
679 match self {
680 Self::Limit(order) => order.is_sell(),
681 Self::LimitIfTouched(order) => order.is_sell(),
682 Self::Market(order) => order.is_sell(),
683 Self::MarketIfTouched(order) => order.is_sell(),
684 Self::MarketToLimit(order) => order.is_sell(),
685 Self::StopLimit(order) => order.is_sell(),
686 Self::StopMarket(order) => order.is_sell(),
687 Self::TrailingStopLimit(order) => order.is_sell(),
688 Self::TrailingStopMarket(order) => order.is_sell(),
689 }
690 }
691
692 #[must_use]
693 pub fn is_open(&self) -> bool {
694 match self {
695 Self::Limit(order) => order.is_open(),
696 Self::LimitIfTouched(order) => order.is_open(),
697 Self::Market(order) => order.is_open(),
698 Self::MarketIfTouched(order) => order.is_open(),
699 Self::MarketToLimit(order) => order.is_open(),
700 Self::StopLimit(order) => order.is_open(),
701 Self::StopMarket(order) => order.is_open(),
702 Self::TrailingStopLimit(order) => order.is_open(),
703 Self::TrailingStopMarket(order) => order.is_open(),
704 }
705 }
706
707 #[must_use]
708 pub fn is_closed(&self) -> bool {
709 match self {
710 Self::Limit(order) => order.is_closed(),
711 Self::LimitIfTouched(order) => order.is_closed(),
712 Self::Market(order) => order.is_closed(),
713 Self::MarketIfTouched(order) => order.is_closed(),
714 Self::MarketToLimit(order) => order.is_closed(),
715 Self::StopLimit(order) => order.is_closed(),
716 Self::StopMarket(order) => order.is_closed(),
717 Self::TrailingStopLimit(order) => order.is_closed(),
718 Self::TrailingStopMarket(order) => order.is_closed(),
719 }
720 }
721
722 #[must_use]
723 pub fn is_inflight(&self) -> bool {
724 match self {
725 Self::Limit(order) => order.is_inflight(),
726 Self::LimitIfTouched(order) => order.is_inflight(),
727 Self::Market(order) => order.is_inflight(),
728 Self::MarketIfTouched(order) => order.is_inflight(),
729 Self::MarketToLimit(order) => order.is_inflight(),
730 Self::StopLimit(order) => order.is_inflight(),
731 Self::StopMarket(order) => order.is_inflight(),
732 Self::TrailingStopLimit(order) => order.is_inflight(),
733 Self::TrailingStopMarket(order) => order.is_inflight(),
734 }
735 }
736
737 pub fn is_pending_cancel(&self) -> bool {
738 match self {
739 Self::Limit(order) => order.is_pending_cancel(),
740 Self::LimitIfTouched(order) => order.is_pending_cancel(),
741 Self::Market(order) => order.is_pending_cancel(),
742 Self::MarketIfTouched(order) => order.is_pending_cancel(),
743 Self::MarketToLimit(order) => order.is_pending_cancel(),
744 Self::StopLimit(order) => order.is_pending_cancel(),
745 Self::StopMarket(order) => order.is_pending_cancel(),
746 Self::TrailingStopLimit(order) => order.is_pending_cancel(),
747 Self::TrailingStopMarket(order) => order.is_pending_cancel(),
748 }
749 }
750
751 #[must_use]
752 pub fn is_aggressive(&self) -> bool {
753 match self {
754 Self::Limit(order) => order.is_aggressive(),
755 Self::LimitIfTouched(order) => order.is_aggressive(),
756 Self::Market(order) => order.is_aggressive(),
757 Self::MarketIfTouched(order) => order.is_aggressive(),
758 Self::MarketToLimit(order) => order.is_aggressive(),
759 Self::StopLimit(order) => order.is_aggressive(),
760 Self::StopMarket(order) => order.is_aggressive(),
761 Self::TrailingStopLimit(order) => order.is_aggressive(),
762 Self::TrailingStopMarket(order) => order.is_aggressive(),
763 }
764 }
765
766 pub fn is_passive(&self) -> bool {
767 match self {
768 OrderAny::Limit(order) => order.is_passive(),
769 OrderAny::LimitIfTouched(order) => order.is_passive(),
770 OrderAny::Market(order) => order.is_passive(),
771 OrderAny::MarketIfTouched(order) => order.is_passive(),
772 OrderAny::MarketToLimit(order) => order.is_passive(),
773 OrderAny::StopLimit(order) => order.is_passive(),
774 OrderAny::StopMarket(order) => order.is_passive(),
775 OrderAny::TrailingStopLimit(order) => order.is_passive(),
776 OrderAny::TrailingStopMarket(order) => order.is_passive(),
777 }
778 }
779
780 #[must_use]
781 pub fn price(&self) -> Option<Price> {
782 match self {
783 Self::Limit(order) => Some(order.price),
784 Self::LimitIfTouched(order) => Some(order.price),
785 Self::Market(_) => None,
786 Self::MarketIfTouched(_) => None,
787 Self::MarketToLimit(order) => order.price,
788 Self::StopLimit(order) => Some(order.price),
789 Self::StopMarket(_) => None,
790 Self::TrailingStopLimit(order) => Some(order.price),
791 Self::TrailingStopMarket(_) => None,
792 }
793 }
794
795 pub fn has_price(&self) -> bool {
796 match self {
797 Self::Limit(_) => true,
798 Self::LimitIfTouched(_) => true,
799 Self::Market(_) => false,
800 Self::MarketIfTouched(_) => false,
801 Self::MarketToLimit(order) => order.price.is_some(),
802 Self::StopLimit(_) => true,
803 Self::StopMarket(_) => false,
804 Self::TrailingStopLimit(_) => true,
805 Self::TrailingStopMarket(_) => false,
806 }
807 }
808
809 #[must_use]
810 pub fn trigger_price(&self) -> Option<Price> {
811 match self {
812 Self::Limit(_) => None,
813 Self::LimitIfTouched(order) => Some(order.trigger_price),
814 Self::Market(_) => None,
815 Self::MarketIfTouched(order) => Some(order.trigger_price),
816 Self::MarketToLimit(_) => None,
817 Self::StopLimit(order) => Some(order.trigger_price),
818 Self::StopMarket(order) => Some(order.trigger_price),
819 Self::TrailingStopLimit(order) => Some(order.trigger_price),
820 Self::TrailingStopMarket(order) => Some(order.trigger_price),
821 }
822 }
823
824 #[must_use]
825 pub fn trigger_type(&self) -> Option<TriggerType> {
826 match self {
827 Self::Limit(_) => None,
828 Self::LimitIfTouched(order) => Some(order.trigger_type),
829 Self::Market(_) => None,
830 Self::MarketIfTouched(order) => Some(order.trigger_type),
831 Self::MarketToLimit(_) => None,
832 Self::StopLimit(order) => Some(order.trigger_type),
833 Self::StopMarket(order) => Some(order.trigger_type),
834 Self::TrailingStopLimit(order) => Some(order.trigger_type),
835 Self::TrailingStopMarket(order) => Some(order.trigger_type),
836 }
837 }
838
839 #[must_use]
840 pub fn limit_offset(&self) -> Option<Decimal> {
841 match self {
842 Self::Limit(_) => None,
843 Self::LimitIfTouched(_) => None,
844 Self::Market(_) => None,
845 Self::MarketIfTouched(_) => None,
846 Self::MarketToLimit(_) => None,
847 Self::StopLimit(_) => None,
848 Self::StopMarket(_) => None,
849 Self::TrailingStopLimit(order) => Some(order.limit_offset),
850 Self::TrailingStopMarket(_) => None,
851 }
852 }
853
854 #[must_use]
855 pub fn trailing_offset(&self) -> Option<Decimal> {
856 match self {
857 Self::Limit(_) => None,
858 Self::LimitIfTouched(_) => None,
859 Self::Market(_) => None,
860 Self::MarketIfTouched(_) => None,
861 Self::MarketToLimit(_) => None,
862 Self::StopLimit(_) => None,
863 Self::StopMarket(_) => None,
864 Self::TrailingStopLimit(order) => Some(order.trailing_offset),
865 Self::TrailingStopMarket(order) => Some(order.trailing_offset),
866 }
867 }
868
869 #[must_use]
870 pub fn trailing_offset_type(&self) -> Option<TrailingOffsetType> {
871 match self {
872 Self::Limit(_) => None,
873 Self::LimitIfTouched(_) => None,
874 Self::Market(_) => None,
875 Self::MarketIfTouched(_) => None,
876 Self::MarketToLimit(_) => None,
877 Self::StopLimit(_) => None,
878 Self::StopMarket(_) => None,
879 Self::TrailingStopLimit(order) => Some(order.trailing_offset_type),
880 Self::TrailingStopMarket(order) => Some(order.trailing_offset_type),
881 }
882 }
883
884 #[must_use]
885 pub fn would_reduce_only(&self, side: PositionSide, position_qty: Quantity) -> bool {
886 match self {
887 Self::Limit(order) => order.would_reduce_only(side, position_qty),
888 Self::Market(order) => order.would_reduce_only(side, position_qty),
889 Self::MarketToLimit(order) => order.would_reduce_only(side, position_qty),
890 Self::LimitIfTouched(order) => order.would_reduce_only(side, position_qty),
891 Self::MarketIfTouched(order) => order.would_reduce_only(side, position_qty),
892 Self::StopLimit(order) => order.would_reduce_only(side, position_qty),
893 Self::StopMarket(order) => order.would_reduce_only(side, position_qty),
894 Self::TrailingStopLimit(order) => order.would_reduce_only(side, position_qty),
895 Self::TrailingStopMarket(order) => order.would_reduce_only(side, position_qty),
896 }
897 }
898
899 #[must_use]
900 pub fn is_post_only(&self) -> bool {
901 match self {
902 Self::Limit(order) => order.is_post_only,
903 Self::LimitIfTouched(order) => order.is_post_only,
904 Self::Market(_) => false,
905 Self::MarketIfTouched(_) => false,
906 Self::MarketToLimit(order) => order.is_post_only,
907 Self::StopLimit(order) => order.is_post_only,
908 Self::StopMarket(_) => false,
909 Self::TrailingStopLimit(order) => order.is_post_only,
910 Self::TrailingStopMarket(_) => false,
911 }
912 }
913
914 #[must_use]
915 pub fn is_reduce_only(&self) -> bool {
916 match self {
917 Self::Limit(order) => order.is_reduce_only,
918 Self::Market(order) => order.is_reduce_only,
919 Self::MarketToLimit(order) => order.is_reduce_only,
920 Self::LimitIfTouched(order) => order.is_reduce_only,
921 Self::MarketIfTouched(order) => order.is_reduce_only,
922 Self::StopLimit(order) => order.is_reduce_only,
923 Self::StopMarket(order) => order.is_reduce_only,
924 Self::TrailingStopLimit(order) => order.is_reduce_only,
925 Self::TrailingStopMarket(order) => order.is_reduce_only,
926 }
927 }
928
929 pub fn is_quote_quantity(&self) -> bool {
930 match self {
931 Self::Limit(order) => order.is_quote_quantity(),
932 Self::LimitIfTouched(order) => order.is_quote_quantity(),
933 Self::Market(order) => order.is_quote_quantity(),
934 Self::MarketIfTouched(order) => order.is_quote_quantity(),
935 Self::MarketToLimit(order) => order.is_quote_quantity(),
936 Self::StopLimit(order) => order.is_quote_quantity(),
937 Self::StopMarket(order) => order.is_quote_quantity(),
938 Self::TrailingStopLimit(order) => order.is_quote_quantity(),
939 Self::TrailingStopMarket(order) => order.is_quote_quantity(),
940 }
941 }
942
943 pub fn is_active_local(&self) -> bool {
944 matches!(
945 self.status(),
946 OrderStatus::Initialized | OrderStatus::Emulated | OrderStatus::Released
947 )
948 }
949
950 #[must_use]
951 pub fn parent_order_id(&self) -> Option<ClientOrderId> {
952 match self {
953 Self::Limit(order) => order.parent_order_id,
954 Self::LimitIfTouched(order) => order.parent_order_id,
955 Self::Market(order) => order.parent_order_id,
956 Self::MarketIfTouched(order) => order.parent_order_id,
957 Self::MarketToLimit(order) => order.parent_order_id,
958 Self::StopLimit(order) => order.parent_order_id,
959 Self::StopMarket(order) => order.parent_order_id,
960 Self::TrailingStopLimit(order) => order.parent_order_id,
961 Self::TrailingStopMarket(order) => order.parent_order_id,
962 }
963 }
964
965 #[must_use]
966 pub fn contingency_type(&self) -> Option<ContingencyType> {
967 match self {
968 Self::Limit(order) => order.contingency_type,
969 Self::LimitIfTouched(order) => order.contingency_type,
970 Self::Market(order) => order.contingency_type,
971 Self::MarketIfTouched(order) => order.contingency_type,
972 Self::MarketToLimit(order) => order.contingency_type,
973 Self::StopLimit(order) => order.contingency_type,
974 Self::StopMarket(order) => order.contingency_type,
975 Self::TrailingStopLimit(order) => order.contingency_type,
976 Self::TrailingStopMarket(order) => order.contingency_type,
977 }
978 }
979
980 #[must_use]
981 pub fn linked_order_ids(&self) -> Option<Vec<ClientOrderId>> {
982 match self {
983 Self::Limit(order) => order.linked_order_ids.clone(),
984 Self::LimitIfTouched(order) => order.linked_order_ids.clone(),
985 Self::Market(order) => order.linked_order_ids.clone(),
986 Self::MarketIfTouched(order) => order.linked_order_ids.clone(),
987 Self::MarketToLimit(order) => order.linked_order_ids.clone(),
988 Self::StopLimit(order) => order.linked_order_ids.clone(),
989 Self::StopMarket(order) => order.linked_order_ids.clone(),
990 Self::TrailingStopLimit(order) => order.linked_order_ids.clone(),
991 Self::TrailingStopMarket(order) => order.linked_order_ids.clone(),
992 }
993 }
994
995 pub fn set_position_id(&mut self, position_id: Option<PositionId>) {
996 match self {
997 Self::Limit(order) => order.position_id = position_id,
998 Self::LimitIfTouched(order) => order.position_id = position_id,
999 Self::Market(order) => order.position_id = position_id,
1000 Self::MarketIfTouched(order) => order.position_id = position_id,
1001 Self::MarketToLimit(order) => order.position_id = position_id,
1002 Self::StopLimit(order) => order.position_id = position_id,
1003 Self::StopMarket(order) => order.position_id = position_id,
1004 Self::TrailingStopLimit(order) => order.position_id = position_id,
1005 Self::TrailingStopMarket(order) => order.position_id = position_id,
1006 }
1007 }
1008
1009 pub fn set_quantity(&mut self, quantity: Quantity) {
1010 match self {
1011 Self::Limit(order) => order.quantity = quantity,
1012 Self::LimitIfTouched(order) => order.quantity = quantity,
1013 Self::Market(order) => order.quantity = quantity,
1014 Self::MarketIfTouched(order) => order.quantity = quantity,
1015 Self::MarketToLimit(order) => order.quantity = quantity,
1016 Self::StopLimit(order) => order.quantity = quantity,
1017 Self::StopMarket(order) => order.quantity = quantity,
1018 Self::TrailingStopLimit(order) => order.quantity = quantity,
1019 Self::TrailingStopMarket(order) => order.quantity = quantity,
1020 }
1021 }
1022
1023 pub fn set_leaves_qty(&mut self, leaves_qty: Quantity) {
1024 match self {
1025 Self::Limit(order) => order.leaves_qty = leaves_qty,
1026 Self::LimitIfTouched(order) => order.leaves_qty = leaves_qty,
1027 Self::Market(order) => order.leaves_qty = leaves_qty,
1028 Self::MarketIfTouched(order) => order.leaves_qty = leaves_qty,
1029 Self::MarketToLimit(order) => order.leaves_qty = leaves_qty,
1030 Self::StopLimit(order) => order.leaves_qty = leaves_qty,
1031 Self::StopMarket(order) => order.leaves_qty = leaves_qty,
1032 Self::TrailingStopLimit(order) => order.leaves_qty = leaves_qty,
1033 Self::TrailingStopMarket(order) => order.leaves_qty = leaves_qty,
1034 }
1035 }
1036
1037 pub fn set_emulation_trigger(&mut self, emulation_trigger: Option<TriggerType>) {
1038 match self {
1039 Self::Limit(order) => order.emulation_trigger = emulation_trigger,
1040 Self::LimitIfTouched(order) => order.emulation_trigger = emulation_trigger,
1041 Self::Market(order) => order.emulation_trigger = emulation_trigger,
1042 Self::MarketIfTouched(order) => order.emulation_trigger = emulation_trigger,
1043 Self::MarketToLimit(order) => order.emulation_trigger = emulation_trigger,
1044 Self::StopLimit(order) => order.emulation_trigger = emulation_trigger,
1045 Self::StopMarket(order) => order.emulation_trigger = emulation_trigger,
1046 Self::TrailingStopLimit(order) => order.emulation_trigger = emulation_trigger,
1047 Self::TrailingStopMarket(order) => order.emulation_trigger = emulation_trigger,
1048 };
1049 }
1050
1051 pub fn set_is_quote_quantity(&mut self, is_quote_quantity: bool) {
1052 match self {
1053 Self::Limit(order) => order.is_quote_quantity = is_quote_quantity,
1054 Self::LimitIfTouched(order) => order.is_quote_quantity = is_quote_quantity,
1055 Self::Market(order) => order.is_quote_quantity = is_quote_quantity,
1056 Self::MarketIfTouched(order) => order.is_quote_quantity = is_quote_quantity,
1057 Self::MarketToLimit(order) => order.is_quote_quantity = is_quote_quantity,
1058 Self::StopLimit(order) => order.is_quote_quantity = is_quote_quantity,
1059 Self::StopMarket(order) => order.is_quote_quantity = is_quote_quantity,
1060 Self::TrailingStopLimit(order) => order.is_quote_quantity = is_quote_quantity,
1061 Self::TrailingStopMarket(order) => order.is_quote_quantity = is_quote_quantity,
1062 }
1063 }
1064
1065 pub fn set_liquidity_side(&mut self, liquidity_side: LiquiditySide) {
1066 match self {
1067 Self::Limit(order) => order.liquidity_side = Some(liquidity_side),
1068 Self::LimitIfTouched(order) => order.liquidity_side = Some(liquidity_side),
1069 Self::Market(order) => order.liquidity_side = Some(liquidity_side),
1070 Self::MarketIfTouched(order) => order.liquidity_side = Some(liquidity_side),
1071 Self::MarketToLimit(order) => order.liquidity_side = Some(liquidity_side),
1072 Self::StopLimit(order) => order.liquidity_side = Some(liquidity_side),
1073 Self::StopMarket(order) => order.liquidity_side = Some(liquidity_side),
1074 Self::TrailingStopLimit(order) => order.liquidity_side = Some(liquidity_side),
1075 Self::TrailingStopMarket(order) => order.liquidity_side = Some(liquidity_side),
1076 }
1077 }
1078}
1079
1080impl PartialEq for OrderAny {
1081 fn eq(&self, other: &Self) -> bool {
1082 self.client_order_id() == other.client_order_id()
1083 }
1084}
1085
1086impl Eq for OrderAny {}
1088
1089impl Display for OrderAny {
1090 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1091 write!(
1092 f,
1093 "{}",
1094 match self {
1095 Self::Limit(order) => order.to_string(),
1096 Self::LimitIfTouched(order) => format!("{:?}", order), Self::Market(order) => order.to_string(),
1098 Self::MarketIfTouched(order) => format!("{:?}", order), Self::MarketToLimit(order) => format!("{:?}", order), Self::StopLimit(order) => order.to_string(),
1101 Self::StopMarket(order) => format!("{:?}", order), Self::TrailingStopLimit(order) => format!("{:?}", order), Self::TrailingStopMarket(order) => format!("{:?}", order), }
1105 )
1106 }
1107}
1108
1109impl From<OrderAny> for PassiveOrderAny {
1110 fn from(order: OrderAny) -> PassiveOrderAny {
1111 match order {
1112 OrderAny::Limit(_) => PassiveOrderAny::Limit(order.into()),
1113 OrderAny::LimitIfTouched(_) => PassiveOrderAny::Stop(order.into()),
1114 OrderAny::MarketIfTouched(_) => PassiveOrderAny::Stop(order.into()),
1115 OrderAny::StopLimit(_) => PassiveOrderAny::Stop(order.into()),
1116 OrderAny::StopMarket(_) => PassiveOrderAny::Stop(order.into()),
1117 OrderAny::TrailingStopLimit(_) => PassiveOrderAny::Stop(order.into()),
1118 OrderAny::TrailingStopMarket(_) => PassiveOrderAny::Stop(order.into()),
1119 _ => panic!("WIP: Implement trait bound to require `HasPrice`"),
1120 }
1121 }
1122}
1123
1124impl From<PassiveOrderAny> for OrderAny {
1125 fn from(order: PassiveOrderAny) -> OrderAny {
1126 match order {
1127 PassiveOrderAny::Limit(order) => order.into(),
1128 PassiveOrderAny::Stop(order) => order.into(),
1129 }
1130 }
1131}
1132
1133impl From<StopOrderAny> for PassiveOrderAny {
1134 fn from(order: StopOrderAny) -> PassiveOrderAny {
1135 match order {
1136 StopOrderAny::LimitIfTouched(_) => PassiveOrderAny::Stop(order),
1137 StopOrderAny::MarketIfTouched(_) => PassiveOrderAny::Stop(order),
1138 StopOrderAny::StopLimit(_) => PassiveOrderAny::Stop(order),
1139 StopOrderAny::StopMarket(_) => PassiveOrderAny::Stop(order),
1140 StopOrderAny::TrailingStopLimit(_) => PassiveOrderAny::Stop(order),
1141 StopOrderAny::TrailingStopMarket(_) => PassiveOrderAny::Stop(order),
1142 }
1143 }
1144}
1145
1146impl From<LimitOrderAny> for PassiveOrderAny {
1147 fn from(order: LimitOrderAny) -> PassiveOrderAny {
1148 match order {
1149 LimitOrderAny::Limit(_) => PassiveOrderAny::Limit(order),
1150 LimitOrderAny::MarketToLimit(_) => PassiveOrderAny::Limit(order),
1151 LimitOrderAny::StopLimit(_) => PassiveOrderAny::Limit(order),
1152 LimitOrderAny::TrailingStopLimit(_) => PassiveOrderAny::Limit(order),
1153 }
1154 }
1155}
1156
1157impl From<OrderAny> for StopOrderAny {
1158 fn from(order: OrderAny) -> StopOrderAny {
1159 match order {
1160 OrderAny::LimitIfTouched(order) => StopOrderAny::LimitIfTouched(order),
1161 OrderAny::MarketIfTouched(order) => StopOrderAny::MarketIfTouched(order),
1162 OrderAny::StopLimit(order) => StopOrderAny::StopLimit(order),
1163 OrderAny::StopMarket(order) => StopOrderAny::StopMarket(order),
1164 OrderAny::TrailingStopLimit(order) => StopOrderAny::TrailingStopLimit(order),
1165 OrderAny::TrailingStopMarket(order) => StopOrderAny::TrailingStopMarket(order),
1166 _ => panic!("WIP: Implement trait bound to require `HasStopPrice`"),
1167 }
1168 }
1169}
1170
1171impl From<StopOrderAny> for OrderAny {
1172 fn from(order: StopOrderAny) -> OrderAny {
1173 match order {
1174 StopOrderAny::LimitIfTouched(order) => OrderAny::LimitIfTouched(order),
1175 StopOrderAny::MarketIfTouched(order) => OrderAny::MarketIfTouched(order),
1176 StopOrderAny::StopLimit(order) => OrderAny::StopLimit(order),
1177 StopOrderAny::StopMarket(order) => OrderAny::StopMarket(order),
1178 StopOrderAny::TrailingStopLimit(order) => OrderAny::TrailingStopLimit(order),
1179 StopOrderAny::TrailingStopMarket(order) => OrderAny::TrailingStopMarket(order),
1180 }
1181 }
1182}
1183
1184impl From<OrderAny> for LimitOrderAny {
1185 fn from(order: OrderAny) -> LimitOrderAny {
1186 match order {
1187 OrderAny::Limit(order) => LimitOrderAny::Limit(order),
1188 OrderAny::MarketToLimit(order) => LimitOrderAny::MarketToLimit(order),
1189 OrderAny::StopLimit(order) => LimitOrderAny::StopLimit(order),
1190 OrderAny::TrailingStopLimit(order) => LimitOrderAny::TrailingStopLimit(order),
1191 _ => panic!("WIP: Implement trait bound to require `HasLimitPrice`"),
1192 }
1193 }
1194}
1195
1196impl From<LimitOrderAny> for OrderAny {
1197 fn from(order: LimitOrderAny) -> OrderAny {
1198 match order {
1199 LimitOrderAny::Limit(order) => OrderAny::Limit(order),
1200 LimitOrderAny::MarketToLimit(order) => OrderAny::MarketToLimit(order),
1201 LimitOrderAny::StopLimit(order) => OrderAny::StopLimit(order),
1202 LimitOrderAny::TrailingStopLimit(order) => OrderAny::TrailingStopLimit(order),
1203 }
1204 }
1205}
1206
1207impl AsRef<StopMarketOrder> for OrderAny {
1208 fn as_ref(&self) -> &StopMarketOrder {
1209 match self {
1210 OrderAny::StopMarket(ref order) => order,
1211 _ => panic!(
1212 "Invalid `OrderAny` not `{}`, was {self:?}",
1213 stringify!(StopMarketOrder),
1214 ),
1215 }
1216 }
1217}
1218
1219#[derive(Clone, Debug)]
1220pub enum PassiveOrderAny {
1221 Limit(LimitOrderAny),
1222 Stop(StopOrderAny),
1223}
1224
1225impl PassiveOrderAny {
1226 #[must_use]
1227 pub fn client_order_id(&self) -> ClientOrderId {
1228 match self {
1229 Self::Limit(order) => order.client_order_id(),
1230 Self::Stop(order) => order.client_order_id(),
1231 }
1232 }
1233
1234 #[must_use]
1235 pub fn order_side_specified(&self) -> OrderSideSpecified {
1236 match self {
1237 Self::Limit(order) => order.order_side_specified(),
1238 Self::Stop(order) => order.order_side_specified(),
1239 }
1240 }
1241
1242 #[must_use]
1243 pub fn is_closed(&self) -> bool {
1244 match self {
1245 Self::Limit(order) => order.is_closed(),
1246 Self::Stop(order) => order.is_closed(),
1247 }
1248 }
1249
1250 #[must_use]
1251 pub fn is_open(&self) -> bool {
1252 match self {
1253 Self::Limit(order) => order.is_open(),
1254 Self::Stop(order) => order.is_open(),
1255 }
1256 }
1257
1258 #[must_use]
1259 pub fn is_inflight(&self) -> bool {
1260 match self {
1261 Self::Limit(order) => order.is_inflight(),
1262 Self::Stop(order) => order.is_inflight(),
1263 }
1264 }
1265
1266 #[must_use]
1267 pub fn expire_time(&self) -> Option<UnixNanos> {
1268 match self {
1269 Self::Limit(order) => order.expire_time(),
1270 Self::Stop(order) => order.expire_time(),
1271 }
1272 }
1273
1274 #[must_use]
1275 pub fn contingency_type(&self) -> Option<ContingencyType> {
1276 match self {
1277 Self::Limit(order) => order.contingency_type(),
1278 Self::Stop(order) => order.contingency_type(),
1279 }
1280 }
1281
1282 #[must_use]
1283 pub fn to_any(&self) -> OrderAny {
1284 match self {
1285 Self::Limit(order) => order.clone().into(),
1286 Self::Stop(order) => order.clone().into(),
1287 }
1288 }
1289}
1290
1291impl PartialEq for PassiveOrderAny {
1292 fn eq(&self, rhs: &Self) -> bool {
1293 match self {
1294 Self::Limit(order) => order.client_order_id() == rhs.client_order_id(),
1295 Self::Stop(order) => order.client_order_id() == rhs.client_order_id(),
1296 }
1297 }
1298}
1299
1300#[derive(Clone, Debug)]
1301pub enum LimitOrderAny {
1302 Limit(LimitOrder),
1303 MarketToLimit(MarketToLimitOrder),
1304 StopLimit(StopLimitOrder),
1305 TrailingStopLimit(TrailingStopLimitOrder),
1306}
1307
1308impl LimitOrderAny {
1309 #[must_use]
1310 pub fn client_order_id(&self) -> ClientOrderId {
1311 match self {
1312 Self::Limit(order) => order.client_order_id,
1313 Self::MarketToLimit(order) => order.client_order_id,
1314 Self::StopLimit(order) => order.client_order_id,
1315 Self::TrailingStopLimit(order) => order.client_order_id,
1316 }
1317 }
1318
1319 #[must_use]
1320 pub fn order_side_specified(&self) -> OrderSideSpecified {
1321 match self {
1322 Self::Limit(order) => order.side.as_specified(),
1323 Self::MarketToLimit(order) => order.side.as_specified(),
1324 Self::StopLimit(order) => order.side.as_specified(),
1325 Self::TrailingStopLimit(order) => order.side.as_specified(),
1326 }
1327 }
1328
1329 #[must_use]
1330 pub fn limit_px(&self) -> Price {
1331 match self {
1332 Self::Limit(order) => order.price,
1333 Self::MarketToLimit(order) => order.price.expect("No price for order"), Self::StopLimit(order) => order.price,
1335 Self::TrailingStopLimit(order) => order.price,
1336 }
1337 }
1338
1339 #[must_use]
1340 pub fn is_closed(&self) -> bool {
1341 match self {
1342 Self::Limit(order) => order.is_closed(),
1343 Self::MarketToLimit(order) => order.is_closed(),
1344 Self::StopLimit(order) => order.is_closed(),
1345 Self::TrailingStopLimit(order) => order.is_closed(),
1346 }
1347 }
1348
1349 #[must_use]
1350 pub fn is_open(&self) -> bool {
1351 match self {
1352 Self::Limit(order) => order.is_open(),
1353 Self::MarketToLimit(order) => order.is_open(),
1354 Self::StopLimit(order) => order.is_open(),
1355 Self::TrailingStopLimit(order) => order.is_open(),
1356 }
1357 }
1358
1359 #[must_use]
1360 pub fn is_inflight(&self) -> bool {
1361 match self {
1362 Self::Limit(order) => order.is_inflight(),
1363 Self::MarketToLimit(order) => order.is_inflight(),
1364 Self::StopLimit(order) => order.is_inflight(),
1365 Self::TrailingStopLimit(order) => order.is_inflight(),
1366 }
1367 }
1368
1369 #[must_use]
1370 pub fn expire_time(&self) -> Option<UnixNanos> {
1371 match self {
1372 Self::Limit(order) => order.expire_time,
1373 Self::MarketToLimit(order) => order.expire_time,
1374 Self::StopLimit(order) => order.expire_time,
1375 Self::TrailingStopLimit(order) => order.expire_time,
1376 }
1377 }
1378
1379 #[must_use]
1380 pub fn contingency_type(&self) -> Option<ContingencyType> {
1381 match self {
1382 Self::Limit(order) => order.contingency_type,
1383 Self::MarketToLimit(order) => order.contingency_type,
1384 Self::StopLimit(order) => order.contingency_type,
1385 Self::TrailingStopLimit(order) => order.contingency_type,
1386 }
1387 }
1388}
1389
1390impl PartialEq for LimitOrderAny {
1391 fn eq(&self, rhs: &Self) -> bool {
1392 match self {
1393 Self::Limit(order) => order.client_order_id == rhs.client_order_id(),
1394 Self::MarketToLimit(order) => order.client_order_id == rhs.client_order_id(),
1395 Self::StopLimit(order) => order.client_order_id == rhs.client_order_id(),
1396 Self::TrailingStopLimit(order) => order.client_order_id == rhs.client_order_id(),
1397 }
1398 }
1399}
1400
1401#[derive(Clone, Debug)]
1402pub enum StopOrderAny {
1403 LimitIfTouched(LimitIfTouchedOrder),
1404 MarketIfTouched(MarketIfTouchedOrder),
1405 StopLimit(StopLimitOrder),
1406 StopMarket(StopMarketOrder),
1407 TrailingStopLimit(TrailingStopLimitOrder),
1408 TrailingStopMarket(TrailingStopMarketOrder),
1409}
1410
1411impl StopOrderAny {
1412 #[must_use]
1413 pub fn client_order_id(&self) -> ClientOrderId {
1414 match self {
1415 Self::LimitIfTouched(order) => order.client_order_id,
1416 Self::MarketIfTouched(order) => order.client_order_id,
1417 Self::StopLimit(order) => order.client_order_id,
1418 Self::StopMarket(order) => order.client_order_id,
1419 Self::TrailingStopLimit(order) => order.client_order_id,
1420 Self::TrailingStopMarket(order) => order.client_order_id,
1421 }
1422 }
1423
1424 #[must_use]
1425 pub fn order_side_specified(&self) -> OrderSideSpecified {
1426 match self {
1427 Self::LimitIfTouched(order) => order.side.as_specified(),
1428 Self::MarketIfTouched(order) => order.side.as_specified(),
1429 Self::StopLimit(order) => order.side.as_specified(),
1430 Self::StopMarket(order) => order.side.as_specified(),
1431 Self::TrailingStopLimit(order) => order.side.as_specified(),
1432 Self::TrailingStopMarket(order) => order.side.as_specified(),
1433 }
1434 }
1435
1436 #[must_use]
1437 pub fn stop_px(&self) -> Price {
1438 match self {
1439 Self::LimitIfTouched(order) => order.trigger_price,
1440 Self::MarketIfTouched(order) => order.trigger_price,
1441 Self::StopLimit(order) => order.trigger_price,
1442 Self::StopMarket(order) => order.trigger_price,
1443 Self::TrailingStopLimit(order) => order.trigger_price,
1444 Self::TrailingStopMarket(order) => order.trigger_price,
1445 }
1446 }
1447
1448 #[must_use]
1449 pub fn is_closed(&self) -> bool {
1450 match self {
1451 Self::LimitIfTouched(order) => order.is_closed(),
1452 Self::MarketIfTouched(order) => order.is_closed(),
1453 Self::StopLimit(order) => order.is_closed(),
1454 Self::StopMarket(order) => order.is_closed(),
1455 Self::TrailingStopLimit(order) => order.is_closed(),
1456 Self::TrailingStopMarket(order) => order.is_closed(),
1457 }
1458 }
1459
1460 #[must_use]
1461 pub fn is_open(&self) -> bool {
1462 match self {
1463 Self::LimitIfTouched(order) => order.is_open(),
1464 Self::MarketIfTouched(order) => order.is_open(),
1465 Self::StopLimit(order) => order.is_open(),
1466 Self::StopMarket(order) => order.is_open(),
1467 Self::TrailingStopLimit(order) => order.is_open(),
1468 Self::TrailingStopMarket(order) => order.is_open(),
1469 }
1470 }
1471
1472 #[must_use]
1473 pub fn is_inflight(&self) -> bool {
1474 match self {
1475 Self::LimitIfTouched(order) => order.is_inflight(),
1476 Self::MarketIfTouched(order) => order.is_inflight(),
1477 Self::StopLimit(order) => order.is_inflight(),
1478 Self::StopMarket(order) => order.is_inflight(),
1479 Self::TrailingStopLimit(order) => order.is_inflight(),
1480 Self::TrailingStopMarket(order) => order.is_inflight(),
1481 }
1482 }
1483
1484 #[must_use]
1485 pub fn expire_time(&self) -> Option<UnixNanos> {
1486 match self {
1487 Self::LimitIfTouched(order) => order.expire_time,
1488 Self::MarketIfTouched(order) => order.expire_time,
1489 Self::StopLimit(order) => order.expire_time,
1490 Self::StopMarket(order) => order.expire_time,
1491 Self::TrailingStopLimit(order) => order.expire_time,
1492 Self::TrailingStopMarket(order) => order.expire_time,
1493 }
1494 }
1495
1496 #[must_use]
1497 pub fn contingency_type(&self) -> Option<ContingencyType> {
1498 match self {
1499 Self::LimitIfTouched(order) => order.contingency_type,
1500 Self::MarketIfTouched(order) => order.contingency_type,
1501 Self::StopLimit(order) => order.contingency_type,
1502 Self::StopMarket(order) => order.contingency_type,
1503 Self::TrailingStopLimit(order) => order.contingency_type,
1504 Self::TrailingStopMarket(order) => order.contingency_type,
1505 }
1506 }
1507}
1508
1509impl PartialEq for StopOrderAny {
1510 fn eq(&self, rhs: &Self) -> bool {
1511 match self {
1512 Self::LimitIfTouched(order) => order.client_order_id == rhs.client_order_id(),
1513 Self::StopLimit(order) => order.client_order_id == rhs.client_order_id(),
1514 Self::StopMarket(order) => order.client_order_id == rhs.client_order_id(),
1515 Self::MarketIfTouched(order) => order.client_order_id == rhs.client_order_id(),
1516 Self::TrailingStopLimit(order) => order.client_order_id == rhs.client_order_id(),
1517 Self::TrailingStopMarket(order) => order.client_order_id == rhs.client_order_id(),
1518 }
1519 }
1520}