1use std::str::FromStr;
17
18use nautilus_core::{UUID4, UnixNanos};
19use rstest::fixture;
20use ustr::Ustr;
21
22use crate::{
23 enums::{ContingencyType, OrderSide, OrderType, TimeInForce, TriggerType},
24 events::{
25 OrderAccepted, OrderCancelRejected, OrderCanceled, OrderDenied, OrderEmulated,
26 OrderExpired, OrderFilled, OrderInitialized, OrderModifyRejected, OrderPendingCancel,
27 OrderPendingUpdate, OrderRejected, OrderReleased, OrderSubmitted, OrderTriggered,
28 OrderUpdated,
29 order::spec::{
30 OrderAcceptedSpec, OrderCancelRejectedSpec, OrderDeniedSpec, OrderEmulatedSpec,
31 OrderExpiredSpec, OrderFilledSpec, OrderInitializedSpec, OrderModifyRejectedSpec,
32 OrderPendingCancelSpec, OrderPendingUpdateSpec, OrderRejectedSpec, OrderReleasedSpec,
33 OrderSubmittedSpec, OrderTriggeredSpec, OrderUpdatedSpec,
34 },
35 },
36 identifiers::{
37 AccountId, ClientOrderId, InstrumentId, OrderListId, StrategyId, TraderId, VenueOrderId,
38 stubs as id_stubs,
39 },
40 stubs::TestDefault,
41 types::{Currency, Money, Price, Quantity},
42};
43
44#[fixture]
46pub fn trader_id() -> TraderId {
47 id_stubs::trader_id()
48}
49
50#[fixture]
51pub fn strategy_id_ema_cross() -> StrategyId {
52 id_stubs::strategy_id_ema_cross()
53}
54
55#[fixture]
56pub fn instrument_id_btc_usdt() -> InstrumentId {
57 id_stubs::instrument_id_btc_usdt()
58}
59
60#[fixture]
61pub fn client_order_id() -> ClientOrderId {
62 id_stubs::client_order_id()
63}
64
65#[fixture]
66pub fn venue_order_id() -> VenueOrderId {
67 id_stubs::venue_order_id()
68}
69
70#[fixture]
71pub fn account_id() -> AccountId {
72 id_stubs::account_id()
73}
74
75#[fixture]
76pub fn uuid4() -> UUID4 {
77 id_stubs::uuid4()
78}
79
80#[fixture]
81pub fn order_filled(
82 trader_id: TraderId,
83 strategy_id_ema_cross: StrategyId,
84 instrument_id_btc_usdt: InstrumentId,
85 client_order_id: ClientOrderId,
86 uuid4: UUID4,
87) -> OrderFilled {
88 OrderFilledSpec::builder()
89 .trader_id(trader_id)
90 .strategy_id(strategy_id_ema_cross)
91 .instrument_id(instrument_id_btc_usdt)
92 .client_order_id(client_order_id)
93 .venue_order_id(VenueOrderId::new("123456"))
94 .order_type(OrderType::Limit)
95 .last_qty(Quantity::from_str("0.561").unwrap())
96 .last_px(Price::from_str("22000").unwrap())
97 .currency(Currency::from_str("USDT").unwrap())
98 .event_id(uuid4)
99 .commission(Money::from("12.2 USDT"))
100 .build()
101}
102
103#[fixture]
104pub fn order_denied_max_submitted_rate(
105 trader_id: TraderId,
106 strategy_id_ema_cross: StrategyId,
107 instrument_id_btc_usdt: InstrumentId,
108 client_order_id: ClientOrderId,
109 uuid4: UUID4,
110) -> OrderDenied {
111 OrderDeniedSpec::builder()
112 .trader_id(trader_id)
113 .strategy_id(strategy_id_ema_cross)
114 .instrument_id(instrument_id_btc_usdt)
115 .client_order_id(client_order_id)
116 .reason(Ustr::from("RATE_LIMIT_EXCEEDED"))
117 .event_id(uuid4)
118 .build()
119}
120
121#[fixture]
122pub fn order_rejected_insufficient_margin(
123 trader_id: TraderId,
124 account_id: AccountId,
125 strategy_id_ema_cross: StrategyId,
126 instrument_id_btc_usdt: InstrumentId,
127 client_order_id: ClientOrderId,
128 uuid4: UUID4,
129) -> OrderRejected {
130 OrderRejectedSpec::builder()
131 .trader_id(trader_id)
132 .strategy_id(strategy_id_ema_cross)
133 .instrument_id(instrument_id_btc_usdt)
134 .client_order_id(client_order_id)
135 .account_id(account_id)
136 .reason(Ustr::from("INSUFFICIENT_MARGIN"))
137 .event_id(uuid4)
138 .build()
139}
140
141#[fixture]
142pub fn order_initialized_buy_limit(
143 trader_id: TraderId,
144 strategy_id_ema_cross: StrategyId,
145 instrument_id_btc_usdt: InstrumentId,
146 client_order_id: ClientOrderId,
147 uuid4: UUID4,
148) -> OrderInitialized {
149 let order_list_id = OrderListId::new("1");
150 let linked_order_ids = vec![ClientOrderId::new("O-2020872378424")];
151 OrderInitializedSpec::builder()
152 .trader_id(trader_id)
153 .strategy_id(strategy_id_ema_cross)
154 .instrument_id(instrument_id_btc_usdt)
155 .client_order_id(client_order_id)
156 .order_type(OrderType::Limit)
157 .quantity(Quantity::from_str("0.561").unwrap())
158 .post_only(true)
159 .reduce_only(true)
160 .event_id(uuid4)
161 .price(Price::from_str("22000").unwrap())
162 .emulation_trigger(TriggerType::BidAsk)
163 .trigger_instrument_id(instrument_id_btc_usdt)
164 .contingency_type(ContingencyType::Oto)
165 .order_list_id(order_list_id)
166 .linked_order_ids(linked_order_ids)
167 .build()
168}
169
170#[fixture]
171pub fn order_submitted(
172 trader_id: TraderId,
173 strategy_id_ema_cross: StrategyId,
174 instrument_id_btc_usdt: InstrumentId,
175 client_order_id: ClientOrderId,
176 account_id: AccountId,
177 uuid4: UUID4,
178) -> OrderSubmitted {
179 OrderSubmittedSpec::builder()
180 .trader_id(trader_id)
181 .strategy_id(strategy_id_ema_cross)
182 .instrument_id(instrument_id_btc_usdt)
183 .client_order_id(client_order_id)
184 .account_id(account_id)
185 .event_id(uuid4)
186 .build()
187}
188
189#[fixture]
190pub fn order_triggered(
191 trader_id: TraderId,
192 strategy_id_ema_cross: StrategyId,
193 instrument_id_btc_usdt: InstrumentId,
194 client_order_id: ClientOrderId,
195 venue_order_id: VenueOrderId,
196 account_id: AccountId,
197 uuid4: UUID4,
198) -> OrderTriggered {
199 OrderTriggeredSpec::builder()
200 .trader_id(trader_id)
201 .strategy_id(strategy_id_ema_cross)
202 .instrument_id(instrument_id_btc_usdt)
203 .client_order_id(client_order_id)
204 .event_id(uuid4)
205 .venue_order_id(venue_order_id)
206 .account_id(account_id)
207 .build()
208}
209
210#[fixture]
211pub fn order_emulated(
212 trader_id: TraderId,
213 strategy_id_ema_cross: StrategyId,
214 instrument_id_btc_usdt: InstrumentId,
215 client_order_id: ClientOrderId,
216 uuid4: UUID4,
217) -> OrderEmulated {
218 OrderEmulatedSpec::builder()
219 .trader_id(trader_id)
220 .strategy_id(strategy_id_ema_cross)
221 .instrument_id(instrument_id_btc_usdt)
222 .client_order_id(client_order_id)
223 .event_id(uuid4)
224 .build()
225}
226
227#[fixture]
228pub fn order_released(
229 trader_id: TraderId,
230 strategy_id_ema_cross: StrategyId,
231 instrument_id_btc_usdt: InstrumentId,
232 client_order_id: ClientOrderId,
233 uuid4: UUID4,
234) -> OrderReleased {
235 OrderReleasedSpec::builder()
236 .trader_id(trader_id)
237 .strategy_id(strategy_id_ema_cross)
238 .instrument_id(instrument_id_btc_usdt)
239 .client_order_id(client_order_id)
240 .released_price(Price::from_str("22000").unwrap())
241 .event_id(uuid4)
242 .build()
243}
244
245#[fixture]
246pub fn order_updated(
247 trader_id: TraderId,
248 strategy_id_ema_cross: StrategyId,
249 instrument_id_btc_usdt: InstrumentId,
250 client_order_id: ClientOrderId,
251 venue_order_id: VenueOrderId,
252 account_id: AccountId,
253 uuid4: UUID4,
254) -> OrderUpdated {
255 OrderUpdatedSpec::builder()
256 .trader_id(trader_id)
257 .strategy_id(strategy_id_ema_cross)
258 .instrument_id(instrument_id_btc_usdt)
259 .client_order_id(client_order_id)
260 .quantity(Quantity::from(100))
261 .event_id(uuid4)
262 .venue_order_id(venue_order_id)
263 .account_id(account_id)
264 .price(Price::from("22000"))
265 .build()
266}
267
268#[fixture]
269pub fn order_pending_update(
270 trader_id: TraderId,
271 strategy_id_ema_cross: StrategyId,
272 instrument_id_btc_usdt: InstrumentId,
273 client_order_id: ClientOrderId,
274 account_id: AccountId,
275 venue_order_id: VenueOrderId,
276 uuid4: UUID4,
277) -> OrderPendingUpdate {
278 OrderPendingUpdateSpec::builder()
279 .trader_id(trader_id)
280 .strategy_id(strategy_id_ema_cross)
281 .instrument_id(instrument_id_btc_usdt)
282 .client_order_id(client_order_id)
283 .account_id(account_id)
284 .event_id(uuid4)
285 .venue_order_id(venue_order_id)
286 .build()
287}
288
289#[fixture]
290pub fn order_pending_cancel(
291 trader_id: TraderId,
292 strategy_id_ema_cross: StrategyId,
293 instrument_id_btc_usdt: InstrumentId,
294 client_order_id: ClientOrderId,
295 account_id: AccountId,
296 venue_order_id: VenueOrderId,
297 uuid4: UUID4,
298) -> OrderPendingCancel {
299 OrderPendingCancelSpec::builder()
300 .trader_id(trader_id)
301 .strategy_id(strategy_id_ema_cross)
302 .instrument_id(instrument_id_btc_usdt)
303 .client_order_id(client_order_id)
304 .account_id(account_id)
305 .event_id(uuid4)
306 .venue_order_id(venue_order_id)
307 .build()
308}
309
310#[fixture]
311pub fn order_modify_rejected(
312 trader_id: TraderId,
313 strategy_id_ema_cross: StrategyId,
314 instrument_id_btc_usdt: InstrumentId,
315 client_order_id: ClientOrderId,
316 venue_order_id: VenueOrderId,
317 account_id: AccountId,
318 uuid4: UUID4,
319) -> OrderModifyRejected {
320 OrderModifyRejectedSpec::builder()
321 .trader_id(trader_id)
322 .strategy_id(strategy_id_ema_cross)
323 .instrument_id(instrument_id_btc_usdt)
324 .client_order_id(client_order_id)
325 .reason(Ustr::from("ORDER_DOES_NOT_EXIST"))
326 .event_id(uuid4)
327 .venue_order_id(venue_order_id)
328 .account_id(account_id)
329 .build()
330}
331
332#[fixture]
333pub fn order_accepted(
334 trader_id: TraderId,
335 strategy_id_ema_cross: StrategyId,
336 instrument_id_btc_usdt: InstrumentId,
337 client_order_id: ClientOrderId,
338 account_id: AccountId,
339 venue_order_id: VenueOrderId,
340 uuid4: UUID4,
341) -> OrderAccepted {
342 OrderAcceptedSpec::builder()
343 .trader_id(trader_id)
344 .strategy_id(strategy_id_ema_cross)
345 .instrument_id(instrument_id_btc_usdt)
346 .client_order_id(client_order_id)
347 .venue_order_id(venue_order_id)
348 .account_id(account_id)
349 .event_id(uuid4)
350 .build()
351}
352
353#[fixture]
354pub fn order_cancel_rejected(
355 trader_id: TraderId,
356 strategy_id_ema_cross: StrategyId,
357 instrument_id_btc_usdt: InstrumentId,
358 client_order_id: ClientOrderId,
359 venue_order_id: VenueOrderId,
360 account_id: AccountId,
361 uuid4: UUID4,
362) -> OrderCancelRejected {
363 OrderCancelRejectedSpec::builder()
364 .trader_id(trader_id)
365 .strategy_id(strategy_id_ema_cross)
366 .instrument_id(instrument_id_btc_usdt)
367 .client_order_id(client_order_id)
368 .reason(Ustr::from("ORDER_DOES_NOT_EXIST"))
369 .event_id(uuid4)
370 .venue_order_id(venue_order_id)
371 .account_id(account_id)
372 .build()
373}
374
375#[fixture]
376pub fn order_expired(
377 trader_id: TraderId,
378 strategy_id_ema_cross: StrategyId,
379 instrument_id_btc_usdt: InstrumentId,
380 client_order_id: ClientOrderId,
381 venue_order_id: VenueOrderId,
382 account_id: AccountId,
383 uuid4: UUID4,
384) -> OrderExpired {
385 OrderExpiredSpec::builder()
386 .trader_id(trader_id)
387 .strategy_id(strategy_id_ema_cross)
388 .instrument_id(instrument_id_btc_usdt)
389 .client_order_id(client_order_id)
390 .event_id(uuid4)
391 .venue_order_id(venue_order_id)
392 .account_id(account_id)
393 .build()
394}
395
396impl TestDefault for OrderAccepted {
400 fn test_default() -> Self {
401 Self {
402 trader_id: TraderId::test_default(),
403 strategy_id: StrategyId::test_default(),
404 instrument_id: InstrumentId::test_default(),
405 client_order_id: ClientOrderId::test_default(),
406 venue_order_id: VenueOrderId::test_default(),
407 account_id: AccountId::test_default(),
408 event_id: UUID4::default(),
409 ts_event: UnixNanos::default(),
410 ts_init: UnixNanos::default(),
411 reconciliation: false,
412 causation_id: None,
413 }
414 }
415}
416
417impl Default for OrderAccepted {
418 fn default() -> Self {
419 Self::test_default()
420 }
421}
422
423impl TestDefault for OrderCanceled {
424 fn test_default() -> Self {
425 Self {
426 trader_id: TraderId::test_default(),
427 strategy_id: StrategyId::test_default(),
428 instrument_id: InstrumentId::test_default(),
429 client_order_id: ClientOrderId::test_default(),
430 event_id: UUID4::default(),
431 ts_event: UnixNanos::default(),
432 ts_init: UnixNanos::default(),
433 reconciliation: false,
434 venue_order_id: None,
435 account_id: None,
436 causation_id: None,
437 }
438 }
439}
440
441impl Default for OrderCanceled {
442 fn default() -> Self {
443 Self::test_default()
444 }
445}
446
447impl TestDefault for OrderCancelRejected {
448 fn test_default() -> Self {
449 Self {
450 trader_id: TraderId::test_default(),
451 strategy_id: StrategyId::test_default(),
452 instrument_id: InstrumentId::test_default(),
453 client_order_id: ClientOrderId::test_default(),
454 reason: Ustr::from("TEST"),
455 event_id: UUID4::default(),
456 ts_event: UnixNanos::default(),
457 ts_init: UnixNanos::default(),
458 reconciliation: false,
459 venue_order_id: None,
460 account_id: None,
461 causation_id: None,
462 }
463 }
464}
465
466impl Default for OrderCancelRejected {
467 fn default() -> Self {
468 Self::test_default()
469 }
470}
471
472impl TestDefault for OrderDenied {
473 fn test_default() -> Self {
474 Self {
475 trader_id: TraderId::test_default(),
476 strategy_id: StrategyId::test_default(),
477 instrument_id: InstrumentId::test_default(),
478 client_order_id: ClientOrderId::test_default(),
479 reason: Ustr::from("TEST"),
480 event_id: UUID4::default(),
481 ts_event: UnixNanos::default(),
482 ts_init: UnixNanos::default(),
483 causation_id: None,
484 }
485 }
486}
487
488impl Default for OrderDenied {
489 fn default() -> Self {
490 Self::test_default()
491 }
492}
493
494impl TestDefault for OrderEmulated {
495 fn test_default() -> Self {
496 Self {
497 trader_id: TraderId::test_default(),
498 strategy_id: StrategyId::test_default(),
499 instrument_id: InstrumentId::test_default(),
500 client_order_id: ClientOrderId::test_default(),
501 event_id: UUID4::default(),
502 ts_event: UnixNanos::default(),
503 ts_init: UnixNanos::default(),
504 causation_id: None,
505 }
506 }
507}
508
509impl Default for OrderEmulated {
510 fn default() -> Self {
511 Self::test_default()
512 }
513}
514
515impl TestDefault for OrderExpired {
516 fn test_default() -> Self {
517 Self {
518 trader_id: TraderId::test_default(),
519 strategy_id: StrategyId::test_default(),
520 instrument_id: InstrumentId::test_default(),
521 client_order_id: ClientOrderId::test_default(),
522 event_id: UUID4::default(),
523 ts_event: UnixNanos::default(),
524 ts_init: UnixNanos::default(),
525 reconciliation: false,
526 venue_order_id: None,
527 account_id: None,
528 causation_id: None,
529 }
530 }
531}
532
533impl Default for OrderExpired {
534 fn default() -> Self {
535 Self::test_default()
536 }
537}
538
539impl TestDefault for OrderInitialized {
540 fn test_default() -> Self {
541 Self {
542 trader_id: TraderId::test_default(),
543 strategy_id: StrategyId::test_default(),
544 instrument_id: InstrumentId::test_default(),
545 client_order_id: ClientOrderId::test_default(),
546 order_side: OrderSide::Buy,
547 order_type: OrderType::Market,
548 quantity: Quantity::new(100_000.0, 0),
549 price: Option::default(),
550 trigger_price: Option::default(),
551 trigger_type: Option::default(),
552 time_in_force: TimeInForce::Day,
553 expire_time: Option::default(),
554 post_only: bool::default(),
555 reduce_only: bool::default(),
556 display_qty: Option::default(),
557 quote_quantity: bool::default(),
558 limit_offset: Option::default(),
559 trailing_offset: Option::default(),
560 trailing_offset_type: Option::default(),
561 emulation_trigger: Option::default(),
562 trigger_instrument_id: Option::default(),
563 contingency_type: Option::default(),
564 order_list_id: Option::default(),
565 linked_order_ids: Option::default(),
566 parent_order_id: Option::default(),
567 exec_algorithm_id: Option::default(),
568 exec_algorithm_params: Option::default(),
569 exec_spawn_id: Option::default(),
570 tags: Option::default(),
571 reconciliation: false,
572 event_id: UUID4::default(),
573 ts_event: UnixNanos::default(),
574 ts_init: UnixNanos::default(),
575 causation_id: None,
576 }
577 }
578}
579
580impl Default for OrderInitialized {
581 fn default() -> Self {
582 Self::test_default()
583 }
584}
585
586impl TestDefault for OrderModifyRejected {
587 fn test_default() -> Self {
588 Self {
589 trader_id: TraderId::test_default(),
590 strategy_id: StrategyId::test_default(),
591 instrument_id: InstrumentId::test_default(),
592 client_order_id: ClientOrderId::test_default(),
593 reason: Ustr::from("TEST"),
594 event_id: UUID4::default(),
595 ts_event: UnixNanos::default(),
596 ts_init: UnixNanos::default(),
597 reconciliation: false,
598 venue_order_id: None,
599 account_id: None,
600 causation_id: None,
601 }
602 }
603}
604
605impl Default for OrderModifyRejected {
606 fn default() -> Self {
607 Self::test_default()
608 }
609}
610
611impl TestDefault for OrderPendingCancel {
612 fn test_default() -> Self {
613 Self {
614 trader_id: TraderId::test_default(),
615 strategy_id: StrategyId::test_default(),
616 instrument_id: InstrumentId::test_default(),
617 client_order_id: ClientOrderId::test_default(),
618 event_id: UUID4::default(),
619 ts_event: UnixNanos::default(),
620 ts_init: UnixNanos::default(),
621 reconciliation: false,
622 venue_order_id: None,
623 account_id: AccountId::test_default(),
624 causation_id: None,
625 }
626 }
627}
628
629impl Default for OrderPendingCancel {
630 fn default() -> Self {
631 Self::test_default()
632 }
633}
634
635impl TestDefault for OrderPendingUpdate {
636 fn test_default() -> Self {
637 Self {
638 trader_id: TraderId::test_default(),
639 strategy_id: StrategyId::test_default(),
640 instrument_id: InstrumentId::test_default(),
641 client_order_id: ClientOrderId::test_default(),
642 event_id: UUID4::default(),
643 ts_event: UnixNanos::default(),
644 ts_init: UnixNanos::default(),
645 reconciliation: false,
646 venue_order_id: None,
647 account_id: AccountId::test_default(),
648 causation_id: None,
649 }
650 }
651}
652
653impl Default for OrderPendingUpdate {
654 fn default() -> Self {
655 Self::test_default()
656 }
657}
658
659impl TestDefault for OrderRejected {
660 fn test_default() -> Self {
661 Self {
662 trader_id: TraderId::test_default(),
663 strategy_id: StrategyId::test_default(),
664 instrument_id: InstrumentId::test_default(),
665 client_order_id: ClientOrderId::test_default(),
666 account_id: AccountId::test_default(),
667 reason: Ustr::from("TEST"),
668 event_id: UUID4::default(),
669 ts_event: UnixNanos::default(),
670 ts_init: UnixNanos::default(),
671 reconciliation: false,
672 due_post_only: false,
673 causation_id: None,
674 }
675 }
676}
677
678impl Default for OrderRejected {
679 fn default() -> Self {
680 Self::test_default()
681 }
682}
683
684impl TestDefault for OrderReleased {
685 fn test_default() -> Self {
686 Self {
687 trader_id: TraderId::test_default(),
688 strategy_id: StrategyId::test_default(),
689 instrument_id: InstrumentId::test_default(),
690 client_order_id: ClientOrderId::test_default(),
691 released_price: Price::from("1.00000"),
692 event_id: UUID4::default(),
693 ts_event: UnixNanos::default(),
694 ts_init: UnixNanos::default(),
695 causation_id: None,
696 }
697 }
698}
699
700impl Default for OrderReleased {
701 fn default() -> Self {
702 Self::test_default()
703 }
704}
705
706impl TestDefault for OrderSubmitted {
707 fn test_default() -> Self {
708 Self {
709 trader_id: TraderId::test_default(),
710 strategy_id: StrategyId::test_default(),
711 instrument_id: InstrumentId::test_default(),
712 client_order_id: ClientOrderId::test_default(),
713 account_id: AccountId::test_default(),
714 event_id: UUID4::default(),
715 ts_event: UnixNanos::default(),
716 ts_init: UnixNanos::default(),
717 causation_id: None,
718 }
719 }
720}
721
722impl Default for OrderSubmitted {
723 fn default() -> Self {
724 Self::test_default()
725 }
726}
727
728impl TestDefault for OrderTriggered {
729 fn test_default() -> Self {
730 Self {
731 trader_id: TraderId::test_default(),
732 strategy_id: StrategyId::test_default(),
733 instrument_id: InstrumentId::test_default(),
734 client_order_id: ClientOrderId::test_default(),
735 event_id: UUID4::default(),
736 ts_event: UnixNanos::default(),
737 ts_init: UnixNanos::default(),
738 reconciliation: false,
739 venue_order_id: None,
740 account_id: None,
741 causation_id: None,
742 }
743 }
744}
745
746impl Default for OrderTriggered {
747 fn default() -> Self {
748 Self::test_default()
749 }
750}
751
752impl TestDefault for OrderUpdated {
753 fn test_default() -> Self {
754 Self {
755 trader_id: TraderId::test_default(),
756 strategy_id: StrategyId::test_default(),
757 instrument_id: InstrumentId::test_default(),
758 client_order_id: ClientOrderId::test_default(),
759 venue_order_id: None,
760 account_id: None,
761 quantity: Quantity::new(100_000.0, 0),
762 price: None,
763 trigger_price: None,
764 protection_price: None,
765 is_quote_quantity: false,
766 event_id: UUID4::default(),
767 ts_event: UnixNanos::default(),
768 ts_init: UnixNanos::default(),
769 reconciliation: false,
770 causation_id: None,
771 }
772 }
773}
774
775impl Default for OrderUpdated {
776 fn default() -> Self {
777 Self::test_default()
778 }
779}