nautilus_common/generators/
client_order_id.rs1use nautilus_core::AtomicTime;
17use nautilus_model::identifiers::{ClientOrderId, StrategyId, TraderId};
18
19use super::get_datetime_tag;
20
21#[repr(C)]
22#[derive(Debug)]
23pub struct ClientOrderIdGenerator {
24 clock: &'static AtomicTime,
25 trader_id: TraderId,
26 strategy_id: StrategyId,
27 count: usize,
28}
29
30impl ClientOrderIdGenerator {
31 #[must_use]
33 pub const fn new(
34 trader_id: TraderId,
35 strategy_id: StrategyId,
36 initial_count: usize,
37 clock: &'static AtomicTime,
38 ) -> Self {
39 Self {
40 trader_id,
41 strategy_id,
42 count: initial_count,
43 clock,
44 }
45 }
46
47 pub const fn set_count(&mut self, count: usize) {
48 self.count = count;
49 }
50
51 pub const fn reset(&mut self) {
52 self.count = 0;
53 }
54
55 #[must_use]
56 pub const fn count(&self) -> usize {
57 self.count
58 }
59
60 pub fn generate(&mut self) -> ClientOrderId {
61 let datetime_tag = get_datetime_tag(self.clock.get_time_ms());
62 let trader_tag = self.trader_id.get_tag();
63 let strategy_tag = self.strategy_id.get_tag();
64 self.count += 1;
65 let value = format!(
66 "O-{}-{}-{}-{}",
67 datetime_tag, trader_tag, strategy_tag, self.count
68 );
69 ClientOrderId::from(value)
70 }
71}
72
73#[cfg(test)]
77mod tests {
78 use nautilus_core::time::get_atomic_clock_static;
79 use nautilus_model::identifiers::{ClientOrderId, StrategyId, TraderId};
80 use rstest::rstest;
81
82 use crate::generators::client_order_id::ClientOrderIdGenerator;
83
84 fn get_client_order_id_generator(initial_count: Option<usize>) -> ClientOrderIdGenerator {
85 ClientOrderIdGenerator::new(
86 TraderId::default(),
87 StrategyId::default(),
88 initial_count.unwrap_or(0),
89 get_atomic_clock_static(),
90 )
91 }
92
93 #[rstest]
94 fn test_init() {
95 let generator = get_client_order_id_generator(None);
96 assert_eq!(generator.count(), 0);
97 }
98
99 #[rstest]
100 fn test_init_with_initial_count() {
101 let generator = get_client_order_id_generator(Some(7));
102 assert_eq!(generator.count(), 7);
103 }
104
105 #[rstest]
106 fn test_generate_client_order_id_from_start() {
107 let mut generator = get_client_order_id_generator(None);
108 let result1 = generator.generate();
109 let result2 = generator.generate();
110 let result3 = generator.generate();
111
112 assert_eq!(result1, ClientOrderId::new("O-19700101-000000-001-001-1"));
113 assert_eq!(result2, ClientOrderId::new("O-19700101-000000-001-001-2"));
114 assert_eq!(result3, ClientOrderId::new("O-19700101-000000-001-001-3"));
115 }
116
117 #[rstest]
118 fn test_generate_client_order_id_from_initial() {
119 let mut generator = get_client_order_id_generator(Some(5));
120 let result1 = generator.generate();
121 let result2 = generator.generate();
122 let result3 = generator.generate();
123
124 assert_eq!(result1, ClientOrderId::new("O-19700101-000000-001-001-6"));
125 assert_eq!(result2, ClientOrderId::new("O-19700101-000000-001-001-7"));
126 assert_eq!(result3, ClientOrderId::new("O-19700101-000000-001-001-8"));
127 }
128
129 #[rstest]
130 fn test_reset() {
131 let mut generator = get_client_order_id_generator(None);
132 generator.generate();
133 generator.generate();
134 generator.reset();
135 let result = generator.generate();
136
137 assert_eq!(result, ClientOrderId::new("O-19700101-000000-001-001-1"));
138 }
139}