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