nautilus_model/events/order/spec/
accepted.rs1use nautilus_core::{UUID4, UnixNanos};
17
18use crate::{
19 events::OrderAccepted,
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 OrderAcceptedSpec {
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 = VenueOrderId::test_default())]
41 pub venue_order_id: VenueOrderId,
42 #[builder(default = AccountId::test_default())]
43 pub account_id: AccountId,
44 #[builder(default = test_uuid())]
45 pub event_id: UUID4,
46 #[builder(default = UnixNanos::default())]
47 pub ts_event: UnixNanos,
48 #[builder(default = UnixNanos::default())]
49 pub ts_init: UnixNanos,
50 #[builder(default = false)]
51 pub reconciliation: bool,
52}
53
54impl<S: order_accepted_spec_builder::IsComplete> OrderAcceptedSpecBuilder<S> {
55 #[must_use]
57 pub fn build(self) -> OrderAccepted {
58 let spec = self.into_spec();
59 OrderAccepted::new(
60 spec.trader_id,
61 spec.strategy_id,
62 spec.instrument_id,
63 spec.client_order_id,
64 spec.venue_order_id,
65 spec.account_id,
66 spec.event_id,
67 spec.ts_event,
68 spec.ts_init,
69 spec.reconciliation,
70 )
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use rstest::rstest;
77
78 use super::*;
79 use crate::stubs::reset_test_uuid_rng;
80
81 #[rstest]
82 fn defaults_are_sensible() {
83 let event = OrderAcceptedSpec::builder().build();
86 assert_eq!(event.trader_id, TraderId::test_default());
87 assert_eq!(event.strategy_id, StrategyId::test_default());
88 assert_eq!(event.instrument_id, InstrumentId::test_default());
89 assert_eq!(event.client_order_id, ClientOrderId::test_default());
90 assert_eq!(event.venue_order_id, VenueOrderId::test_default());
91 assert_eq!(event.account_id, AccountId::test_default());
92 assert_eq!(event.ts_event, UnixNanos::default());
93 assert_eq!(event.ts_init, UnixNanos::default());
94 assert_eq!(event.reconciliation, 0);
95 }
96
97 #[rstest]
98 fn overrides_apply_through_constructor() {
99 let event = OrderAcceptedSpec::builder()
100 .venue_order_id(VenueOrderId::from("V-1"))
101 .reconciliation(true)
102 .build();
103
104 assert_eq!(event.venue_order_id, VenueOrderId::from("V-1"));
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 = OrderAcceptedSpec::builder().build();
114 let b = OrderAcceptedSpec::builder().build();
115 let c = OrderAcceptedSpec::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(|_| OrderAcceptedSpec::builder().build().event_id)
127 .collect();
128
129 reset_test_uuid_rng();
130 let second_run: Vec<_> = (0..3)
131 .map(|_| OrderAcceptedSpec::builder().build().event_id)
132 .collect();
133
134 assert_eq!(first_run, second_run);
135 }
136}