nautilus_execution/models/
latency.rs1use std::fmt::{Debug, Display};
17
18use nautilus_core::UnixNanos;
19
20pub trait LatencyModel: Debug {
25 fn get_insert_latency(&self) -> UnixNanos;
27
28 fn get_update_latency(&self) -> UnixNanos;
30
31 fn get_delete_latency(&self) -> UnixNanos;
33
34 fn get_base_latency(&self) -> UnixNanos;
36}
37
38#[derive(Debug, Clone)]
39pub enum LatencyModelAny {
40 Static(StaticLatencyModel),
41}
42
43impl LatencyModel for LatencyModelAny {
44 fn get_insert_latency(&self) -> UnixNanos {
45 match self {
46 Self::Static(model) => model.get_insert_latency(),
47 }
48 }
49
50 fn get_update_latency(&self) -> UnixNanos {
51 match self {
52 Self::Static(model) => model.get_update_latency(),
53 }
54 }
55
56 fn get_delete_latency(&self) -> UnixNanos {
57 match self {
58 Self::Static(model) => model.get_delete_latency(),
59 }
60 }
61
62 fn get_base_latency(&self) -> UnixNanos {
63 match self {
64 Self::Static(model) => model.get_base_latency(),
65 }
66 }
67}
68
69impl From<LatencyModelAny> for Box<dyn LatencyModel> {
70 fn from(value: LatencyModelAny) -> Self {
71 match value {
72 LatencyModelAny::Static(model) => Box::new(model),
73 }
74 }
75}
76
77#[derive(Debug, Clone)]
86#[cfg_attr(
87 feature = "python",
88 pyo3::pyclass(
89 module = "nautilus_trader.core.nautilus_pyo3.execution",
90 unsendable,
91 from_py_object
92 )
93)]
94#[cfg_attr(
95 feature = "python",
96 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.execution")
97)]
98pub struct StaticLatencyModel {
99 base_latency_nanos: UnixNanos,
100 insert_latency_nanos: UnixNanos,
101 update_latency_nanos: UnixNanos,
102 delete_latency_nanos: UnixNanos,
103}
104
105impl StaticLatencyModel {
106 #[must_use]
117 pub fn new(
118 base_latency_nanos: UnixNanos,
119 insert_latency_nanos: UnixNanos,
120 update_latency_nanos: UnixNanos,
121 delete_latency_nanos: UnixNanos,
122 ) -> Self {
123 Self {
124 base_latency_nanos,
125 insert_latency_nanos: UnixNanos::from(
126 base_latency_nanos.as_u64() + insert_latency_nanos.as_u64(),
127 ),
128 update_latency_nanos: UnixNanos::from(
129 base_latency_nanos.as_u64() + update_latency_nanos.as_u64(),
130 ),
131 delete_latency_nanos: UnixNanos::from(
132 base_latency_nanos.as_u64() + delete_latency_nanos.as_u64(),
133 ),
134 }
135 }
136}
137
138impl LatencyModel for StaticLatencyModel {
139 fn get_insert_latency(&self) -> UnixNanos {
140 self.insert_latency_nanos
141 }
142
143 fn get_update_latency(&self) -> UnixNanos {
144 self.update_latency_nanos
145 }
146
147 fn get_delete_latency(&self) -> UnixNanos {
148 self.delete_latency_nanos
149 }
150
151 fn get_base_latency(&self) -> UnixNanos {
152 self.base_latency_nanos
153 }
154}
155
156impl Display for StaticLatencyModel {
157 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158 write!(f, "LatencyModel()")
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use rstest::rstest;
165
166 use super::*;
167
168 #[rstest]
169 fn test_static_latency_model() {
170 let model = StaticLatencyModel::new(
171 UnixNanos::from(1_000_000),
172 UnixNanos::from(2_000_000),
173 UnixNanos::from(3_000_000),
174 UnixNanos::from(4_000_000),
175 );
176
177 assert_eq!(model.get_insert_latency().as_u64(), 3_000_000);
179 assert_eq!(model.get_update_latency().as_u64(), 4_000_000);
180 assert_eq!(model.get_delete_latency().as_u64(), 5_000_000);
181 assert_eq!(model.get_base_latency().as_u64(), 1_000_000);
182 }
183}