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]
84 #[pyo3(name = "is_snapshot")]
85 fn py_is_snapshot(&self) -> bool {
86 self.is_snapshot()
87 }
88
89 #[getter]
90 #[pyo3(name = "sequence")]
91 fn py_sequence(&self) -> u64 {
92 self.sequence
93 }
94
95 #[getter]
96 #[pyo3(name = "ts_event")]
97 fn py_ts_event(&self) -> u64 {
98 self.ts_event.as_u64()
99 }
100
101 #[getter]
102 #[pyo3(name = "ts_init")]
103 fn py_ts_init(&self) -> u64 {
104 self.ts_init.as_u64()
105 }
106
107 #[staticmethod]
108 #[pyo3(name = "fully_qualified_name")]
109 fn py_fully_qualified_name() -> String {
110 format!("{}:{}", PY_MODULE_MODEL, stringify!(OrderBookDeltas))
111 }
112
113 fn __reduce__(&self, py: Python) -> PyResult<Py<PyAny>> {
114 let reconstruct = py.get_type::<Self>().getattr("_from_dicts")?;
115 let delta_dicts: Vec<_> = self
116 .deltas
117 .iter()
118 .map(|d| to_dict_pyo3(py, d))
119 .collect::<PyResult<_>>()?;
120 let py_list = PyList::new(py, delta_dicts)?;
121 (reconstruct, (self.instrument_id, py_list)).into_py_any(py)
122 }
123
124 #[staticmethod]
125 fn _from_dicts(
126 instrument_id: InstrumentId,
127 delta_dicts: Vec<pyo3::Py<pyo3::types::PyDict>>,
128 ) -> PyResult<Self> {
129 use nautilus_core::python::serialization::from_dict_pyo3;
130 let deltas: Vec<OrderBookDelta> = pyo3::Python::attach(|py| {
131 delta_dicts
132 .into_iter()
133 .map(|d| from_dict_pyo3(py, d))
134 .collect::<PyResult<_>>()
135 })?;
136 Self::new_checked(instrument_id, deltas).map_err(to_pyvalue_err)
137 }
138}