nautilus_binance/python/
types.rs1use std::{
17 collections::hash_map::DefaultHasher,
18 hash::{Hash, Hasher},
19};
20
21use nautilus_core::python::{IntoPyObjectNautilusExt, serialization::from_dict_pyo3};
22use nautilus_model::{
23 data::bar::BarType,
24 enums::OrderSide,
25 identifiers::InstrumentId,
26 types::{Price, Quantity},
27};
28use pyo3::{
29 basic::CompareOp,
30 prelude::*,
31 types::{PyDict, PyList},
32};
33use rust_decimal::Decimal;
34
35use crate::{
36 common::bar::BinanceBar,
37 data_types::{
38 BinanceFuturesLiquidation, BinanceFuturesOpenInterest, BinanceFuturesOpenInterestHist,
39 BinanceFuturesOpenInterestHistPoint, BinanceFuturesTicker,
40 },
41};
42
43#[pymethods]
44#[pyo3_stub_gen::derive::gen_stub_pymethods]
45impl BinanceBar {
46 fn __richcmp__(&self, other: &Self, op: CompareOp, py: Python<'_>) -> Py<PyAny> {
47 match op {
48 CompareOp::Eq => self.eq(other).into_py_any_unwrap(py),
49 CompareOp::Ne => self.ne(other).into_py_any_unwrap(py),
50 _ => py.NotImplemented(),
51 }
52 }
53
54 fn __hash__(&self) -> isize {
55 let mut hasher = DefaultHasher::new();
56 self.bar_type.hash(&mut hasher);
57 self.ts_event.hash(&mut hasher);
58 hasher.finish() as isize
59 }
60
61 fn __repr__(&self) -> String {
62 format!(
63 "{}(bar_type={}, open={}, high={}, low={}, close={}, volume={}, quote_volume={}, count={}, taker_buy_base_volume={}, taker_buy_quote_volume={}, ts_event={}, ts_init={})",
64 stringify!(BinanceBar),
65 self.bar_type,
66 self.open,
67 self.high,
68 self.low,
69 self.close,
70 self.volume,
71 self.quote_volume,
72 self.count,
73 self.taker_buy_base_volume,
74 self.taker_buy_quote_volume,
75 self.ts_event,
76 self.ts_init,
77 )
78 }
79
80 fn __str__(&self) -> String {
81 self.__repr__()
82 }
83
84 #[getter]
85 #[pyo3(name = "bar_type")]
86 fn py_bar_type(&self) -> BarType {
87 self.bar_type
88 }
89
90 #[getter]
91 #[pyo3(name = "open")]
92 const fn py_open(&self) -> Price {
93 self.open
94 }
95
96 #[getter]
97 #[pyo3(name = "high")]
98 const fn py_high(&self) -> Price {
99 self.high
100 }
101
102 #[getter]
103 #[pyo3(name = "low")]
104 const fn py_low(&self) -> Price {
105 self.low
106 }
107
108 #[getter]
109 #[pyo3(name = "close")]
110 const fn py_close(&self) -> Price {
111 self.close
112 }
113
114 #[getter]
115 #[pyo3(name = "volume")]
116 const fn py_volume(&self) -> Quantity {
117 self.volume
118 }
119
120 #[getter]
121 #[pyo3(name = "quote_volume")]
122 fn py_quote_volume(&self) -> Decimal {
123 self.quote_volume
124 }
125
126 #[getter]
127 #[pyo3(name = "count")]
128 const fn py_count(&self) -> u64 {
129 self.count
130 }
131
132 #[getter]
133 #[pyo3(name = "taker_buy_base_volume")]
134 fn py_taker_buy_base_volume(&self) -> Decimal {
135 self.taker_buy_base_volume
136 }
137
138 #[getter]
139 #[pyo3(name = "taker_buy_quote_volume")]
140 fn py_taker_buy_quote_volume(&self) -> Decimal {
141 self.taker_buy_quote_volume
142 }
143
144 #[getter]
145 #[pyo3(name = "ts_event")]
146 const fn py_ts_event(&self) -> u64 {
147 self.ts_event.as_u64()
148 }
149
150 #[getter]
151 #[pyo3(name = "ts_init")]
152 const fn py_ts_init(&self) -> u64 {
153 self.ts_init.as_u64()
154 }
155
156 #[staticmethod]
157 #[pyo3(name = "from_dict")]
158 fn py_from_dict(py: Python<'_>, values: Py<PyDict>) -> PyResult<Self> {
159 from_dict_pyo3(py, values)
160 }
161
162 #[pyo3(name = "to_dict")]
166 pub fn py_to_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
167 let dict = PyDict::new(py);
168 dict.set_item("type", stringify!(BinanceBar))?;
169 dict.set_item("bar_type", self.bar_type.to_string())?;
170 dict.set_item("open", self.open.to_string())?;
171 dict.set_item("high", self.high.to_string())?;
172 dict.set_item("low", self.low.to_string())?;
173 dict.set_item("close", self.close.to_string())?;
174 dict.set_item("volume", self.volume.to_string())?;
175 dict.set_item("quote_volume", self.quote_volume.to_string())?;
176 dict.set_item("count", self.count)?;
177 dict.set_item(
178 "taker_buy_base_volume",
179 self.taker_buy_base_volume.to_string(),
180 )?;
181 dict.set_item(
182 "taker_buy_quote_volume",
183 self.taker_buy_quote_volume.to_string(),
184 )?;
185 dict.set_item("ts_event", self.ts_event.as_u64())?;
186 dict.set_item("ts_init", self.ts_init.as_u64())?;
187 Ok(dict.into())
188 }
189}
190
191#[pymethods]
192#[pyo3_stub_gen::derive::gen_stub_pymethods]
193impl BinanceFuturesLiquidation {
194 #[getter]
195 #[pyo3(name = "instrument_id")]
196 fn py_instrument_id(&self) -> InstrumentId {
197 self.instrument_id
198 }
199
200 #[getter]
201 #[pyo3(name = "side")]
202 fn py_side(&self) -> OrderSide {
203 self.side
204 }
205
206 #[getter]
207 #[pyo3(name = "price")]
208 fn py_price(&self) -> Price {
209 self.price
210 }
211
212 #[getter]
213 #[pyo3(name = "average_price")]
214 fn py_average_price(&self) -> Price {
215 self.average_price
216 }
217
218 #[getter]
219 #[pyo3(name = "last_filled_qty")]
220 fn py_last_filled_qty(&self) -> Quantity {
221 self.last_filled_qty
222 }
223
224 #[getter]
225 #[pyo3(name = "accumulated_qty")]
226 fn py_accumulated_qty(&self) -> Quantity {
227 self.accumulated_qty
228 }
229
230 #[getter]
231 #[pyo3(name = "ts_event")]
232 fn py_ts_event(&self) -> u64 {
233 self.ts_event.as_u64()
234 }
235
236 #[getter]
237 #[pyo3(name = "ts_init")]
238 fn py_ts_init(&self) -> u64 {
239 self.ts_init.as_u64()
240 }
241}
242
243#[pymethods]
244#[pyo3_stub_gen::derive::gen_stub_pymethods]
245impl BinanceFuturesTicker {
246 #[getter]
247 #[pyo3(name = "instrument_id")]
248 fn py_instrument_id(&self) -> InstrumentId {
249 self.instrument_id
250 }
251
252 #[getter]
253 #[pyo3(name = "price_change")]
254 fn py_price_change(&self) -> Decimal {
255 self.price_change
256 }
257
258 #[getter]
259 #[pyo3(name = "price_change_percent")]
260 fn py_price_change_percent(&self) -> Decimal {
261 self.price_change_percent
262 }
263
264 #[getter]
265 #[pyo3(name = "weighted_avg_price")]
266 fn py_weighted_avg_price(&self) -> Decimal {
267 self.weighted_avg_price
268 }
269
270 #[getter]
271 #[pyo3(name = "last_price")]
272 fn py_last_price(&self) -> Decimal {
273 self.last_price
274 }
275
276 #[getter]
277 #[pyo3(name = "last_qty")]
278 fn py_last_qty(&self) -> Decimal {
279 self.last_qty
280 }
281
282 #[getter]
283 #[pyo3(name = "open_price")]
284 fn py_open_price(&self) -> Decimal {
285 self.open_price
286 }
287
288 #[getter]
289 #[pyo3(name = "high_price")]
290 fn py_high_price(&self) -> Decimal {
291 self.high_price
292 }
293
294 #[getter]
295 #[pyo3(name = "low_price")]
296 fn py_low_price(&self) -> Decimal {
297 self.low_price
298 }
299
300 #[getter]
301 #[pyo3(name = "volume")]
302 fn py_volume(&self) -> Decimal {
303 self.volume
304 }
305
306 #[getter]
307 #[pyo3(name = "quote_volume")]
308 fn py_quote_volume(&self) -> Decimal {
309 self.quote_volume
310 }
311
312 #[getter]
313 #[pyo3(name = "open_time")]
314 fn py_open_time(&self) -> u64 {
315 self.open_time.as_u64()
316 }
317
318 #[getter]
319 #[pyo3(name = "close_time")]
320 fn py_close_time(&self) -> u64 {
321 self.close_time.as_u64()
322 }
323
324 #[getter]
325 #[pyo3(name = "first_trade_id")]
326 fn py_first_trade_id(&self) -> i64 {
327 self.first_trade_id
328 }
329
330 #[getter]
331 #[pyo3(name = "last_trade_id")]
332 fn py_last_trade_id(&self) -> i64 {
333 self.last_trade_id
334 }
335
336 #[getter]
337 #[pyo3(name = "num_trades")]
338 fn py_num_trades(&self) -> i64 {
339 self.num_trades
340 }
341
342 #[getter]
343 #[pyo3(name = "ts_event")]
344 fn py_ts_event(&self) -> u64 {
345 self.ts_event.as_u64()
346 }
347
348 #[getter]
349 #[pyo3(name = "ts_init")]
350 fn py_ts_init(&self) -> u64 {
351 self.ts_init.as_u64()
352 }
353}
354
355#[pymethods]
356#[pyo3_stub_gen::derive::gen_stub_pymethods]
357impl BinanceFuturesOpenInterest {
358 #[getter]
359 #[pyo3(name = "instrument_id")]
360 fn py_instrument_id(&self) -> InstrumentId {
361 self.instrument_id
362 }
363
364 #[getter]
365 #[pyo3(name = "open_interest")]
366 fn py_open_interest(&self) -> Decimal {
367 self.open_interest
368 }
369
370 #[getter]
371 #[pyo3(name = "ts_event")]
372 fn py_ts_event(&self) -> u64 {
373 self.ts_event.as_u64()
374 }
375
376 #[getter]
377 #[pyo3(name = "ts_init")]
378 fn py_ts_init(&self) -> u64 {
379 self.ts_init.as_u64()
380 }
381}
382
383#[pymethods]
384#[pyo3_stub_gen::derive::gen_stub_pymethods]
385impl BinanceFuturesOpenInterestHistPoint {
386 #[getter]
387 #[pyo3(name = "sum_open_interest")]
388 fn py_sum_open_interest(&self) -> Decimal {
389 self.sum_open_interest
390 }
391
392 #[getter]
393 #[pyo3(name = "sum_open_interest_value")]
394 fn py_sum_open_interest_value(&self) -> Decimal {
395 self.sum_open_interest_value
396 }
397
398 #[getter]
399 #[pyo3(name = "ts_event")]
400 fn py_ts_event(&self) -> u64 {
401 self.ts_event.as_u64()
402 }
403}
404
405#[pymethods]
406#[pyo3_stub_gen::derive::gen_stub_pymethods]
407impl BinanceFuturesOpenInterestHist {
408 #[getter]
409 #[pyo3(name = "instrument_id")]
410 fn py_instrument_id(&self) -> InstrumentId {
411 self.instrument_id
412 }
413
414 #[getter]
415 #[pyo3(name = "period")]
416 fn py_period(&self) -> String {
417 self.period.clone()
418 }
419
420 #[getter]
421 #[pyo3(name = "points")]
422 fn py_points(&self, py: Python<'_>) -> PyResult<Py<PyList>> {
423 let points = self
424 .points
425 .iter()
426 .cloned()
427 .map(|point| point.into_py_any_unwrap(py))
428 .collect::<Vec<_>>();
429 Ok(PyList::new(py, points)?.into())
430 }
431
432 #[getter]
433 #[pyo3(name = "ts_event")]
434 fn py_ts_event(&self) -> u64 {
435 self.ts_event.as_u64()
436 }
437
438 #[getter]
439 #[pyo3(name = "ts_init")]
440 fn py_ts_init(&self) -> u64 {
441 self.ts_init.as_u64()
442 }
443}