nautilus_model/python/data/
deltas.rs1use std::{
17 collections::hash_map::DefaultHasher,
18 hash::{Hash, Hasher},
19};
20
21use nautilus_core::python::{IntoPyObjectNautilusExt, serialization::to_dict_pyo3, to_pyvalue_err};
22use pyo3::{IntoPyObjectExt, prelude::*, pyclass::CompareOp, types::PyList};
23
24use crate::{
25 data::{OrderBookDelta, OrderBookDeltas},
26 identifiers::InstrumentId,
27 python::common::PY_MODULE_MODEL,
28};
29
30#[pymethods]
31#[pyo3_stub_gen::derive::gen_stub_pymethods]
32impl OrderBookDeltas {
33 #[new]
37 fn py_new(instrument_id: InstrumentId, deltas: Vec<OrderBookDelta>) -> PyResult<Self> {
38 Self::new_checked(instrument_id, deltas).map_err(to_pyvalue_err)
39 }
40
41 fn __richcmp__(&self, other: &Self, op: CompareOp, py: Python<'_>) -> Py<PyAny> {
42 match op {
43 CompareOp::Eq => self.eq(other).into_py_any_unwrap(py),
44 CompareOp::Ne => self.ne(other).into_py_any_unwrap(py),
45 _ => py.NotImplemented(),
46 }
47 }
48
49 fn __hash__(&self) -> isize {
50 let mut h = DefaultHasher::new();
51 self.hash(&mut h);
52 h.finish() as isize
53 }
54
55 fn __repr__(&self) -> String {
56 format!("{self:?}")
57 }
58
59 fn __str__(&self) -> String {
60 self.to_string()
61 }
62
63 #[getter]
64 #[pyo3(name = "instrument_id")]
65 fn py_instrument_id(&self) -> InstrumentId {
66 self.instrument_id
67 }
68
69 #[getter]
70 #[pyo3(name = "deltas")]
71 fn py_deltas(&self) -> Vec<OrderBookDelta> {
72 self.deltas.clone()
74 }
75
76 #[getter]
77 #[pyo3(name = "flags")]
78 fn py_flags(&self) -> u8 {
79 self.flags
80 }
81
82 #[getter]
83 #[pyo3(name = "sequence")]
84 fn py_sequence(&self) -> u64 {
85 self.sequence
86 }
87
88 #[getter]
89 #[pyo3(name = "ts_event")]
90 fn py_ts_event(&self) -> u64 {
91 self.ts_event.as_u64()
92 }
93
94 #[getter]
95 #[pyo3(name = "ts_init")]
96 fn py_ts_init(&self) -> u64 {
97 self.ts_init.as_u64()
98 }
99
100 #[staticmethod]
101 #[pyo3(name = "fully_qualified_name")]
102 fn py_fully_qualified_name() -> String {
103 format!("{}:{}", PY_MODULE_MODEL, stringify!(OrderBookDeltas))
104 }
105
106 fn __reduce__(&self, py: Python) -> PyResult<Py<PyAny>> {
107 let reconstruct = py.get_type::<Self>().getattr("_from_dicts")?;
108 let delta_dicts: Vec<_> = self
109 .deltas
110 .iter()
111 .map(|d| to_dict_pyo3(py, d))
112 .collect::<PyResult<_>>()?;
113 let py_list = PyList::new(py, delta_dicts)?;
114 (reconstruct, (self.instrument_id, py_list)).into_py_any(py)
115 }
116
117 #[staticmethod]
118 fn _from_dicts(
119 instrument_id: InstrumentId,
120 delta_dicts: Vec<pyo3::Py<pyo3::types::PyDict>>,
121 ) -> PyResult<Self> {
122 use nautilus_core::python::serialization::from_dict_pyo3;
123 let deltas: Vec<OrderBookDelta> = pyo3::Python::attach(|py| {
124 delta_dicts
125 .into_iter()
126 .map(|d| from_dict_pyo3(py, d))
127 .collect::<PyResult<_>>()
128 })?;
129 Self::new_checked(instrument_id, deltas).map_err(to_pyvalue_err)
130 }
131}