nautilus_model/events/order/spec/
canceled.rs1use nautilus_core::{UUID4, UnixNanos};
17
18use crate::{
19 events::OrderCanceled,
20 identifiers::{AccountId, ClientOrderId, InstrumentId, StrategyId, TraderId, VenueOrderId},
21 stubs::{TestDefault, test_uuid},
22};
23
24#[derive(Debug, Clone, bon::Builder)]
30#[builder(finish_fn = into_spec)]
31pub struct OrderCanceledSpec {
32 #[builder(default = TraderId::test_default())]
33 pub trader_id: TraderId,
34 #[builder(default = StrategyId::test_default())]
35 pub strategy_id: StrategyId,
36 #[builder(default = InstrumentId::test_default())]
37 pub instrument_id: InstrumentId,
38 #[builder(default = ClientOrderId::test_default())]
39 pub client_order_id: ClientOrderId,
40 #[builder(default = test_uuid())]
41 pub event_id: UUID4,
42 #[builder(default = UnixNanos::default())]
43 pub ts_event: UnixNanos,
44 #[builder(default = UnixNanos::default())]
45 pub ts_init: UnixNanos,
46 #[builder(default = false)]
47 pub reconciliation: bool,
48 pub venue_order_id: Option<VenueOrderId>,
49 pub account_id: Option<AccountId>,
50}
51
52impl<S: order_canceled_spec_builder::IsComplete> OrderCanceledSpecBuilder<S> {
53 #[must_use]
55 pub fn build(self) -> OrderCanceled {
56 let spec = self.into_spec();
57 OrderCanceled::new(
58 spec.trader_id,
59 spec.strategy_id,
60 spec.instrument_id,
61 spec.client_order_id,
62 spec.event_id,
63 spec.ts_event,
64 spec.ts_init,
65 spec.reconciliation,
66 spec.venue_order_id,
67 spec.account_id,
68 )
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use rstest::rstest;
75
76 use super::*;
77 use crate::stubs::reset_test_uuid_rng;
78
79 #[rstest]
80 fn defaults_are_sensible() {
81 let event = OrderCanceledSpec::builder().build();
84 assert_eq!(event.trader_id, TraderId::test_default());
85 assert_eq!(event.strategy_id, StrategyId::test_default());
86 assert_eq!(event.instrument_id, InstrumentId::test_default());
87 assert_eq!(event.client_order_id, ClientOrderId::test_default());
88 assert_eq!(event.ts_event, UnixNanos::default());
89 assert_eq!(event.ts_init, UnixNanos::default());
90 assert_eq!(event.reconciliation, 0);
91 assert_eq!(event.venue_order_id, None);
92 assert_eq!(event.account_id, None);
93 }
94
95 #[rstest]
96 fn overrides_apply_through_constructor() {
97 let event = OrderCanceledSpec::builder()
98 .venue_order_id(VenueOrderId::from("V-1"))
99 .account_id(AccountId::from("SIM-002"))
100 .reconciliation(true)
101 .build();
102
103 assert_eq!(event.venue_order_id, Some(VenueOrderId::from("V-1")));
104 assert_eq!(event.account_id, Some(AccountId::from("SIM-002")));
105 assert_eq!(event.reconciliation, 1);
107 assert_eq!(event.trader_id, TraderId::test_default());
108 }
109
110 #[rstest]
111 fn event_ids_are_unique_within_a_run() {
112 reset_test_uuid_rng();
113 let a = OrderCanceledSpec::builder().build();
114 let b = OrderCanceledSpec::builder().build();
115 let c = OrderCanceledSpec::builder().build();
116 assert_ne!(a.event_id, b.event_id);
117 assert_ne!(b.event_id, c.event_id);
118 assert_ne!(a.event_id, c.event_id);
119 }
120
121 #[rstest]
122 fn event_id_sequence_is_reproducible() {
123 reset_test_uuid_rng();
125 let first_run: Vec<_> = (0..3)
126 .map(|_| OrderCanceledSpec::builder().build().event_id)
127 .collect();
128
129 reset_test_uuid_rng();
130 let second_run: Vec<_> = (0..3)
131 .map(|_| OrderCanceledSpec::builder().build().event_id)
132 .collect();
133
134 assert_eq!(first_run, second_run);
135 }
136}