use std::fmt::{Debug, Display};
use nautilus_core::UnixNanos;
pub trait LatencyModel: Debug {
fn get_insert_latency(&self) -> UnixNanos;
fn get_update_latency(&self) -> UnixNanos;
fn get_delete_latency(&self) -> UnixNanos;
fn get_base_latency(&self) -> UnixNanos;
}
#[derive(Debug, Clone)]
pub enum LatencyModelAny {
Static(StaticLatencyModel),
}
impl LatencyModel for LatencyModelAny {
fn get_insert_latency(&self) -> UnixNanos {
match self {
Self::Static(model) => model.get_insert_latency(),
}
}
fn get_update_latency(&self) -> UnixNanos {
match self {
Self::Static(model) => model.get_update_latency(),
}
}
fn get_delete_latency(&self) -> UnixNanos {
match self {
Self::Static(model) => model.get_delete_latency(),
}
}
fn get_base_latency(&self) -> UnixNanos {
match self {
Self::Static(model) => model.get_base_latency(),
}
}
}
impl From<LatencyModelAny> for Box<dyn LatencyModel> {
fn from(value: LatencyModelAny) -> Self {
match value {
LatencyModelAny::Static(model) => Box::new(model),
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(
feature = "python",
pyo3::pyclass(
module = "nautilus_trader.core.nautilus_pyo3.execution",
unsendable,
from_py_object
)
)]
#[cfg_attr(
feature = "python",
pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.execution")
)]
pub struct StaticLatencyModel {
base_latency_nanos: UnixNanos,
insert_latency_nanos: UnixNanos,
update_latency_nanos: UnixNanos,
delete_latency_nanos: UnixNanos,
}
impl StaticLatencyModel {
#[must_use]
pub fn new(
base_latency_nanos: UnixNanos,
insert_latency_nanos: UnixNanos,
update_latency_nanos: UnixNanos,
delete_latency_nanos: UnixNanos,
) -> Self {
Self {
base_latency_nanos,
insert_latency_nanos: UnixNanos::from(
base_latency_nanos.as_u64() + insert_latency_nanos.as_u64(),
),
update_latency_nanos: UnixNanos::from(
base_latency_nanos.as_u64() + update_latency_nanos.as_u64(),
),
delete_latency_nanos: UnixNanos::from(
base_latency_nanos.as_u64() + delete_latency_nanos.as_u64(),
),
}
}
}
impl LatencyModel for StaticLatencyModel {
fn get_insert_latency(&self) -> UnixNanos {
self.insert_latency_nanos
}
fn get_update_latency(&self) -> UnixNanos {
self.update_latency_nanos
}
fn get_delete_latency(&self) -> UnixNanos {
self.delete_latency_nanos
}
fn get_base_latency(&self) -> UnixNanos {
self.base_latency_nanos
}
}
impl Display for StaticLatencyModel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "LatencyModel()")
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
fn test_static_latency_model() {
let model = StaticLatencyModel::new(
UnixNanos::from(1_000_000),
UnixNanos::from(2_000_000),
UnixNanos::from(3_000_000),
UnixNanos::from(4_000_000),
);
assert_eq!(model.get_insert_latency().as_u64(), 3_000_000);
assert_eq!(model.get_update_latency().as_u64(), 4_000_000);
assert_eq!(model.get_delete_latency().as_u64(), 5_000_000);
assert_eq!(model.get_base_latency().as_u64(), 1_000_000);
}
}