nautilus_model/events/order/spec/
submitted.rs1use nautilus_core::{UUID4, UnixNanos};
17
18use crate::{
19 events::OrderSubmitted,
20 identifiers::{AccountId, ClientOrderId, InstrumentId, StrategyId, TraderId},
21 stubs::{TestDefault, test_uuid},
22};
23
24#[derive(Debug, Clone, bon::Builder)]
30#[builder(finish_fn = into_spec)]
31pub struct OrderSubmittedSpec {
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 = AccountId::test_default())]
41 pub account_id: AccountId,
42 #[builder(default = test_uuid())]
43 pub event_id: UUID4,
44 #[builder(default = UnixNanos::default())]
45 pub ts_event: UnixNanos,
46 #[builder(default = UnixNanos::default())]
47 pub ts_init: UnixNanos,
48}
49
50impl<S: order_submitted_spec_builder::IsComplete> OrderSubmittedSpecBuilder<S> {
51 #[must_use]
53 pub fn build(self) -> OrderSubmitted {
54 let spec = self.into_spec();
55 OrderSubmitted::new(
56 spec.trader_id,
57 spec.strategy_id,
58 spec.instrument_id,
59 spec.client_order_id,
60 spec.account_id,
61 spec.event_id,
62 spec.ts_event,
63 spec.ts_init,
64 )
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use rstest::rstest;
71
72 use super::*;
73 use crate::stubs::reset_test_uuid_rng;
74
75 #[rstest]
76 fn defaults_are_sensible() {
77 let event = OrderSubmittedSpec::builder().build();
80 assert_eq!(event.trader_id, TraderId::test_default());
81 assert_eq!(event.strategy_id, StrategyId::test_default());
82 assert_eq!(event.instrument_id, InstrumentId::test_default());
83 assert_eq!(event.client_order_id, ClientOrderId::test_default());
84 assert_eq!(event.account_id, AccountId::test_default());
85 assert_eq!(event.ts_event, UnixNanos::default());
86 assert_eq!(event.ts_init, UnixNanos::default());
87 }
88
89 #[rstest]
90 fn overrides_apply_through_constructor() {
91 let event = OrderSubmittedSpec::builder()
92 .account_id(AccountId::from("SIM-002"))
93 .ts_event(UnixNanos::from(1_000))
94 .ts_init(UnixNanos::from(2_000))
95 .build();
96
97 assert_eq!(event.account_id, AccountId::from("SIM-002"));
98 assert_eq!(event.ts_event, UnixNanos::from(1_000));
99 assert_eq!(event.ts_init, UnixNanos::from(2_000));
100 assert_eq!(event.trader_id, TraderId::test_default());
101 }
102
103 #[rstest]
104 fn event_ids_are_unique_within_a_run() {
105 reset_test_uuid_rng();
106 let a = OrderSubmittedSpec::builder().build();
107 let b = OrderSubmittedSpec::builder().build();
108 let c = OrderSubmittedSpec::builder().build();
109 assert_ne!(a.event_id, b.event_id);
110 assert_ne!(b.event_id, c.event_id);
111 assert_ne!(a.event_id, c.event_id);
112 }
113
114 #[rstest]
115 fn event_id_sequence_is_reproducible() {
116 reset_test_uuid_rng();
118 let first_run: Vec<_> = (0..3)
119 .map(|_| OrderSubmittedSpec::builder().build().event_id)
120 .collect();
121
122 reset_test_uuid_rng();
123 let second_run: Vec<_> = (0..3)
124 .map(|_| OrderSubmittedSpec::builder().build().event_id)
125 .collect();
126
127 assert_eq!(first_run, second_run);
128 }
129}