dbn/python/
record.rs

1use std::{ffi::c_char, mem};
2
3use pyo3::{conversion::IntoPyObjectExt, prelude::*};
4
5use crate::{
6    record::str_to_c_chars, rtype, v1, v2, Action, BboMsg, BidAskPair, CbboMsg, Cmbp1Msg,
7    ConsolidatedBidAskPair, ErrorCode, ErrorMsg, FlagSet, ImbalanceMsg, InstrumentClass,
8    InstrumentDefMsg, MatchAlgorithm, MboMsg, Mbp10Msg, Mbp1Msg, OhlcvMsg, RType, Record,
9    RecordHeader, SType, SecurityUpdateAction, Side, StatMsg, StatType, StatUpdateAction,
10    StatusAction, StatusMsg, StatusReason, SymbolMappingMsg, SystemCode, SystemMsg, TradeMsg,
11    TradingEvent, TriState, UserDefinedInstrument, UNDEF_ORDER_SIZE, UNDEF_PRICE, UNDEF_TIMESTAMP,
12};
13
14use super::{
15    conversions::{char_to_c_char, new_py_timestamp_or_datetime},
16    to_py_err, PyFieldDesc,
17};
18
19#[pymethods]
20impl MboMsg {
21    #[new]
22    #[pyo3(signature = (
23        publisher_id,
24        instrument_id,
25        ts_event,
26        order_id,
27        price,
28        size,
29        action,
30        side,
31        ts_recv,
32        flags = None,
33        channel_id = None,
34        ts_in_delta = 0,
35        sequence = 0,
36    ))]
37    fn py_new(
38        publisher_id: u16,
39        instrument_id: u32,
40        ts_event: u64,
41        order_id: u64,
42        price: i64,
43        size: u32,
44        action: Action,
45        side: Side,
46        ts_recv: u64,
47        flags: Option<FlagSet>,
48        channel_id: Option<u8>,
49        ts_in_delta: i32,
50        sequence: u32,
51    ) -> PyResult<Self> {
52        Ok(Self {
53            hd: RecordHeader::new::<Self>(rtype::MBO, publisher_id, instrument_id, ts_event),
54            order_id,
55            price,
56            size,
57            flags: flags.unwrap_or_default(),
58            channel_id: channel_id.unwrap_or(u8::MAX),
59            action: action as u8 as c_char,
60            side: side as u8 as c_char,
61            ts_recv,
62            ts_in_delta,
63            sequence,
64        })
65    }
66
67    fn __bytes__(&self) -> &[u8] {
68        self.as_ref()
69    }
70
71    fn __repr__(&self) -> String {
72        format!("{self:?}")
73    }
74
75    #[getter]
76    fn rtype(&self) -> PyResult<RType> {
77        self.hd.rtype().map_err(to_py_err)
78    }
79
80    #[getter]
81    fn get_publisher_id(&self) -> u16 {
82        self.hd.publisher_id
83    }
84    #[setter]
85    fn set_publisher_id(&mut self, publisher_id: u16) {
86        self.hd.publisher_id = publisher_id;
87    }
88
89    #[getter]
90    fn get_instrument_id(&self) -> u32 {
91        self.hd.instrument_id
92    }
93    #[setter]
94    fn set_instrument_id(&mut self, instrument_id: u32) {
95        self.hd.instrument_id = instrument_id;
96    }
97
98    #[getter]
99    fn ts_event(&self) -> u64 {
100        self.hd.ts_event
101    }
102    #[getter]
103    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
104        new_py_timestamp_or_datetime(py, self.ts_event())
105    }
106    #[setter]
107    fn set_ts_event(&mut self, ts_event: u64) {
108        self.hd.ts_event = ts_event;
109    }
110
111    #[pyo3(name = "record_size")]
112    fn py_record_size(&self) -> usize {
113        self.record_size()
114    }
115
116    #[classattr]
117    fn size_hint() -> PyResult<usize> {
118        Ok(mem::size_of::<Self>())
119    }
120
121    #[getter]
122    fn ts_index(&self) -> u64 {
123        self.raw_index_ts()
124    }
125    #[getter]
126    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
127        new_py_timestamp_or_datetime(py, self.raw_index_ts())
128    }
129
130    #[getter]
131    fn get_pretty_price(&self) -> f64 {
132        self.price_f64()
133    }
134
135    #[getter]
136    fn get_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
137        self.action()
138            .map(|c| c.into_bound_py_any(py))
139            .unwrap_or_else(|_| (self.action as u8 as char).into_bound_py_any(py))
140    }
141    #[setter]
142    fn set_action(&mut self, action: Action) {
143        self.action = action as u8 as c_char;
144    }
145
146    #[getter]
147    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
148        self.side()
149            .map(|c| c.into_bound_py_any(py))
150            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
151    }
152    #[setter]
153    fn set_side(&mut self, side: Side) {
154        self.side = side as u8 as c_char;
155    }
156
157    #[getter]
158    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
159        new_py_timestamp_or_datetime(py, self.ts_recv)
160    }
161
162    #[classattr]
163    #[pyo3(name = "_dtypes")]
164    fn py_dtypes() -> Vec<(String, String)> {
165        Self::field_dtypes("")
166    }
167
168    #[classattr]
169    #[pyo3(name = "_price_fields")]
170    fn py_price_fields() -> Vec<String> {
171        Self::price_fields("")
172    }
173
174    #[classattr]
175    #[pyo3(name = "_timestamp_fields")]
176    fn py_timestamp_fields() -> Vec<String> {
177        Self::timestamp_fields("")
178    }
179
180    #[classattr]
181    #[pyo3(name = "_hidden_fields")]
182    fn py_hidden_fields() -> Vec<String> {
183        Self::hidden_fields("")
184    }
185
186    #[classattr]
187    #[pyo3(name = "_ordered_fields")]
188    fn py_ordered_fields() -> Vec<String> {
189        Self::ordered_fields("")
190    }
191}
192
193#[pymethods]
194impl BidAskPair {
195    #[new]
196    #[pyo3(signature = (
197        bid_px = UNDEF_PRICE,
198        ask_px = UNDEF_PRICE,
199        bid_sz = 0,
200        ask_sz = 0,
201        bid_ct = 0,
202        ask_ct = 0,
203    ))]
204    fn py_new(
205        bid_px: i64,
206        ask_px: i64,
207        bid_sz: u32,
208        ask_sz: u32,
209        bid_ct: u32,
210        ask_ct: u32,
211    ) -> Self {
212        Self {
213            bid_px,
214            ask_px,
215            bid_sz,
216            ask_sz,
217            bid_ct,
218            ask_ct,
219        }
220    }
221
222    fn __repr__(&self) -> String {
223        format!("{self:?}")
224    }
225
226    #[getter]
227    fn get_pretty_bid_px(&self) -> f64 {
228        self.bid_px_f64()
229    }
230
231    #[getter]
232    fn get_pretty_ask_px(&self) -> f64 {
233        self.ask_px_f64()
234    }
235}
236
237#[pymethods]
238impl ConsolidatedBidAskPair {
239    #[new]
240    #[pyo3(signature = (
241        bid_px = UNDEF_PRICE,
242        ask_px = UNDEF_PRICE,
243        bid_sz = 0,
244        ask_sz = 0,
245        bid_pb = 0,
246        ask_pb = 0,
247    ))]
248    fn py_new(
249        bid_px: i64,
250        ask_px: i64,
251        bid_sz: u32,
252        ask_sz: u32,
253        bid_pb: u16,
254        ask_pb: u16,
255    ) -> Self {
256        Self {
257            bid_px,
258            ask_px,
259            bid_sz,
260            ask_sz,
261            bid_pb,
262            _reserved1: Default::default(),
263            ask_pb,
264            _reserved2: Default::default(),
265        }
266    }
267
268    fn __repr__(&self) -> String {
269        format!("{self:?}")
270    }
271
272    #[getter]
273    fn get_pretty_bid_px(&self) -> f64 {
274        self.bid_px_f64()
275    }
276
277    #[getter]
278    fn get_pretty_ask_px(&self) -> f64 {
279        self.ask_px_f64()
280    }
281}
282
283#[pymethods]
284impl TradeMsg {
285    #[new]
286    #[pyo3(signature = (
287        publisher_id,
288        instrument_id,
289        ts_event,
290        price,
291        size,
292        action,
293        side,
294        depth,
295        ts_recv,
296        flags = None,
297        ts_in_delta = 0,
298        sequence = 0,
299    ))]
300    fn py_new(
301        publisher_id: u16,
302        instrument_id: u32,
303        ts_event: u64,
304        price: i64,
305        size: u32,
306        action: Action,
307        side: Side,
308        depth: u8,
309        ts_recv: u64,
310        flags: Option<FlagSet>,
311        ts_in_delta: i32,
312        sequence: u32,
313    ) -> PyResult<Self> {
314        Ok(Self {
315            hd: RecordHeader::new::<Self>(rtype::MBP_0, publisher_id, instrument_id, ts_event),
316            price,
317            size,
318            action: action as u8 as c_char,
319            side: side as u8 as c_char,
320            flags: flags.unwrap_or_default(),
321            depth,
322            ts_recv,
323            ts_in_delta,
324            sequence,
325        })
326    }
327
328    fn __bytes__(&self) -> &[u8] {
329        self.as_ref()
330    }
331
332    fn __repr__(&self) -> String {
333        format!("{self:?}")
334    }
335
336    #[getter]
337    fn rtype(&self) -> PyResult<RType> {
338        self.hd.rtype().map_err(to_py_err)
339    }
340
341    #[getter]
342    fn get_publisher_id(&self) -> u16 {
343        self.hd.publisher_id
344    }
345    #[setter]
346    fn set_publisher_id(&mut self, publisher_id: u16) {
347        self.hd.publisher_id = publisher_id;
348    }
349
350    #[getter]
351    fn get_instrument_id(&self) -> u32 {
352        self.hd.instrument_id
353    }
354    #[setter]
355    fn set_instrument_id(&mut self, instrument_id: u32) {
356        self.hd.instrument_id = instrument_id;
357    }
358
359    #[getter]
360    fn ts_event(&self) -> u64 {
361        self.hd.ts_event
362    }
363    #[getter]
364    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
365        new_py_timestamp_or_datetime(py, self.ts_event())
366    }
367    #[setter]
368    fn set_ts_event(&mut self, ts_event: u64) {
369        self.hd.ts_event = ts_event;
370    }
371
372    #[pyo3(name = "record_size")]
373    fn py_record_size(&self) -> usize {
374        self.record_size()
375    }
376
377    #[classattr]
378    fn size_hint() -> PyResult<usize> {
379        Ok(mem::size_of::<Self>())
380    }
381
382    #[getter]
383    fn ts_index(&self) -> u64 {
384        self.raw_index_ts()
385    }
386    #[getter]
387    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
388        new_py_timestamp_or_datetime(py, self.raw_index_ts())
389    }
390
391    #[getter]
392    fn get_pretty_price(&self) -> f64 {
393        self.price_f64()
394    }
395
396    #[getter]
397    fn get_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
398        self.action()
399            .map(|c| c.into_bound_py_any(py))
400            .unwrap_or_else(|_| (self.action as u8 as char).into_bound_py_any(py))
401    }
402    #[setter]
403    fn set_action(&mut self, action: Action) {
404        self.action = action as u8 as c_char;
405    }
406
407    #[getter]
408    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
409        self.side()
410            .map(|c| c.into_bound_py_any(py))
411            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
412    }
413    #[setter]
414    fn set_side(&mut self, side: Side) {
415        self.side = side as u8 as c_char;
416    }
417
418    #[getter]
419    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
420        new_py_timestamp_or_datetime(py, self.ts_recv)
421    }
422
423    #[classattr]
424    #[pyo3(name = "_dtypes")]
425    fn py_dtypes() -> Vec<(String, String)> {
426        Self::field_dtypes("")
427    }
428
429    #[classattr]
430    #[pyo3(name = "_price_fields")]
431    fn py_price_fields() -> Vec<String> {
432        Self::price_fields("")
433    }
434
435    #[classattr]
436    #[pyo3(name = "_timestamp_fields")]
437    fn py_timestamp_fields() -> Vec<String> {
438        Self::timestamp_fields("")
439    }
440
441    #[classattr]
442    #[pyo3(name = "_hidden_fields")]
443    fn py_hidden_fields() -> Vec<String> {
444        Self::hidden_fields("")
445    }
446
447    #[classattr]
448    #[pyo3(name = "_ordered_fields")]
449    fn py_ordered_fields() -> Vec<String> {
450        Self::ordered_fields("")
451    }
452}
453
454#[pymethods]
455impl Mbp1Msg {
456    #[new]
457    #[pyo3(signature = (
458        publisher_id,
459        instrument_id,
460        ts_event,
461        price,
462        size,
463        action,
464        side,
465        depth,
466        ts_recv,
467        flags = None,
468        ts_in_delta = 0,
469        sequence = 0,
470        levels = None,
471    ))]
472    fn py_new(
473        publisher_id: u16,
474        instrument_id: u32,
475        ts_event: u64,
476        price: i64,
477        size: u32,
478        action: Action,
479        side: Side,
480        depth: u8,
481        ts_recv: u64,
482        flags: Option<FlagSet>,
483        ts_in_delta: i32,
484        sequence: u32,
485        levels: Option<BidAskPair>,
486    ) -> PyResult<Self> {
487        Ok(Self {
488            hd: RecordHeader::new::<Self>(rtype::MBP_1, publisher_id, instrument_id, ts_event),
489            price,
490            size,
491            action: action as u8 as c_char,
492            side: side as u8 as c_char,
493            flags: flags.unwrap_or_default(),
494            depth,
495            ts_recv,
496            ts_in_delta,
497            sequence,
498            levels: [levels.unwrap_or_default()],
499        })
500    }
501
502    fn __bytes__(&self) -> &[u8] {
503        self.as_ref()
504    }
505
506    fn __repr__(&self) -> String {
507        format!("{self:?}")
508    }
509
510    #[getter]
511    fn rtype(&self) -> PyResult<RType> {
512        self.hd.rtype().map_err(to_py_err)
513    }
514
515    #[getter]
516    fn get_publisher_id(&self) -> u16 {
517        self.hd.publisher_id
518    }
519    #[setter]
520    fn set_publisher_id(&mut self, publisher_id: u16) {
521        self.hd.publisher_id = publisher_id;
522    }
523
524    #[getter]
525    fn get_instrument_id(&self) -> u32 {
526        self.hd.instrument_id
527    }
528    #[setter]
529    fn set_instrument_id(&mut self, instrument_id: u32) {
530        self.hd.instrument_id = instrument_id;
531    }
532
533    #[getter]
534    fn ts_event(&self) -> u64 {
535        self.hd.ts_event
536    }
537    #[getter]
538    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
539        new_py_timestamp_or_datetime(py, self.ts_event())
540    }
541    #[setter]
542    fn set_ts_event(&mut self, ts_event: u64) {
543        self.hd.ts_event = ts_event;
544    }
545
546    #[pyo3(name = "record_size")]
547    fn py_record_size(&self) -> usize {
548        self.record_size()
549    }
550
551    #[classattr]
552    fn size_hint() -> PyResult<usize> {
553        Ok(mem::size_of::<Self>())
554    }
555
556    #[getter]
557    fn ts_index(&self) -> u64 {
558        self.raw_index_ts()
559    }
560    #[getter]
561    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
562        new_py_timestamp_or_datetime(py, self.raw_index_ts())
563    }
564
565    #[getter]
566    fn get_pretty_price(&self) -> f64 {
567        self.price_f64()
568    }
569
570    #[getter]
571    fn get_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
572        self.action()
573            .map(|c| c.into_bound_py_any(py))
574            .unwrap_or_else(|_| (self.action as u8 as char).into_bound_py_any(py))
575    }
576    #[setter]
577    fn set_action(&mut self, action: Action) {
578        self.action = action as u8 as c_char;
579    }
580
581    #[getter]
582    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
583        self.side()
584            .map(|c| c.into_bound_py_any(py))
585            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
586    }
587    #[setter]
588    fn set_side(&mut self, side: Side) {
589        self.side = side as u8 as c_char;
590    }
591
592    #[getter]
593    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
594        new_py_timestamp_or_datetime(py, self.ts_recv)
595    }
596
597    #[classattr]
598    #[pyo3(name = "_dtypes")]
599    fn py_dtypes() -> Vec<(String, String)> {
600        Self::field_dtypes("")
601    }
602
603    #[classattr]
604    #[pyo3(name = "_price_fields")]
605    fn py_price_fields() -> Vec<String> {
606        Self::price_fields("")
607    }
608
609    #[classattr]
610    #[pyo3(name = "_timestamp_fields")]
611    fn py_timestamp_fields() -> Vec<String> {
612        Self::timestamp_fields("")
613    }
614
615    #[classattr]
616    #[pyo3(name = "_hidden_fields")]
617    fn py_hidden_fields() -> Vec<String> {
618        Self::hidden_fields("")
619    }
620
621    #[classattr]
622    #[pyo3(name = "_ordered_fields")]
623    fn py_ordered_fields() -> Vec<String> {
624        Self::ordered_fields("")
625    }
626}
627
628#[pymethods]
629impl Mbp10Msg {
630    #[new]
631    #[pyo3(signature = (
632        publisher_id,
633        instrument_id,
634        ts_event,
635        price,
636        size,
637        action,
638        side,
639        depth,
640        ts_recv,
641        flags = None,
642        ts_in_delta = 0,
643        sequence = 0,
644        levels = None,
645    ))]
646    fn py_new(
647        publisher_id: u16,
648        instrument_id: u32,
649        ts_event: u64,
650        price: i64,
651        size: u32,
652        action: Action,
653        side: Side,
654        depth: u8,
655        ts_recv: u64,
656        flags: Option<FlagSet>,
657        ts_in_delta: i32,
658        sequence: u32,
659        levels: Option<[BidAskPair; 10]>,
660    ) -> PyResult<Self> {
661        Ok(Self {
662            hd: RecordHeader::new::<Self>(rtype::MBP_10, publisher_id, instrument_id, ts_event),
663            price,
664            size,
665            action: action as u8 as c_char,
666            side: side as u8 as c_char,
667            flags: flags.unwrap_or_default(),
668            depth,
669            ts_recv,
670            ts_in_delta,
671            sequence,
672            levels: levels.unwrap_or_default(),
673        })
674    }
675
676    fn __bytes__(&self) -> &[u8] {
677        self.as_ref()
678    }
679
680    fn __repr__(&self) -> String {
681        format!("{self:?}")
682    }
683
684    #[getter]
685    fn rtype(&self) -> PyResult<RType> {
686        self.hd.rtype().map_err(to_py_err)
687    }
688
689    #[getter]
690    fn get_publisher_id(&self) -> u16 {
691        self.hd.publisher_id
692    }
693    #[setter]
694    fn set_publisher_id(&mut self, publisher_id: u16) {
695        self.hd.publisher_id = publisher_id;
696    }
697
698    #[getter]
699    fn get_instrument_id(&self) -> u32 {
700        self.hd.instrument_id
701    }
702    #[setter]
703    fn set_instrument_id(&mut self, instrument_id: u32) {
704        self.hd.instrument_id = instrument_id;
705    }
706
707    #[getter]
708    fn ts_event(&self) -> u64 {
709        self.hd.ts_event
710    }
711    #[getter]
712    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
713        new_py_timestamp_or_datetime(py, self.ts_event())
714    }
715    #[setter]
716    fn set_ts_event(&mut self, ts_event: u64) {
717        self.hd.ts_event = ts_event;
718    }
719
720    #[pyo3(name = "record_size")]
721    fn py_record_size(&self) -> usize {
722        self.record_size()
723    }
724
725    #[classattr]
726    fn size_hint() -> PyResult<usize> {
727        Ok(mem::size_of::<Self>())
728    }
729
730    #[getter]
731    fn ts_index(&self) -> u64 {
732        self.raw_index_ts()
733    }
734    #[getter]
735    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
736        new_py_timestamp_or_datetime(py, self.raw_index_ts())
737    }
738
739    #[getter]
740    fn get_pretty_price(&self) -> f64 {
741        self.price_f64()
742    }
743
744    #[getter]
745    fn get_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
746        self.action()
747            .map(|c| c.into_bound_py_any(py))
748            .unwrap_or_else(|_| (self.action as u8 as char).into_bound_py_any(py))
749    }
750    #[setter]
751    fn set_action(&mut self, action: Action) {
752        self.action = action as u8 as c_char;
753    }
754
755    #[getter]
756    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
757        self.side()
758            .map(|c| c.into_bound_py_any(py))
759            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
760    }
761    #[setter]
762    fn set_side(&mut self, side: Side) {
763        self.side = side as u8 as c_char;
764    }
765
766    #[getter]
767    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
768        new_py_timestamp_or_datetime(py, self.ts_recv)
769    }
770
771    #[classattr]
772    #[pyo3(name = "_dtypes")]
773    fn py_dtypes() -> Vec<(String, String)> {
774        Self::field_dtypes("")
775    }
776
777    #[classattr]
778    #[pyo3(name = "_price_fields")]
779    fn py_price_fields() -> Vec<String> {
780        Self::price_fields("")
781    }
782
783    #[classattr]
784    #[pyo3(name = "_timestamp_fields")]
785    fn py_timestamp_fields() -> Vec<String> {
786        Self::timestamp_fields("")
787    }
788
789    #[classattr]
790    #[pyo3(name = "_hidden_fields")]
791    fn py_hidden_fields() -> Vec<String> {
792        Self::hidden_fields("")
793    }
794
795    #[classattr]
796    #[pyo3(name = "_ordered_fields")]
797    fn py_ordered_fields() -> Vec<String> {
798        Self::ordered_fields("")
799    }
800}
801
802#[pymethods]
803impl BboMsg {
804    #[new]
805    #[pyo3(signature = (
806        rtype,
807        publisher_id,
808        instrument_id,
809        ts_event,
810        price,
811        size,
812        side,
813        ts_recv,
814        flags = None,
815        sequence = 0,
816        levels = None,
817    ))]
818    fn py_new(
819        rtype: u8,
820        publisher_id: u16,
821        instrument_id: u32,
822        ts_event: u64,
823        price: i64,
824        size: u32,
825        side: Side,
826        ts_recv: u64,
827        flags: Option<FlagSet>,
828        sequence: u32,
829        levels: Option<BidAskPair>,
830    ) -> PyResult<Self> {
831        Ok(Self {
832            hd: RecordHeader::new::<Self>(rtype, publisher_id, instrument_id, ts_event),
833            price,
834            size,
835            _reserved1: Default::default(),
836            side: side as u8 as c_char,
837            flags: flags.unwrap_or_default(),
838            _reserved2: Default::default(),
839            ts_recv,
840            _reserved3: Default::default(),
841            sequence,
842            levels: [levels.unwrap_or_default()],
843        })
844    }
845
846    fn __bytes__(&self) -> &[u8] {
847        self.as_ref()
848    }
849
850    fn __repr__(&self) -> String {
851        format!("{self:?}")
852    }
853
854    #[getter]
855    fn rtype(&self) -> PyResult<RType> {
856        self.hd.rtype().map_err(to_py_err)
857    }
858
859    #[getter]
860    fn get_publisher_id(&self) -> u16 {
861        self.hd.publisher_id
862    }
863    #[setter]
864    fn set_publisher_id(&mut self, publisher_id: u16) {
865        self.hd.publisher_id = publisher_id;
866    }
867
868    #[getter]
869    fn get_instrument_id(&self) -> u32 {
870        self.hd.instrument_id
871    }
872    #[setter]
873    fn set_instrument_id(&mut self, instrument_id: u32) {
874        self.hd.instrument_id = instrument_id;
875    }
876
877    #[getter]
878    fn ts_event(&self) -> u64 {
879        self.hd.ts_event
880    }
881    #[getter]
882    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
883        new_py_timestamp_or_datetime(py, self.ts_event())
884    }
885    #[setter]
886    fn set_ts_event(&mut self, ts_event: u64) {
887        self.hd.ts_event = ts_event;
888    }
889
890    #[pyo3(name = "record_size")]
891    fn py_record_size(&self) -> usize {
892        self.record_size()
893    }
894
895    #[classattr]
896    fn size_hint() -> PyResult<usize> {
897        Ok(mem::size_of::<Self>())
898    }
899
900    #[getter]
901    fn ts_index(&self) -> u64 {
902        self.raw_index_ts()
903    }
904    #[getter]
905    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
906        new_py_timestamp_or_datetime(py, self.raw_index_ts())
907    }
908
909    #[getter]
910    fn get_pretty_price(&self) -> f64 {
911        self.price_f64()
912    }
913
914    #[getter]
915    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
916        self.side()
917            .map(|c| c.into_bound_py_any(py))
918            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
919    }
920    #[setter]
921    fn set_side(&mut self, side: Side) {
922        self.side = side as u8 as c_char;
923    }
924
925    #[getter]
926    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
927        new_py_timestamp_or_datetime(py, self.ts_recv)
928    }
929
930    #[classattr]
931    #[pyo3(name = "_dtypes")]
932    fn py_dtypes() -> Vec<(String, String)> {
933        Self::field_dtypes("")
934    }
935
936    #[classattr]
937    #[pyo3(name = "_price_fields")]
938    fn py_price_fields() -> Vec<String> {
939        Self::price_fields("")
940    }
941
942    #[classattr]
943    #[pyo3(name = "_timestamp_fields")]
944    fn py_timestamp_fields() -> Vec<String> {
945        Self::timestamp_fields("")
946    }
947
948    #[classattr]
949    #[pyo3(name = "_hidden_fields")]
950    fn py_hidden_fields() -> Vec<String> {
951        Self::hidden_fields("")
952    }
953
954    #[classattr]
955    #[pyo3(name = "_ordered_fields")]
956    fn py_ordered_fields() -> Vec<String> {
957        Self::ordered_fields("")
958    }
959}
960
961#[pymethods]
962impl Cmbp1Msg {
963    #[new]
964    #[pyo3(signature = (
965        rtype,
966        publisher_id,
967        instrument_id,
968        ts_event,
969        price,
970        size,
971        action,
972        side,
973        ts_recv,
974        flags = None,
975        ts_in_delta = 0,
976        levels = None,
977    ))]
978    fn py_new(
979        rtype: u8,
980        publisher_id: u16,
981        instrument_id: u32,
982        ts_event: u64,
983        price: i64,
984        size: u32,
985        action: Action,
986        side: Side,
987        ts_recv: u64,
988        flags: Option<FlagSet>,
989        ts_in_delta: i32,
990        levels: Option<ConsolidatedBidAskPair>,
991    ) -> PyResult<Self> {
992        Ok(Self {
993            hd: RecordHeader::new::<Self>(rtype, publisher_id, instrument_id, ts_event),
994            price,
995            size,
996            action: action as u8 as c_char,
997            side: side as u8 as c_char,
998            flags: flags.unwrap_or_default(),
999            _reserved1: Default::default(),
1000            ts_recv,
1001            ts_in_delta,
1002            _reserved2: Default::default(),
1003            levels: [levels.unwrap_or_default()],
1004        })
1005    }
1006
1007    fn __bytes__(&self) -> &[u8] {
1008        self.as_ref()
1009    }
1010
1011    fn __repr__(&self) -> String {
1012        format!("{self:?}")
1013    }
1014
1015    #[getter]
1016    fn rtype(&self) -> PyResult<RType> {
1017        self.hd.rtype().map_err(to_py_err)
1018    }
1019
1020    #[getter]
1021    fn get_publisher_id(&self) -> u16 {
1022        self.hd.publisher_id
1023    }
1024    #[setter]
1025    fn set_publisher_id(&mut self, publisher_id: u16) {
1026        self.hd.publisher_id = publisher_id;
1027    }
1028
1029    #[getter]
1030    fn get_instrument_id(&self) -> u32 {
1031        self.hd.instrument_id
1032    }
1033    #[setter]
1034    fn set_instrument_id(&mut self, instrument_id: u32) {
1035        self.hd.instrument_id = instrument_id;
1036    }
1037
1038    #[getter]
1039    fn ts_event(&self) -> u64 {
1040        self.hd.ts_event
1041    }
1042    #[getter]
1043    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1044        new_py_timestamp_or_datetime(py, self.ts_event())
1045    }
1046    #[setter]
1047    fn set_ts_event(&mut self, ts_event: u64) {
1048        self.hd.ts_event = ts_event;
1049    }
1050
1051    #[pyo3(name = "record_size")]
1052    fn py_record_size(&self) -> usize {
1053        self.record_size()
1054    }
1055
1056    #[classattr]
1057    fn size_hint() -> PyResult<usize> {
1058        Ok(mem::size_of::<Self>())
1059    }
1060
1061    #[getter]
1062    fn ts_index(&self) -> u64 {
1063        self.raw_index_ts()
1064    }
1065    #[getter]
1066    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1067        new_py_timestamp_or_datetime(py, self.raw_index_ts())
1068    }
1069
1070    #[getter]
1071    fn get_pretty_price(&self) -> f64 {
1072        self.price_f64()
1073    }
1074
1075    #[getter]
1076    fn get_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
1077        self.action()
1078            .map(|c| c.into_bound_py_any(py))
1079            .unwrap_or_else(|_| (self.action as u8 as char).into_bound_py_any(py))
1080    }
1081    #[setter]
1082    fn set_action(&mut self, action: Action) {
1083        self.action = action as u8 as c_char;
1084    }
1085
1086    #[getter]
1087    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
1088        self.side()
1089            .map(|c| c.into_bound_py_any(py))
1090            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
1091    }
1092    #[setter]
1093    fn set_side(&mut self, side: Side) {
1094        self.side = side as u8 as c_char;
1095    }
1096
1097    #[getter]
1098    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1099        new_py_timestamp_or_datetime(py, self.ts_recv)
1100    }
1101
1102    #[classattr]
1103    #[pyo3(name = "_dtypes")]
1104    fn py_dtypes() -> Vec<(String, String)> {
1105        Self::field_dtypes("")
1106    }
1107
1108    #[classattr]
1109    #[pyo3(name = "_price_fields")]
1110    fn py_price_fields() -> Vec<String> {
1111        Self::price_fields("")
1112    }
1113
1114    #[classattr]
1115    #[pyo3(name = "_timestamp_fields")]
1116    fn py_timestamp_fields() -> Vec<String> {
1117        Self::timestamp_fields("")
1118    }
1119
1120    #[classattr]
1121    #[pyo3(name = "_hidden_fields")]
1122    fn py_hidden_fields() -> Vec<String> {
1123        Self::hidden_fields("")
1124    }
1125
1126    #[classattr]
1127    #[pyo3(name = "_ordered_fields")]
1128    fn py_ordered_fields() -> Vec<String> {
1129        Self::ordered_fields("")
1130    }
1131}
1132
1133#[pymethods]
1134impl CbboMsg {
1135    #[new]
1136    #[pyo3(signature = (
1137        rtype,
1138        publisher_id,
1139        instrument_id,
1140        ts_event,
1141        price,
1142        size,
1143        side,
1144        ts_recv,
1145        flags = None,
1146        levels = None,
1147    ))]
1148    fn py_new(
1149        rtype: u8,
1150        publisher_id: u16,
1151        instrument_id: u32,
1152        ts_event: u64,
1153        price: i64,
1154        size: u32,
1155        side: Side,
1156        ts_recv: u64,
1157        flags: Option<FlagSet>,
1158        levels: Option<ConsolidatedBidAskPair>,
1159    ) -> PyResult<Self> {
1160        Ok(Self {
1161            hd: RecordHeader::new::<Self>(rtype, publisher_id, instrument_id, ts_event),
1162            price,
1163            size,
1164            _reserved1: Default::default(),
1165            side: side as u8 as c_char,
1166            flags: flags.unwrap_or_default(),
1167            _reserved2: Default::default(),
1168            ts_recv,
1169            _reserved3: Default::default(),
1170            levels: [levels.unwrap_or_default()],
1171        })
1172    }
1173
1174    fn __bytes__(&self) -> &[u8] {
1175        self.as_ref()
1176    }
1177
1178    fn __repr__(&self) -> String {
1179        format!("{self:?}")
1180    }
1181
1182    #[getter]
1183    fn rtype(&self) -> PyResult<RType> {
1184        self.hd.rtype().map_err(to_py_err)
1185    }
1186
1187    #[getter]
1188    fn get_publisher_id(&self) -> u16 {
1189        self.hd.publisher_id
1190    }
1191    #[setter]
1192    fn set_publisher_id(&mut self, publisher_id: u16) {
1193        self.hd.publisher_id = publisher_id;
1194    }
1195
1196    #[getter]
1197    fn get_instrument_id(&self) -> u32 {
1198        self.hd.instrument_id
1199    }
1200    #[setter]
1201    fn set_instrument_id(&mut self, instrument_id: u32) {
1202        self.hd.instrument_id = instrument_id;
1203    }
1204
1205    #[getter]
1206    fn ts_event(&self) -> u64 {
1207        self.hd.ts_event
1208    }
1209    #[getter]
1210    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1211        new_py_timestamp_or_datetime(py, self.ts_event())
1212    }
1213    #[setter]
1214    fn set_ts_event(&mut self, ts_event: u64) {
1215        self.hd.ts_event = ts_event;
1216    }
1217
1218    #[pyo3(name = "record_size")]
1219    fn py_record_size(&self) -> usize {
1220        self.record_size()
1221    }
1222
1223    #[classattr]
1224    fn size_hint() -> PyResult<usize> {
1225        Ok(mem::size_of::<Self>())
1226    }
1227
1228    #[getter]
1229    fn ts_index(&self) -> u64 {
1230        self.raw_index_ts()
1231    }
1232    #[getter]
1233    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1234        new_py_timestamp_or_datetime(py, self.raw_index_ts())
1235    }
1236
1237    #[getter]
1238    fn get_pretty_price(&self) -> f64 {
1239        self.price_f64()
1240    }
1241
1242    #[getter]
1243    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
1244        self.side()
1245            .map(|c| c.into_bound_py_any(py))
1246            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
1247    }
1248    #[setter]
1249    fn set_side(&mut self, side: Side) {
1250        self.side = side as u8 as c_char;
1251    }
1252
1253    #[getter]
1254    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1255        new_py_timestamp_or_datetime(py, self.ts_recv)
1256    }
1257
1258    #[classattr]
1259    #[pyo3(name = "_dtypes")]
1260    fn py_dtypes() -> Vec<(String, String)> {
1261        Self::field_dtypes("")
1262    }
1263
1264    #[classattr]
1265    #[pyo3(name = "_price_fields")]
1266    fn py_price_fields() -> Vec<String> {
1267        Self::price_fields("")
1268    }
1269
1270    #[classattr]
1271    #[pyo3(name = "_timestamp_fields")]
1272    fn py_timestamp_fields() -> Vec<String> {
1273        Self::timestamp_fields("")
1274    }
1275
1276    #[classattr]
1277    #[pyo3(name = "_hidden_fields")]
1278    fn py_hidden_fields() -> Vec<String> {
1279        Self::hidden_fields("")
1280    }
1281
1282    #[classattr]
1283    #[pyo3(name = "_ordered_fields")]
1284    fn py_ordered_fields() -> Vec<String> {
1285        Self::ordered_fields("")
1286    }
1287}
1288
1289#[pymethods]
1290impl OhlcvMsg {
1291    #[new]
1292    #[pyo3(signature = (
1293        rtype,
1294        publisher_id,
1295        instrument_id,
1296        ts_event,
1297        open,
1298        high,
1299        low,
1300        close,
1301        volume,
1302    ))]
1303    fn py_new(
1304        rtype: u8,
1305        publisher_id: u16,
1306        instrument_id: u32,
1307        ts_event: u64,
1308        open: i64,
1309        high: i64,
1310        low: i64,
1311        close: i64,
1312        volume: u64,
1313    ) -> PyResult<Self> {
1314        Ok(Self {
1315            hd: RecordHeader::new::<Self>(rtype, publisher_id, instrument_id, ts_event),
1316            open,
1317            high,
1318            low,
1319            close,
1320            volume,
1321        })
1322    }
1323
1324    fn __bytes__(&self) -> &[u8] {
1325        self.as_ref()
1326    }
1327
1328    fn __repr__(&self) -> String {
1329        format!("{self:?}")
1330    }
1331
1332    #[getter]
1333    fn rtype(&self) -> PyResult<RType> {
1334        self.hd.rtype().map_err(to_py_err)
1335    }
1336
1337    #[getter]
1338    fn get_publisher_id(&self) -> u16 {
1339        self.hd.publisher_id
1340    }
1341    #[setter]
1342    fn set_publisher_id(&mut self, publisher_id: u16) {
1343        self.hd.publisher_id = publisher_id;
1344    }
1345
1346    #[getter]
1347    fn get_instrument_id(&self) -> u32 {
1348        self.hd.instrument_id
1349    }
1350    #[setter]
1351    fn set_instrument_id(&mut self, instrument_id: u32) {
1352        self.hd.instrument_id = instrument_id;
1353    }
1354
1355    #[getter]
1356    fn ts_event(&self) -> u64 {
1357        self.hd.ts_event
1358    }
1359    #[getter]
1360    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1361        new_py_timestamp_or_datetime(py, self.ts_event())
1362    }
1363    #[setter]
1364    fn set_ts_event(&mut self, ts_event: u64) {
1365        self.hd.ts_event = ts_event;
1366    }
1367
1368    #[pyo3(name = "record_size")]
1369    fn py_record_size(&self) -> usize {
1370        self.record_size()
1371    }
1372
1373    #[classattr]
1374    fn size_hint() -> PyResult<usize> {
1375        Ok(mem::size_of::<Self>())
1376    }
1377
1378    #[getter]
1379    fn ts_index(&self) -> u64 {
1380        self.raw_index_ts()
1381    }
1382    #[getter]
1383    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1384        new_py_timestamp_or_datetime(py, self.raw_index_ts())
1385    }
1386
1387    #[getter]
1388    fn get_pretty_open(&self) -> f64 {
1389        self.open_f64()
1390    }
1391
1392    #[getter]
1393    fn get_pretty_high(&self) -> f64 {
1394        self.high_f64()
1395    }
1396
1397    #[getter]
1398    fn get_pretty_low(&self) -> f64 {
1399        self.low_f64()
1400    }
1401
1402    #[getter]
1403    fn get_pretty_close(&self) -> f64 {
1404        self.close_f64()
1405    }
1406
1407    #[classattr]
1408    #[pyo3(name = "_dtypes")]
1409    fn py_dtypes() -> Vec<(String, String)> {
1410        Self::field_dtypes("")
1411    }
1412
1413    #[classattr]
1414    #[pyo3(name = "_price_fields")]
1415    fn py_price_fields() -> Vec<String> {
1416        Self::price_fields("")
1417    }
1418
1419    #[classattr]
1420    #[pyo3(name = "_timestamp_fields")]
1421    fn py_timestamp_fields() -> Vec<String> {
1422        Self::timestamp_fields("")
1423    }
1424
1425    #[classattr]
1426    #[pyo3(name = "_hidden_fields")]
1427    fn py_hidden_fields() -> Vec<String> {
1428        Self::hidden_fields("")
1429    }
1430
1431    #[classattr]
1432    #[pyo3(name = "_ordered_fields")]
1433    fn py_ordered_fields() -> Vec<String> {
1434        Self::ordered_fields("")
1435    }
1436}
1437
1438#[pymethods]
1439impl StatusMsg {
1440    #[new]
1441    #[pyo3(signature = (
1442        publisher_id,
1443        instrument_id,
1444        ts_event,
1445        ts_recv,
1446        action = None,
1447        reason = None,
1448        trading_event = None,
1449        is_trading = None,
1450        is_quoting = None,
1451        is_short_sell_restricted = None,
1452    ))]
1453    fn py_new(
1454        publisher_id: u16,
1455        instrument_id: u32,
1456        ts_event: u64,
1457        ts_recv: u64,
1458        action: Option<StatusAction>,
1459        reason: Option<StatusReason>,
1460        trading_event: Option<TradingEvent>,
1461        is_trading: Option<TriState>,
1462        is_quoting: Option<TriState>,
1463        is_short_sell_restricted: Option<TriState>,
1464    ) -> PyResult<Self> {
1465        Ok(Self {
1466            hd: RecordHeader::new::<Self>(rtype::STATUS, publisher_id, instrument_id, ts_event),
1467            ts_recv,
1468            action: action.unwrap_or_default() as u16,
1469            reason: reason.unwrap_or_default() as u16,
1470            trading_event: trading_event.unwrap_or_default() as u16,
1471            is_trading: is_trading.unwrap_or_default() as u8 as c_char,
1472            is_quoting: is_quoting.unwrap_or_default() as u8 as c_char,
1473            is_short_sell_restricted: is_short_sell_restricted.unwrap_or_default() as u8 as c_char,
1474            _reserved: Default::default(),
1475        })
1476    }
1477
1478    fn __bytes__(&self) -> &[u8] {
1479        self.as_ref()
1480    }
1481
1482    fn __repr__(&self) -> String {
1483        format!("{self:?}")
1484    }
1485
1486    #[getter]
1487    fn rtype(&self) -> PyResult<RType> {
1488        self.hd.rtype().map_err(to_py_err)
1489    }
1490
1491    #[getter]
1492    fn get_publisher_id(&self) -> u16 {
1493        self.hd.publisher_id
1494    }
1495    #[setter]
1496    fn set_publisher_id(&mut self, publisher_id: u16) {
1497        self.hd.publisher_id = publisher_id;
1498    }
1499
1500    #[getter]
1501    fn get_instrument_id(&self) -> u32 {
1502        self.hd.instrument_id
1503    }
1504    #[setter]
1505    fn set_instrument_id(&mut self, instrument_id: u32) {
1506        self.hd.instrument_id = instrument_id;
1507    }
1508
1509    #[getter]
1510    fn ts_event(&self) -> u64 {
1511        self.hd.ts_event
1512    }
1513    #[getter]
1514    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1515        new_py_timestamp_or_datetime(py, self.ts_event())
1516    }
1517    #[setter]
1518    fn set_ts_event(&mut self, ts_event: u64) {
1519        self.hd.ts_event = ts_event;
1520    }
1521
1522    #[pyo3(name = "record_size")]
1523    fn py_record_size(&self) -> usize {
1524        self.record_size()
1525    }
1526
1527    #[classattr]
1528    fn size_hint() -> PyResult<usize> {
1529        Ok(mem::size_of::<Self>())
1530    }
1531
1532    #[getter]
1533    fn ts_index(&self) -> u64 {
1534        self.raw_index_ts()
1535    }
1536    #[getter]
1537    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1538        new_py_timestamp_or_datetime(py, self.raw_index_ts())
1539    }
1540
1541    #[getter]
1542    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1543        new_py_timestamp_or_datetime(py, self.ts_recv)
1544    }
1545
1546    #[getter]
1547    fn get_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
1548        self.action()
1549            .map(|c| c.into_bound_py_any(py))
1550            .unwrap_or_else(|_| self.action.into_bound_py_any(py))
1551    }
1552    #[setter]
1553    fn set_action(&mut self, action: StatusAction) {
1554        self.action = action as u16;
1555    }
1556
1557    #[getter]
1558    fn get_reason<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
1559        self.reason()
1560            .map(|c| c.into_bound_py_any(py))
1561            .unwrap_or_else(|_| self.reason.into_bound_py_any(py))
1562    }
1563    #[setter]
1564    fn set_reason(&mut self, reason: StatusReason) {
1565        self.reason = reason as u16;
1566    }
1567
1568    #[getter]
1569    fn get_trading_event<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
1570        self.trading_event()
1571            .map(|c| c.into_bound_py_any(py))
1572            .unwrap_or_else(|_| self.trading_event.into_bound_py_any(py))
1573    }
1574    #[setter]
1575    fn set_trading_event(&mut self, trading_event: TradingEvent) {
1576        self.trading_event = trading_event as u16;
1577    }
1578
1579    #[getter]
1580    fn get_is_trading(&self) -> Option<bool> {
1581        self.is_trading()
1582    }
1583
1584    #[getter]
1585    fn get_is_quoting(&self) -> Option<bool> {
1586        self.is_quoting()
1587    }
1588
1589    #[getter]
1590    fn get_is_short_sell_restricted(&self) -> Option<bool> {
1591        self.is_short_sell_restricted()
1592    }
1593
1594    #[classattr]
1595    #[pyo3(name = "_dtypes")]
1596    fn py_dtypes() -> Vec<(String, String)> {
1597        Self::field_dtypes("")
1598    }
1599
1600    #[classattr]
1601    #[pyo3(name = "_price_fields")]
1602    fn py_price_fields() -> Vec<String> {
1603        Self::price_fields("")
1604    }
1605
1606    #[classattr]
1607    #[pyo3(name = "_timestamp_fields")]
1608    fn py_timestamp_fields() -> Vec<String> {
1609        Self::timestamp_fields("")
1610    }
1611
1612    #[classattr]
1613    #[pyo3(name = "_hidden_fields")]
1614    fn py_hidden_fields() -> Vec<String> {
1615        Self::hidden_fields("")
1616    }
1617
1618    #[classattr]
1619    #[pyo3(name = "_ordered_fields")]
1620    fn py_ordered_fields() -> Vec<String> {
1621        Self::ordered_fields("")
1622    }
1623}
1624
1625#[pymethods]
1626impl InstrumentDefMsg {
1627    #[new]
1628    #[pyo3(signature = (
1629        publisher_id,
1630        instrument_id,
1631        ts_event,
1632        ts_recv,
1633        min_price_increment,
1634        display_factor,
1635        raw_symbol,
1636        asset,
1637        security_type,
1638        instrument_class,
1639        security_update_action,
1640        expiration = UNDEF_TIMESTAMP,
1641        activation = UNDEF_TIMESTAMP,
1642        high_limit_price = UNDEF_PRICE,
1643        low_limit_price = UNDEF_PRICE,
1644        max_price_variation = UNDEF_PRICE,
1645        unit_of_measure_qty = UNDEF_PRICE,
1646        min_price_increment_amount = UNDEF_PRICE,
1647        price_ratio = UNDEF_PRICE,
1648        strike_price = UNDEF_PRICE,
1649        raw_instrument_id = 0,
1650        leg_price = UNDEF_PRICE,
1651        leg_delta = UNDEF_PRICE,
1652        inst_attrib_value = None,
1653        underlying_id = 0,
1654        market_depth_implied = None,
1655        market_depth = None,
1656        market_segment_id = None,
1657        max_trade_vol = None,
1658        min_lot_size = None,
1659        min_lot_size_block = None,
1660        min_lot_size_round_lot = None,
1661        min_trade_vol = None,
1662        contract_multiplier = None,
1663        decay_quantity = None,
1664        original_contract_size = None,
1665        leg_instrument_id = 0,
1666        leg_ratio_price_numerator = 0,
1667        leg_ratio_price_denominator = 0,
1668        leg_ratio_qty_numerator = 0,
1669        leg_ratio_qty_denominator = 0,
1670        leg_underlying_id = 0,
1671        appl_id = None,
1672        maturity_year = None,
1673        decay_start_date = None,
1674        channel_id = None,
1675        leg_count = 0,
1676        leg_index = 0,
1677        currency = "",
1678        settl_currency = "",
1679        secsubtype = "",
1680        group = "",
1681        exchange = "",
1682        cfi = "",
1683        unit_of_measure = "",
1684        underlying = "",
1685        strike_price_currency = "",
1686        leg_raw_symbol = "",
1687        match_algorithm = None,
1688        main_fraction = None,
1689        price_display_format = None,
1690        sub_fraction = None,
1691        underlying_product = None,
1692        maturity_month = None,
1693        maturity_day = None,
1694        maturity_week = None,
1695        user_defined_instrument = None,
1696        contract_multiplier_unit = None,
1697        flow_schedule_type = None,
1698        tick_rule = None,
1699        leg_instrument_class = None,
1700        leg_side = None,
1701    ))]
1702    fn py_new(
1703        publisher_id: u16,
1704        instrument_id: u32,
1705        ts_event: u64,
1706        ts_recv: u64,
1707        min_price_increment: i64,
1708        display_factor: i64,
1709        raw_symbol: &str,
1710        asset: &str,
1711        security_type: &str,
1712        instrument_class: InstrumentClass,
1713        security_update_action: SecurityUpdateAction,
1714        expiration: u64,
1715        activation: u64,
1716        high_limit_price: i64,
1717        low_limit_price: i64,
1718        max_price_variation: i64,
1719        unit_of_measure_qty: i64,
1720        min_price_increment_amount: i64,
1721        price_ratio: i64,
1722        strike_price: i64,
1723        raw_instrument_id: u64,
1724        leg_price: i64,
1725        leg_delta: i64,
1726        inst_attrib_value: Option<i32>,
1727        underlying_id: u32,
1728        market_depth_implied: Option<i32>,
1729        market_depth: Option<i32>,
1730        market_segment_id: Option<u32>,
1731        max_trade_vol: Option<u32>,
1732        min_lot_size: Option<i32>,
1733        min_lot_size_block: Option<i32>,
1734        min_lot_size_round_lot: Option<i32>,
1735        min_trade_vol: Option<u32>,
1736        contract_multiplier: Option<i32>,
1737        decay_quantity: Option<i32>,
1738        original_contract_size: Option<i32>,
1739        leg_instrument_id: u32,
1740        leg_ratio_price_numerator: i32,
1741        leg_ratio_price_denominator: i32,
1742        leg_ratio_qty_numerator: i32,
1743        leg_ratio_qty_denominator: i32,
1744        leg_underlying_id: u32,
1745        appl_id: Option<i16>,
1746        maturity_year: Option<u16>,
1747        decay_start_date: Option<u16>,
1748        channel_id: Option<u16>,
1749        leg_count: u16,
1750        leg_index: u16,
1751        currency: &str,
1752        settl_currency: &str,
1753        secsubtype: &str,
1754        group: &str,
1755        exchange: &str,
1756        cfi: &str,
1757        unit_of_measure: &str,
1758        underlying: &str,
1759        strike_price_currency: &str,
1760        leg_raw_symbol: &str,
1761        match_algorithm: Option<MatchAlgorithm>,
1762        main_fraction: Option<u8>,
1763        price_display_format: Option<u8>,
1764        sub_fraction: Option<u8>,
1765        underlying_product: Option<u8>,
1766        maturity_month: Option<u8>,
1767        maturity_day: Option<u8>,
1768        maturity_week: Option<u8>,
1769        user_defined_instrument: Option<UserDefinedInstrument>,
1770        contract_multiplier_unit: Option<i8>,
1771        flow_schedule_type: Option<i8>,
1772        tick_rule: Option<u8>,
1773        leg_instrument_class: Option<InstrumentClass>,
1774        leg_side: Option<Side>,
1775    ) -> PyResult<Self> {
1776        Ok(Self {
1777            hd: RecordHeader::new::<Self>(
1778                rtype::INSTRUMENT_DEF,
1779                publisher_id,
1780                instrument_id,
1781                ts_event,
1782            ),
1783            ts_recv,
1784            min_price_increment,
1785            display_factor,
1786            expiration,
1787            activation,
1788            high_limit_price,
1789            low_limit_price,
1790            max_price_variation,
1791            unit_of_measure_qty,
1792            min_price_increment_amount,
1793            price_ratio,
1794            strike_price,
1795            raw_instrument_id,
1796            leg_price,
1797            leg_delta,
1798            inst_attrib_value: inst_attrib_value.unwrap_or(i32::MAX),
1799            underlying_id,
1800            market_depth_implied: market_depth_implied.unwrap_or(i32::MAX),
1801            market_depth: market_depth.unwrap_or(i32::MAX),
1802            market_segment_id: market_segment_id.unwrap_or(u32::MAX),
1803            max_trade_vol: max_trade_vol.unwrap_or(u32::MAX),
1804            min_lot_size: min_lot_size.unwrap_or(i32::MAX),
1805            min_lot_size_block: min_lot_size_block.unwrap_or(i32::MAX),
1806            min_lot_size_round_lot: min_lot_size_round_lot.unwrap_or(i32::MAX),
1807            min_trade_vol: min_trade_vol.unwrap_or(u32::MAX),
1808            contract_multiplier: contract_multiplier.unwrap_or(i32::MAX),
1809            decay_quantity: decay_quantity.unwrap_or(i32::MAX),
1810            original_contract_size: original_contract_size.unwrap_or(i32::MAX),
1811            leg_instrument_id,
1812            leg_ratio_price_numerator,
1813            leg_ratio_price_denominator,
1814            leg_ratio_qty_numerator,
1815            leg_ratio_qty_denominator,
1816            leg_underlying_id,
1817            appl_id: appl_id.unwrap_or(i16::MAX),
1818            maturity_year: maturity_year.unwrap_or(u16::MAX),
1819            decay_start_date: decay_start_date.unwrap_or(u16::MAX),
1820            channel_id: channel_id.unwrap_or(u16::MAX),
1821            leg_count,
1822            leg_index,
1823            currency: str_to_c_chars(currency)?,
1824            settl_currency: str_to_c_chars(settl_currency)?,
1825            secsubtype: str_to_c_chars(secsubtype)?,
1826            raw_symbol: str_to_c_chars(raw_symbol)?,
1827            group: str_to_c_chars(group)?,
1828            exchange: str_to_c_chars(exchange)?,
1829            asset: str_to_c_chars(asset)?,
1830            cfi: str_to_c_chars(cfi)?,
1831            security_type: str_to_c_chars(security_type)?,
1832            unit_of_measure: str_to_c_chars(unit_of_measure)?,
1833            underlying: str_to_c_chars(underlying)?,
1834            strike_price_currency: str_to_c_chars(strike_price_currency)?,
1835            leg_raw_symbol: str_to_c_chars(leg_raw_symbol)?,
1836            instrument_class: instrument_class as u8 as c_char,
1837            match_algorithm: match_algorithm.unwrap_or_default() as u8 as c_char,
1838            main_fraction: main_fraction.unwrap_or(u8::MAX),
1839            price_display_format: price_display_format.unwrap_or(u8::MAX),
1840            sub_fraction: sub_fraction.unwrap_or(u8::MAX),
1841            underlying_product: underlying_product.unwrap_or(u8::MAX),
1842            security_update_action: security_update_action as u8 as c_char,
1843            maturity_month: maturity_month.unwrap_or(u8::MAX),
1844            maturity_day: maturity_day.unwrap_or(u8::MAX),
1845            maturity_week: maturity_week.unwrap_or(u8::MAX),
1846            user_defined_instrument: user_defined_instrument.unwrap_or_default() as u8 as c_char,
1847            contract_multiplier_unit: contract_multiplier_unit.unwrap_or(i8::MAX),
1848            flow_schedule_type: flow_schedule_type.unwrap_or(i8::MAX),
1849            tick_rule: tick_rule.unwrap_or(u8::MAX),
1850            leg_instrument_class: leg_instrument_class
1851                .map(|leg_instrument_class| leg_instrument_class as u8 as c_char)
1852                .unwrap_or_default(),
1853            leg_side: leg_side.unwrap_or_default() as u8 as c_char,
1854            _reserved: Default::default(),
1855        })
1856    }
1857
1858    fn __bytes__(&self) -> &[u8] {
1859        self.as_ref()
1860    }
1861
1862    fn __repr__(&self) -> String {
1863        format!("{self:?}")
1864    }
1865
1866    #[getter]
1867    fn rtype(&self) -> PyResult<RType> {
1868        self.hd.rtype().map_err(to_py_err)
1869    }
1870
1871    #[getter]
1872    fn get_publisher_id(&self) -> u16 {
1873        self.hd.publisher_id
1874    }
1875    #[setter]
1876    fn set_publisher_id(&mut self, publisher_id: u16) {
1877        self.hd.publisher_id = publisher_id;
1878    }
1879
1880    #[getter]
1881    fn get_instrument_id(&self) -> u32 {
1882        self.hd.instrument_id
1883    }
1884    #[setter]
1885    fn set_instrument_id(&mut self, instrument_id: u32) {
1886        self.hd.instrument_id = instrument_id;
1887    }
1888
1889    #[getter]
1890    fn ts_event(&self) -> u64 {
1891        self.hd.ts_event
1892    }
1893    #[getter]
1894    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1895        new_py_timestamp_or_datetime(py, self.ts_event())
1896    }
1897    #[setter]
1898    fn set_ts_event(&mut self, ts_event: u64) {
1899        self.hd.ts_event = ts_event;
1900    }
1901
1902    #[pyo3(name = "record_size")]
1903    fn py_record_size(&self) -> usize {
1904        self.record_size()
1905    }
1906
1907    #[classattr]
1908    fn size_hint() -> PyResult<usize> {
1909        Ok(mem::size_of::<Self>())
1910    }
1911
1912    #[getter]
1913    fn ts_index(&self) -> u64 {
1914        self.raw_index_ts()
1915    }
1916    #[getter]
1917    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1918        new_py_timestamp_or_datetime(py, self.raw_index_ts())
1919    }
1920
1921    #[getter]
1922    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1923        new_py_timestamp_or_datetime(py, self.ts_recv)
1924    }
1925
1926    #[getter]
1927    fn get_pretty_min_price_increment(&self) -> f64 {
1928        self.min_price_increment_f64()
1929    }
1930
1931    #[getter]
1932    fn get_pretty_display_factor(&self) -> f64 {
1933        self.display_factor_f64()
1934    }
1935
1936    #[getter]
1937    fn get_pretty_expiration<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1938        new_py_timestamp_or_datetime(py, self.expiration)
1939    }
1940
1941    #[getter]
1942    fn get_pretty_activation<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
1943        new_py_timestamp_or_datetime(py, self.activation)
1944    }
1945
1946    #[getter]
1947    fn get_pretty_high_limit_price(&self) -> f64 {
1948        self.high_limit_price_f64()
1949    }
1950
1951    #[getter]
1952    fn get_pretty_low_limit_price(&self) -> f64 {
1953        self.low_limit_price_f64()
1954    }
1955
1956    #[getter]
1957    fn get_pretty_max_price_variation(&self) -> f64 {
1958        self.max_price_variation_f64()
1959    }
1960
1961    #[getter]
1962    fn get_pretty_unit_of_measure_qty(&self) -> f64 {
1963        self.unit_of_measure_qty_f64()
1964    }
1965
1966    #[getter]
1967    fn get_pretty_min_price_increment_amount(&self) -> f64 {
1968        self.min_price_increment_amount_f64()
1969    }
1970
1971    #[getter]
1972    fn get_pretty_price_ratio(&self) -> f64 {
1973        self.price_ratio_f64()
1974    }
1975
1976    #[getter]
1977    fn get_pretty_strike_price(&self) -> f64 {
1978        self.strike_price_f64()
1979    }
1980
1981    #[getter]
1982    fn get_pretty_leg_price(&self) -> f64 {
1983        self.leg_price_f64()
1984    }
1985
1986    #[getter]
1987    fn get_pretty_leg_delta(&self) -> f64 {
1988        self.leg_delta_f64()
1989    }
1990
1991    #[getter]
1992    fn get_currency(&self) -> PyResult<&str> {
1993        Ok(self.currency()?)
1994    }
1995
1996    #[getter]
1997    fn get_settl_currency(&self) -> PyResult<&str> {
1998        Ok(self.settl_currency()?)
1999    }
2000
2001    #[getter]
2002    fn get_secsubtype(&self) -> PyResult<&str> {
2003        Ok(self.secsubtype()?)
2004    }
2005
2006    #[getter]
2007    fn get_raw_symbol(&self) -> PyResult<&str> {
2008        Ok(self.raw_symbol()?)
2009    }
2010
2011    #[getter]
2012    fn get_group(&self) -> PyResult<&str> {
2013        Ok(self.group()?)
2014    }
2015
2016    #[getter]
2017    fn get_exchange(&self) -> PyResult<&str> {
2018        Ok(self.exchange()?)
2019    }
2020
2021    #[getter]
2022    fn get_asset(&self) -> PyResult<&str> {
2023        Ok(self.asset()?)
2024    }
2025
2026    #[getter]
2027    fn get_cfi(&self) -> PyResult<&str> {
2028        Ok(self.cfi()?)
2029    }
2030
2031    #[getter]
2032    fn get_security_type(&self) -> PyResult<&str> {
2033        Ok(self.security_type()?)
2034    }
2035
2036    #[getter]
2037    fn get_unit_of_measure(&self) -> PyResult<&str> {
2038        Ok(self.unit_of_measure()?)
2039    }
2040
2041    #[getter]
2042    fn get_underlying(&self) -> PyResult<&str> {
2043        Ok(self.underlying()?)
2044    }
2045
2046    #[getter]
2047    fn get_strike_price_currency(&self) -> PyResult<&str> {
2048        Ok(self.strike_price_currency()?)
2049    }
2050
2051    #[getter]
2052    fn get_leg_raw_symbol(&self) -> PyResult<&str> {
2053        Ok(self.leg_raw_symbol()?)
2054    }
2055
2056    #[getter]
2057    fn get_instrument_class<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2058        self.instrument_class()
2059            .map(|c| c.into_bound_py_any(py))
2060            .unwrap_or_else(|_| (self.instrument_class as u8 as char).into_bound_py_any(py))
2061    }
2062    #[setter]
2063    fn set_instrument_class(&mut self, instrument_class: InstrumentClass) {
2064        self.instrument_class = instrument_class as u8 as c_char;
2065    }
2066
2067    #[getter]
2068    fn get_match_algorithm<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2069        self.match_algorithm()
2070            .map(|c| c.into_bound_py_any(py))
2071            .unwrap_or_else(|_| (self.match_algorithm as u8 as char).into_bound_py_any(py))
2072    }
2073    #[setter]
2074    fn set_match_algorithm(&mut self, match_algorithm: MatchAlgorithm) {
2075        self.match_algorithm = match_algorithm as u8 as c_char;
2076    }
2077
2078    #[getter]
2079    fn get_security_update_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2080        self.security_update_action()
2081            .map(|c| c.into_bound_py_any(py))
2082            .unwrap_or_else(|_| (self.security_update_action as u8 as char).into_bound_py_any(py))
2083    }
2084    #[setter]
2085    fn set_security_update_action(&mut self, security_update_action: SecurityUpdateAction) {
2086        self.security_update_action = security_update_action as u8 as c_char;
2087    }
2088
2089    #[getter]
2090    fn get_user_defined_instrument<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2091        self.user_defined_instrument()
2092            .map(|c| c.into_bound_py_any(py))
2093            .unwrap_or_else(|_| (self.user_defined_instrument as u8 as char).into_bound_py_any(py))
2094    }
2095    #[setter]
2096    fn set_user_defined_instrument(&mut self, user_defined_instrument: UserDefinedInstrument) {
2097        self.user_defined_instrument = user_defined_instrument as u8 as c_char;
2098    }
2099
2100    #[getter]
2101    fn get_leg_instrument_class<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2102        self.leg_instrument_class()
2103            .map(|c| c.into_bound_py_any(py))
2104            .unwrap_or_else(|_| (self.leg_instrument_class as u8 as char).into_bound_py_any(py))
2105    }
2106    #[setter]
2107    fn set_leg_instrument_class(&mut self, leg_instrument_class: InstrumentClass) {
2108        self.leg_instrument_class = leg_instrument_class as u8 as c_char;
2109    }
2110
2111    #[getter]
2112    fn get_leg_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2113        self.leg_side()
2114            .map(|c| c.into_bound_py_any(py))
2115            .unwrap_or_else(|_| (self.leg_side as u8 as char).into_bound_py_any(py))
2116    }
2117    #[setter]
2118    fn set_leg_side(&mut self, leg_side: Side) {
2119        self.leg_side = leg_side as u8 as c_char;
2120    }
2121
2122    #[classattr]
2123    #[pyo3(name = "_dtypes")]
2124    fn py_dtypes() -> Vec<(String, String)> {
2125        Self::field_dtypes("")
2126    }
2127
2128    #[classattr]
2129    #[pyo3(name = "_price_fields")]
2130    fn py_price_fields() -> Vec<String> {
2131        Self::price_fields("")
2132    }
2133
2134    #[classattr]
2135    #[pyo3(name = "_timestamp_fields")]
2136    fn py_timestamp_fields() -> Vec<String> {
2137        Self::timestamp_fields("")
2138    }
2139
2140    #[classattr]
2141    #[pyo3(name = "_hidden_fields")]
2142    fn py_hidden_fields() -> Vec<String> {
2143        Self::hidden_fields("")
2144    }
2145
2146    #[classattr]
2147    #[pyo3(name = "_ordered_fields")]
2148    fn py_ordered_fields() -> Vec<String> {
2149        Self::ordered_fields("")
2150    }
2151}
2152
2153#[pymethods]
2154impl ImbalanceMsg {
2155    #[new]
2156    #[pyo3(signature = (
2157        publisher_id,
2158        instrument_id,
2159        ts_event,
2160        ts_recv,
2161        ref_price,
2162        auction_time,
2163        cont_book_clr_price,
2164        auct_interest_clr_price,
2165        paired_qty,
2166        total_imbalance_qty,
2167        auction_type,
2168        side,
2169        significant_imbalance,
2170        ssr_filling_price = UNDEF_PRICE,
2171        ind_match_price = UNDEF_PRICE,
2172        upper_collar = UNDEF_PRICE,
2173        lower_collar = UNDEF_PRICE,
2174        market_imbalance_qty = UNDEF_ORDER_SIZE,
2175        unpaired_qty = UNDEF_ORDER_SIZE,
2176        auction_status = 0,
2177        freeze_status = 0,
2178        num_extensions = 0,
2179        unpaired_side = None,
2180    ))]
2181    fn py_new(
2182        publisher_id: u16,
2183        instrument_id: u32,
2184        ts_event: u64,
2185        ts_recv: u64,
2186        ref_price: i64,
2187        auction_time: u64,
2188        cont_book_clr_price: i64,
2189        auct_interest_clr_price: i64,
2190        paired_qty: u32,
2191        total_imbalance_qty: u32,
2192        auction_type: char,
2193        side: Side,
2194        significant_imbalance: char,
2195        ssr_filling_price: i64,
2196        ind_match_price: i64,
2197        upper_collar: i64,
2198        lower_collar: i64,
2199        market_imbalance_qty: u32,
2200        unpaired_qty: u32,
2201        auction_status: u8,
2202        freeze_status: u8,
2203        num_extensions: u8,
2204        unpaired_side: Option<Side>,
2205    ) -> PyResult<Self> {
2206        Ok(Self {
2207            hd: RecordHeader::new::<Self>(rtype::IMBALANCE, publisher_id, instrument_id, ts_event),
2208            ts_recv,
2209            ref_price,
2210            auction_time,
2211            cont_book_clr_price,
2212            auct_interest_clr_price,
2213            ssr_filling_price,
2214            ind_match_price,
2215            upper_collar,
2216            lower_collar,
2217            paired_qty,
2218            total_imbalance_qty,
2219            market_imbalance_qty,
2220            unpaired_qty,
2221            auction_type: char_to_c_char(auction_type)?,
2222            side: side as u8 as c_char,
2223            auction_status,
2224            freeze_status,
2225            num_extensions,
2226            unpaired_side: unpaired_side.unwrap_or_default() as u8 as c_char,
2227
2228            significant_imbalance: char_to_c_char(significant_imbalance)?,
2229            _reserved: Default::default(),
2230        })
2231    }
2232
2233    fn __bytes__(&self) -> &[u8] {
2234        self.as_ref()
2235    }
2236
2237    fn __repr__(&self) -> String {
2238        format!("{self:?}")
2239    }
2240
2241    #[getter]
2242    fn rtype(&self) -> PyResult<RType> {
2243        self.hd.rtype().map_err(to_py_err)
2244    }
2245
2246    #[getter]
2247    fn get_publisher_id(&self) -> u16 {
2248        self.hd.publisher_id
2249    }
2250    #[setter]
2251    fn set_publisher_id(&mut self, publisher_id: u16) {
2252        self.hd.publisher_id = publisher_id;
2253    }
2254
2255    #[getter]
2256    fn get_instrument_id(&self) -> u32 {
2257        self.hd.instrument_id
2258    }
2259    #[setter]
2260    fn set_instrument_id(&mut self, instrument_id: u32) {
2261        self.hd.instrument_id = instrument_id;
2262    }
2263
2264    #[getter]
2265    fn ts_event(&self) -> u64 {
2266        self.hd.ts_event
2267    }
2268    #[getter]
2269    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2270        new_py_timestamp_or_datetime(py, self.ts_event())
2271    }
2272    #[setter]
2273    fn set_ts_event(&mut self, ts_event: u64) {
2274        self.hd.ts_event = ts_event;
2275    }
2276
2277    #[pyo3(name = "record_size")]
2278    fn py_record_size(&self) -> usize {
2279        self.record_size()
2280    }
2281
2282    #[classattr]
2283    fn size_hint() -> PyResult<usize> {
2284        Ok(mem::size_of::<Self>())
2285    }
2286
2287    #[getter]
2288    fn ts_index(&self) -> u64 {
2289        self.raw_index_ts()
2290    }
2291    #[getter]
2292    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2293        new_py_timestamp_or_datetime(py, self.raw_index_ts())
2294    }
2295
2296    #[getter]
2297    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2298        new_py_timestamp_or_datetime(py, self.ts_recv)
2299    }
2300
2301    #[getter]
2302    fn get_pretty_ref_price(&self) -> f64 {
2303        self.ref_price_f64()
2304    }
2305
2306    #[getter]
2307    fn get_pretty_auction_time<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2308        new_py_timestamp_or_datetime(py, self.auction_time)
2309    }
2310
2311    #[getter]
2312    fn get_pretty_cont_book_clr_price(&self) -> f64 {
2313        self.cont_book_clr_price_f64()
2314    }
2315
2316    #[getter]
2317    fn get_pretty_auct_interest_clr_price(&self) -> f64 {
2318        self.auct_interest_clr_price_f64()
2319    }
2320
2321    #[getter]
2322    fn get_pretty_ssr_filling_price(&self) -> f64 {
2323        self.ssr_filling_price_f64()
2324    }
2325
2326    #[getter]
2327    fn get_pretty_ind_match_price(&self) -> f64 {
2328        self.ind_match_price_f64()
2329    }
2330
2331    #[getter]
2332    fn get_pretty_upper_collar(&self) -> f64 {
2333        self.upper_collar_f64()
2334    }
2335
2336    #[getter]
2337    fn get_pretty_lower_collar(&self) -> f64 {
2338        self.lower_collar_f64()
2339    }
2340
2341    #[getter]
2342    fn get_auction_type(&self) -> char {
2343        self.auction_type as u8 as char
2344    }
2345    #[setter]
2346    fn set_auction_type(&mut self, auction_type: char) -> PyResult<()> {
2347        self.auction_type = char_to_c_char(auction_type)?;
2348        Ok(())
2349    }
2350
2351    #[getter]
2352    fn get_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2353        self.side()
2354            .map(|c| c.into_bound_py_any(py))
2355            .unwrap_or_else(|_| (self.side as u8 as char).into_bound_py_any(py))
2356    }
2357    #[setter]
2358    fn set_side(&mut self, side: Side) {
2359        self.side = side as u8 as c_char;
2360    }
2361
2362    #[getter]
2363    fn get_unpaired_side<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2364        self.unpaired_side()
2365            .map(|c| c.into_bound_py_any(py))
2366            .unwrap_or_else(|_| (self.unpaired_side as u8 as char).into_bound_py_any(py))
2367    }
2368    #[setter]
2369    fn set_unpaired_side(&mut self, unpaired_side: Side) {
2370        self.unpaired_side = unpaired_side as u8 as c_char;
2371    }
2372
2373    #[getter]
2374    fn get_significant_imbalance(&self) -> char {
2375        self.significant_imbalance as u8 as char
2376    }
2377    #[setter]
2378    fn set_significant_imbalance(&mut self, significant_imbalance: char) -> PyResult<()> {
2379        self.significant_imbalance = char_to_c_char(significant_imbalance)?;
2380        Ok(())
2381    }
2382
2383    #[classattr]
2384    #[pyo3(name = "_dtypes")]
2385    fn py_dtypes() -> Vec<(String, String)> {
2386        Self::field_dtypes("")
2387    }
2388
2389    #[classattr]
2390    #[pyo3(name = "_price_fields")]
2391    fn py_price_fields() -> Vec<String> {
2392        Self::price_fields("")
2393    }
2394
2395    #[classattr]
2396    #[pyo3(name = "_timestamp_fields")]
2397    fn py_timestamp_fields() -> Vec<String> {
2398        Self::timestamp_fields("")
2399    }
2400
2401    #[classattr]
2402    #[pyo3(name = "_hidden_fields")]
2403    fn py_hidden_fields() -> Vec<String> {
2404        Self::hidden_fields("")
2405    }
2406
2407    #[classattr]
2408    #[pyo3(name = "_ordered_fields")]
2409    fn py_ordered_fields() -> Vec<String> {
2410        Self::ordered_fields("")
2411    }
2412}
2413
2414#[pymethods]
2415impl StatMsg {
2416    #[new]
2417    #[pyo3(signature = (
2418        publisher_id,
2419        instrument_id,
2420        ts_event,
2421        ts_recv,
2422        ts_ref,
2423        price,
2424        quantity,
2425        stat_type,
2426        sequence = 0,
2427        ts_in_delta = 0,
2428        channel_id = None,
2429        update_action = None,
2430        stat_flags = 0,
2431    ))]
2432    fn py_new(
2433        publisher_id: u16,
2434        instrument_id: u32,
2435        ts_event: u64,
2436        ts_recv: u64,
2437        ts_ref: u64,
2438        price: i64,
2439        quantity: i64,
2440        stat_type: StatType,
2441        sequence: u32,
2442        ts_in_delta: i32,
2443        channel_id: Option<u16>,
2444        update_action: Option<StatUpdateAction>,
2445        stat_flags: u8,
2446    ) -> PyResult<Self> {
2447        Ok(Self {
2448            hd: RecordHeader::new::<Self>(rtype::STATISTICS, publisher_id, instrument_id, ts_event),
2449            ts_recv,
2450            ts_ref,
2451            price,
2452            quantity,
2453            sequence,
2454            ts_in_delta,
2455            stat_type: stat_type as u16,
2456            channel_id: channel_id.unwrap_or(u16::MAX),
2457            update_action: update_action.unwrap_or_default() as u8,
2458            stat_flags,
2459            _reserved: Default::default(),
2460        })
2461    }
2462
2463    fn __bytes__(&self) -> &[u8] {
2464        self.as_ref()
2465    }
2466
2467    fn __repr__(&self) -> String {
2468        format!("{self:?}")
2469    }
2470
2471    #[getter]
2472    fn rtype(&self) -> PyResult<RType> {
2473        self.hd.rtype().map_err(to_py_err)
2474    }
2475
2476    #[getter]
2477    fn get_publisher_id(&self) -> u16 {
2478        self.hd.publisher_id
2479    }
2480    #[setter]
2481    fn set_publisher_id(&mut self, publisher_id: u16) {
2482        self.hd.publisher_id = publisher_id;
2483    }
2484
2485    #[getter]
2486    fn get_instrument_id(&self) -> u32 {
2487        self.hd.instrument_id
2488    }
2489    #[setter]
2490    fn set_instrument_id(&mut self, instrument_id: u32) {
2491        self.hd.instrument_id = instrument_id;
2492    }
2493
2494    #[getter]
2495    fn ts_event(&self) -> u64 {
2496        self.hd.ts_event
2497    }
2498    #[getter]
2499    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2500        new_py_timestamp_or_datetime(py, self.ts_event())
2501    }
2502    #[setter]
2503    fn set_ts_event(&mut self, ts_event: u64) {
2504        self.hd.ts_event = ts_event;
2505    }
2506
2507    #[pyo3(name = "record_size")]
2508    fn py_record_size(&self) -> usize {
2509        self.record_size()
2510    }
2511
2512    #[classattr]
2513    fn size_hint() -> PyResult<usize> {
2514        Ok(mem::size_of::<Self>())
2515    }
2516
2517    #[getter]
2518    fn ts_index(&self) -> u64 {
2519        self.raw_index_ts()
2520    }
2521    #[getter]
2522    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2523        new_py_timestamp_or_datetime(py, self.raw_index_ts())
2524    }
2525
2526    #[getter]
2527    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2528        new_py_timestamp_or_datetime(py, self.ts_recv)
2529    }
2530
2531    #[getter]
2532    fn get_pretty_ts_ref<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2533        new_py_timestamp_or_datetime(py, self.ts_ref)
2534    }
2535
2536    #[getter]
2537    fn get_pretty_price(&self) -> f64 {
2538        self.price_f64()
2539    }
2540
2541    #[getter]
2542    fn get_stat_type<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2543        self.stat_type()
2544            .map(|c| c.into_bound_py_any(py))
2545            .unwrap_or_else(|_| self.stat_type.into_bound_py_any(py))
2546    }
2547    #[setter]
2548    fn set_stat_type(&mut self, stat_type: StatType) {
2549        self.stat_type = stat_type as u16;
2550    }
2551
2552    #[getter]
2553    fn get_update_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2554        self.update_action()
2555            .map(|c| c.into_bound_py_any(py))
2556            .unwrap_or_else(|_| self.update_action.into_bound_py_any(py))
2557    }
2558    #[setter]
2559    fn set_update_action(&mut self, update_action: StatUpdateAction) {
2560        self.update_action = update_action as u8;
2561    }
2562
2563    #[classattr]
2564    #[pyo3(name = "_dtypes")]
2565    fn py_dtypes() -> Vec<(String, String)> {
2566        Self::field_dtypes("")
2567    }
2568
2569    #[classattr]
2570    #[pyo3(name = "_price_fields")]
2571    fn py_price_fields() -> Vec<String> {
2572        Self::price_fields("")
2573    }
2574
2575    #[classattr]
2576    #[pyo3(name = "_timestamp_fields")]
2577    fn py_timestamp_fields() -> Vec<String> {
2578        Self::timestamp_fields("")
2579    }
2580
2581    #[classattr]
2582    #[pyo3(name = "_hidden_fields")]
2583    fn py_hidden_fields() -> Vec<String> {
2584        Self::hidden_fields("")
2585    }
2586
2587    #[classattr]
2588    #[pyo3(name = "_ordered_fields")]
2589    fn py_ordered_fields() -> Vec<String> {
2590        Self::ordered_fields("")
2591    }
2592}
2593
2594#[pymethods]
2595impl ErrorMsg {
2596    #[new]
2597    #[pyo3(signature = (ts_event, err, is_last = true, code = None))]
2598    fn py_new(ts_event: u64, err: &str, is_last: bool, code: Option<ErrorCode>) -> PyResult<Self> {
2599        Ok(Self::new(ts_event, code, err, is_last))
2600    }
2601
2602    fn __bytes__(&self) -> &[u8] {
2603        self.as_ref()
2604    }
2605
2606    fn __repr__(&self) -> String {
2607        format!("{self:?}")
2608    }
2609
2610    #[getter]
2611    fn rtype(&self) -> PyResult<RType> {
2612        self.hd.rtype().map_err(to_py_err)
2613    }
2614
2615    #[getter]
2616    fn get_publisher_id(&self) -> u16 {
2617        self.hd.publisher_id
2618    }
2619    #[setter]
2620    fn set_publisher_id(&mut self, publisher_id: u16) {
2621        self.hd.publisher_id = publisher_id;
2622    }
2623
2624    #[getter]
2625    fn get_instrument_id(&self) -> u32 {
2626        self.hd.instrument_id
2627    }
2628    #[setter]
2629    fn set_instrument_id(&mut self, instrument_id: u32) {
2630        self.hd.instrument_id = instrument_id;
2631    }
2632
2633    #[getter]
2634    fn ts_event(&self) -> u64 {
2635        self.hd.ts_event
2636    }
2637    #[getter]
2638    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2639        new_py_timestamp_or_datetime(py, self.ts_event())
2640    }
2641    #[setter]
2642    fn set_ts_event(&mut self, ts_event: u64) {
2643        self.hd.ts_event = ts_event;
2644    }
2645
2646    #[pyo3(name = "record_size")]
2647    fn py_record_size(&self) -> usize {
2648        self.record_size()
2649    }
2650
2651    #[classattr]
2652    fn size_hint() -> PyResult<usize> {
2653        Ok(mem::size_of::<Self>())
2654    }
2655
2656    #[getter]
2657    fn ts_index(&self) -> u64 {
2658        self.raw_index_ts()
2659    }
2660    #[getter]
2661    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2662        new_py_timestamp_or_datetime(py, self.raw_index_ts())
2663    }
2664
2665    #[getter]
2666    fn get_err(&self) -> PyResult<&str> {
2667        Ok(self.err()?)
2668    }
2669
2670    #[getter]
2671    fn get_code<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2672        self.code()
2673            .map(|c| c.into_bound_py_any(py))
2674            .unwrap_or_else(|_| self.code.into_bound_py_any(py))
2675    }
2676    #[setter]
2677    fn set_code(&mut self, code: ErrorCode) {
2678        self.code = code as u8;
2679    }
2680
2681    #[classattr]
2682    #[pyo3(name = "_dtypes")]
2683    fn py_dtypes() -> Vec<(String, String)> {
2684        Self::field_dtypes("")
2685    }
2686
2687    #[classattr]
2688    #[pyo3(name = "_price_fields")]
2689    fn py_price_fields() -> Vec<String> {
2690        Self::price_fields("")
2691    }
2692
2693    #[classattr]
2694    #[pyo3(name = "_timestamp_fields")]
2695    fn py_timestamp_fields() -> Vec<String> {
2696        Self::timestamp_fields("")
2697    }
2698
2699    #[classattr]
2700    #[pyo3(name = "_hidden_fields")]
2701    fn py_hidden_fields() -> Vec<String> {
2702        Self::hidden_fields("")
2703    }
2704
2705    #[classattr]
2706    #[pyo3(name = "_ordered_fields")]
2707    fn py_ordered_fields() -> Vec<String> {
2708        Self::ordered_fields("")
2709    }
2710}
2711
2712#[pymethods]
2713impl SymbolMappingMsg {
2714    #[new]
2715    #[pyo3(signature = (
2716        publisher_id,
2717        instrument_id,
2718        ts_event,
2719        stype_in,
2720        stype_in_symbol,
2721        stype_out,
2722        stype_out_symbol,
2723        start_ts,
2724        end_ts,
2725    ))]
2726    fn py_new(
2727        publisher_id: u16,
2728        instrument_id: u32,
2729        ts_event: u64,
2730        stype_in: SType,
2731        stype_in_symbol: &str,
2732        stype_out: SType,
2733        stype_out_symbol: &str,
2734        start_ts: u64,
2735        end_ts: u64,
2736    ) -> PyResult<Self> {
2737        Ok(Self {
2738            hd: RecordHeader::new::<Self>(
2739                rtype::SYMBOL_MAPPING,
2740                publisher_id,
2741                instrument_id,
2742                ts_event,
2743            ),
2744            stype_in: stype_in as u8,
2745            stype_in_symbol: str_to_c_chars(stype_in_symbol)?,
2746            stype_out: stype_out as u8,
2747            stype_out_symbol: str_to_c_chars(stype_out_symbol)?,
2748            start_ts,
2749            end_ts,
2750        })
2751    }
2752
2753    fn __bytes__(&self) -> &[u8] {
2754        self.as_ref()
2755    }
2756
2757    fn __repr__(&self) -> String {
2758        format!("{self:?}")
2759    }
2760
2761    #[getter]
2762    fn rtype(&self) -> PyResult<RType> {
2763        self.hd.rtype().map_err(to_py_err)
2764    }
2765
2766    #[getter]
2767    fn get_publisher_id(&self) -> u16 {
2768        self.hd.publisher_id
2769    }
2770    #[setter]
2771    fn set_publisher_id(&mut self, publisher_id: u16) {
2772        self.hd.publisher_id = publisher_id;
2773    }
2774
2775    #[getter]
2776    fn get_instrument_id(&self) -> u32 {
2777        self.hd.instrument_id
2778    }
2779    #[setter]
2780    fn set_instrument_id(&mut self, instrument_id: u32) {
2781        self.hd.instrument_id = instrument_id;
2782    }
2783
2784    #[getter]
2785    fn ts_event(&self) -> u64 {
2786        self.hd.ts_event
2787    }
2788    #[getter]
2789    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2790        new_py_timestamp_or_datetime(py, self.ts_event())
2791    }
2792    #[setter]
2793    fn set_ts_event(&mut self, ts_event: u64) {
2794        self.hd.ts_event = ts_event;
2795    }
2796
2797    #[pyo3(name = "record_size")]
2798    fn py_record_size(&self) -> usize {
2799        self.record_size()
2800    }
2801
2802    #[classattr]
2803    fn size_hint() -> PyResult<usize> {
2804        Ok(mem::size_of::<Self>())
2805    }
2806
2807    #[getter]
2808    fn ts_index(&self) -> u64 {
2809        self.raw_index_ts()
2810    }
2811    #[getter]
2812    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2813        new_py_timestamp_or_datetime(py, self.raw_index_ts())
2814    }
2815
2816    #[getter]
2817    fn get_stype_in<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2818        self.stype_in()
2819            .map(|c| c.into_bound_py_any(py))
2820            .unwrap_or_else(|_| self.stype_in.into_bound_py_any(py))
2821    }
2822    #[setter]
2823    fn set_stype_in(&mut self, stype_in: SType) {
2824        self.stype_in = stype_in as u8;
2825    }
2826
2827    #[getter]
2828    fn get_stype_in_symbol(&self) -> PyResult<&str> {
2829        Ok(self.stype_in_symbol()?)
2830    }
2831
2832    #[getter]
2833    fn get_stype_out<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2834        self.stype_out()
2835            .map(|c| c.into_bound_py_any(py))
2836            .unwrap_or_else(|_| self.stype_out.into_bound_py_any(py))
2837    }
2838    #[setter]
2839    fn set_stype_out(&mut self, stype_out: SType) {
2840        self.stype_out = stype_out as u8;
2841    }
2842
2843    #[getter]
2844    fn get_stype_out_symbol(&self) -> PyResult<&str> {
2845        Ok(self.stype_out_symbol()?)
2846    }
2847
2848    #[getter]
2849    fn get_pretty_start_ts<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2850        new_py_timestamp_or_datetime(py, self.start_ts)
2851    }
2852
2853    #[getter]
2854    fn get_pretty_end_ts<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2855        new_py_timestamp_or_datetime(py, self.end_ts)
2856    }
2857
2858    #[classattr]
2859    #[pyo3(name = "_dtypes")]
2860    fn py_dtypes() -> Vec<(String, String)> {
2861        Self::field_dtypes("")
2862    }
2863
2864    #[classattr]
2865    #[pyo3(name = "_price_fields")]
2866    fn py_price_fields() -> Vec<String> {
2867        Self::price_fields("")
2868    }
2869
2870    #[classattr]
2871    #[pyo3(name = "_timestamp_fields")]
2872    fn py_timestamp_fields() -> Vec<String> {
2873        Self::timestamp_fields("")
2874    }
2875
2876    #[classattr]
2877    #[pyo3(name = "_hidden_fields")]
2878    fn py_hidden_fields() -> Vec<String> {
2879        Self::hidden_fields("")
2880    }
2881
2882    #[classattr]
2883    #[pyo3(name = "_ordered_fields")]
2884    fn py_ordered_fields() -> Vec<String> {
2885        Self::ordered_fields("")
2886    }
2887}
2888
2889#[pymethods]
2890impl SystemMsg {
2891    #[new]
2892    #[pyo3(signature = (ts_event, msg, code = None))]
2893    fn py_new(ts_event: u64, msg: &str, code: Option<SystemCode>) -> PyResult<Self> {
2894        Ok(Self::new(ts_event, code, msg)?)
2895    }
2896
2897    fn __bytes__(&self) -> &[u8] {
2898        self.as_ref()
2899    }
2900
2901    fn __repr__(&self) -> String {
2902        format!("{self:?}")
2903    }
2904
2905    #[getter]
2906    fn rtype(&self) -> PyResult<RType> {
2907        self.hd.rtype().map_err(to_py_err)
2908    }
2909
2910    #[getter]
2911    fn get_publisher_id(&self) -> u16 {
2912        self.hd.publisher_id
2913    }
2914    #[setter]
2915    fn set_publisher_id(&mut self, publisher_id: u16) {
2916        self.hd.publisher_id = publisher_id;
2917    }
2918
2919    #[getter]
2920    fn get_instrument_id(&self) -> u32 {
2921        self.hd.instrument_id
2922    }
2923    #[setter]
2924    fn set_instrument_id(&mut self, instrument_id: u32) {
2925        self.hd.instrument_id = instrument_id;
2926    }
2927
2928    #[getter]
2929    fn ts_event(&self) -> u64 {
2930        self.hd.ts_event
2931    }
2932    #[getter]
2933    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2934        new_py_timestamp_or_datetime(py, self.ts_event())
2935    }
2936    #[setter]
2937    fn set_ts_event(&mut self, ts_event: u64) {
2938        self.hd.ts_event = ts_event;
2939    }
2940
2941    #[pyo3(name = "record_size")]
2942    fn py_record_size(&self) -> usize {
2943        self.record_size()
2944    }
2945
2946    #[classattr]
2947    fn size_hint() -> PyResult<usize> {
2948        Ok(mem::size_of::<Self>())
2949    }
2950
2951    #[getter]
2952    fn ts_index(&self) -> u64 {
2953        self.raw_index_ts()
2954    }
2955    #[getter]
2956    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
2957        new_py_timestamp_or_datetime(py, self.raw_index_ts())
2958    }
2959
2960    #[pyo3(name = "is_heartbeat")]
2961    fn py_is_heartbeat(&self) -> bool {
2962        self.is_heartbeat()
2963    }
2964
2965    #[getter]
2966    fn get_msg(&self) -> PyResult<&str> {
2967        Ok(self.msg()?)
2968    }
2969
2970    #[getter]
2971    fn get_code<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
2972        self.code()
2973            .map(|c| c.into_bound_py_any(py))
2974            .unwrap_or_else(|_| self.code.into_bound_py_any(py))
2975    }
2976    #[setter]
2977    fn set_code(&mut self, code: SystemCode) {
2978        self.code = code as u8;
2979    }
2980
2981    #[classattr]
2982    #[pyo3(name = "_dtypes")]
2983    fn py_dtypes() -> Vec<(String, String)> {
2984        Self::field_dtypes("")
2985    }
2986
2987    #[classattr]
2988    #[pyo3(name = "_price_fields")]
2989    fn py_price_fields() -> Vec<String> {
2990        Self::price_fields("")
2991    }
2992
2993    #[classattr]
2994    #[pyo3(name = "_timestamp_fields")]
2995    fn py_timestamp_fields() -> Vec<String> {
2996        Self::timestamp_fields("")
2997    }
2998
2999    #[classattr]
3000    #[pyo3(name = "_hidden_fields")]
3001    fn py_hidden_fields() -> Vec<String> {
3002        Self::hidden_fields("")
3003    }
3004
3005    #[classattr]
3006    #[pyo3(name = "_ordered_fields")]
3007    fn py_ordered_fields() -> Vec<String> {
3008        Self::ordered_fields("")
3009    }
3010}
3011
3012#[pymethods]
3013impl v1::ErrorMsg {
3014    #[new]
3015    fn py_new(ts_event: u64, err: &str) -> PyResult<Self> {
3016        Ok(Self::new(ts_event, err))
3017    }
3018
3019    fn __bytes__(&self) -> &[u8] {
3020        self.as_ref()
3021    }
3022
3023    fn __repr__(&self) -> String {
3024        format!("{self:?}")
3025    }
3026
3027    #[getter]
3028    fn rtype(&self) -> PyResult<RType> {
3029        self.hd.rtype().map_err(to_py_err)
3030    }
3031
3032    #[getter]
3033    fn get_publisher_id(&self) -> u16 {
3034        self.hd.publisher_id
3035    }
3036    #[setter]
3037    fn set_publisher_id(&mut self, publisher_id: u16) {
3038        self.hd.publisher_id = publisher_id;
3039    }
3040
3041    #[getter]
3042    fn get_instrument_id(&self) -> u32 {
3043        self.hd.instrument_id
3044    }
3045    #[setter]
3046    fn set_instrument_id(&mut self, instrument_id: u32) {
3047        self.hd.instrument_id = instrument_id;
3048    }
3049
3050    #[getter]
3051    fn ts_event(&self) -> u64 {
3052        self.hd.ts_event
3053    }
3054    #[getter]
3055    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3056        new_py_timestamp_or_datetime(py, self.ts_event())
3057    }
3058    #[setter]
3059    fn set_ts_event(&mut self, ts_event: u64) {
3060        self.hd.ts_event = ts_event;
3061    }
3062
3063    #[pyo3(name = "record_size")]
3064    fn py_record_size(&self) -> usize {
3065        self.record_size()
3066    }
3067
3068    #[classattr]
3069    fn size_hint() -> PyResult<usize> {
3070        Ok(mem::size_of::<Self>())
3071    }
3072
3073    #[getter]
3074    fn ts_index(&self) -> u64 {
3075        self.raw_index_ts()
3076    }
3077    #[getter]
3078    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3079        new_py_timestamp_or_datetime(py, self.raw_index_ts())
3080    }
3081
3082    #[getter]
3083    fn get_err(&self) -> PyResult<&str> {
3084        Ok(self.err()?)
3085    }
3086
3087    #[classattr]
3088    #[pyo3(name = "_dtypes")]
3089    fn py_dtypes() -> Vec<(String, String)> {
3090        Self::field_dtypes("")
3091    }
3092
3093    #[classattr]
3094    #[pyo3(name = "_price_fields")]
3095    fn py_price_fields() -> Vec<String> {
3096        Self::price_fields("")
3097    }
3098
3099    #[classattr]
3100    #[pyo3(name = "_timestamp_fields")]
3101    fn py_timestamp_fields() -> Vec<String> {
3102        Self::timestamp_fields("")
3103    }
3104
3105    #[classattr]
3106    #[pyo3(name = "_hidden_fields")]
3107    fn py_hidden_fields() -> Vec<String> {
3108        Self::hidden_fields("")
3109    }
3110
3111    #[classattr]
3112    #[pyo3(name = "_ordered_fields")]
3113    fn py_ordered_fields() -> Vec<String> {
3114        Self::ordered_fields("")
3115    }
3116}
3117
3118#[pymethods]
3119impl v1::InstrumentDefMsg {
3120    #[new]
3121    #[pyo3(signature = (
3122        publisher_id,
3123        instrument_id,
3124        ts_event,
3125        ts_recv,
3126        min_price_increment,
3127        display_factor,
3128        expiration,
3129        activation,
3130        high_limit_price,
3131        low_limit_price,
3132        max_price_variation,
3133        trading_reference_price,
3134        unit_of_measure_qty,
3135        min_price_increment_amount,
3136        price_ratio,
3137        inst_attrib_value,
3138        underlying_id,
3139        raw_instrument_id,
3140        market_depth_implied,
3141        market_depth,
3142        market_segment_id,
3143        max_trade_vol,
3144        min_lot_size,
3145        min_lot_size_block,
3146        min_lot_size_round_lot,
3147        min_trade_vol,
3148        contract_multiplier,
3149        decay_quantity,
3150        original_contract_size,
3151        trading_reference_date,
3152        appl_id,
3153        maturity_year,
3154        decay_start_date,
3155        channel_id,
3156        currency,
3157        settl_currency,
3158        secsubtype,
3159        raw_symbol,
3160        group,
3161        exchange,
3162        asset,
3163        cfi,
3164        security_type,
3165        unit_of_measure,
3166        underlying,
3167        strike_price_currency,
3168        instrument_class,
3169        strike_price,
3170        match_algorithm,
3171        md_security_trading_status,
3172        main_fraction,
3173        price_display_format,
3174        settl_price_type,
3175        sub_fraction,
3176        underlying_product,
3177        security_update_action,
3178        maturity_month,
3179        maturity_day,
3180        maturity_week,
3181        user_defined_instrument,
3182        contract_multiplier_unit,
3183        flow_schedule_type,
3184        tick_rule,
3185    ))]
3186    fn py_new(
3187        publisher_id: u16,
3188        instrument_id: u32,
3189        ts_event: u64,
3190        ts_recv: u64,
3191        min_price_increment: i64,
3192        display_factor: i64,
3193        expiration: u64,
3194        activation: u64,
3195        high_limit_price: i64,
3196        low_limit_price: i64,
3197        max_price_variation: i64,
3198        trading_reference_price: i64,
3199        unit_of_measure_qty: i64,
3200        min_price_increment_amount: i64,
3201        price_ratio: i64,
3202        inst_attrib_value: i32,
3203        underlying_id: u32,
3204        raw_instrument_id: u32,
3205        market_depth_implied: i32,
3206        market_depth: i32,
3207        market_segment_id: u32,
3208        max_trade_vol: u32,
3209        min_lot_size: i32,
3210        min_lot_size_block: i32,
3211        min_lot_size_round_lot: i32,
3212        min_trade_vol: u32,
3213        contract_multiplier: i32,
3214        decay_quantity: i32,
3215        original_contract_size: i32,
3216        trading_reference_date: u16,
3217        appl_id: i16,
3218        maturity_year: u16,
3219        decay_start_date: u16,
3220        channel_id: u16,
3221        currency: &str,
3222        settl_currency: &str,
3223        secsubtype: &str,
3224        raw_symbol: &str,
3225        group: &str,
3226        exchange: &str,
3227        asset: &str,
3228        cfi: &str,
3229        security_type: &str,
3230        unit_of_measure: &str,
3231        underlying: &str,
3232        strike_price_currency: &str,
3233        instrument_class: InstrumentClass,
3234        strike_price: i64,
3235        match_algorithm: MatchAlgorithm,
3236        md_security_trading_status: u8,
3237        main_fraction: u8,
3238        price_display_format: u8,
3239        settl_price_type: u8,
3240        sub_fraction: u8,
3241        underlying_product: u8,
3242        security_update_action: SecurityUpdateAction,
3243        maturity_month: u8,
3244        maturity_day: u8,
3245        maturity_week: u8,
3246        user_defined_instrument: UserDefinedInstrument,
3247        contract_multiplier_unit: i8,
3248        flow_schedule_type: i8,
3249        tick_rule: u8,
3250    ) -> PyResult<Self> {
3251        Ok(Self {
3252            hd: RecordHeader::new::<Self>(
3253                rtype::INSTRUMENT_DEF,
3254                publisher_id,
3255                instrument_id,
3256                ts_event,
3257            ),
3258            ts_recv,
3259            min_price_increment,
3260            display_factor,
3261            expiration,
3262            activation,
3263            high_limit_price,
3264            low_limit_price,
3265            max_price_variation,
3266            trading_reference_price,
3267            unit_of_measure_qty,
3268            min_price_increment_amount,
3269            price_ratio,
3270            inst_attrib_value,
3271            underlying_id,
3272            raw_instrument_id,
3273            market_depth_implied,
3274            market_depth,
3275            market_segment_id,
3276            max_trade_vol,
3277            min_lot_size,
3278            min_lot_size_block,
3279            min_lot_size_round_lot,
3280            min_trade_vol,
3281            _reserved2: Default::default(),
3282            contract_multiplier,
3283            decay_quantity,
3284            original_contract_size,
3285            _reserved3: Default::default(),
3286            trading_reference_date,
3287            appl_id,
3288            maturity_year,
3289            decay_start_date,
3290            channel_id,
3291            currency: str_to_c_chars(currency)?,
3292            settl_currency: str_to_c_chars(settl_currency)?,
3293            secsubtype: str_to_c_chars(secsubtype)?,
3294            raw_symbol: str_to_c_chars(raw_symbol)?,
3295            group: str_to_c_chars(group)?,
3296            exchange: str_to_c_chars(exchange)?,
3297            asset: str_to_c_chars(asset)?,
3298            cfi: str_to_c_chars(cfi)?,
3299            security_type: str_to_c_chars(security_type)?,
3300            unit_of_measure: str_to_c_chars(unit_of_measure)?,
3301            underlying: str_to_c_chars(underlying)?,
3302            strike_price_currency: str_to_c_chars(strike_price_currency)?,
3303            instrument_class: instrument_class as u8 as c_char,
3304            _reserved4: Default::default(),
3305            strike_price,
3306            _reserved5: Default::default(),
3307            match_algorithm: match_algorithm as u8 as c_char,
3308            md_security_trading_status,
3309            main_fraction,
3310            price_display_format,
3311            settl_price_type,
3312            sub_fraction,
3313            underlying_product,
3314            security_update_action,
3315            maturity_month,
3316            maturity_day,
3317            maturity_week,
3318            user_defined_instrument,
3319            contract_multiplier_unit,
3320            flow_schedule_type,
3321            tick_rule,
3322            _dummy: Default::default(),
3323        })
3324    }
3325
3326    fn __bytes__(&self) -> &[u8] {
3327        self.as_ref()
3328    }
3329
3330    fn __repr__(&self) -> String {
3331        format!("{self:?}")
3332    }
3333
3334    #[getter]
3335    fn rtype(&self) -> PyResult<RType> {
3336        self.hd.rtype().map_err(to_py_err)
3337    }
3338
3339    #[getter]
3340    fn get_publisher_id(&self) -> u16 {
3341        self.hd.publisher_id
3342    }
3343    #[setter]
3344    fn set_publisher_id(&mut self, publisher_id: u16) {
3345        self.hd.publisher_id = publisher_id;
3346    }
3347
3348    #[getter]
3349    fn get_instrument_id(&self) -> u32 {
3350        self.hd.instrument_id
3351    }
3352    #[setter]
3353    fn set_instrument_id(&mut self, instrument_id: u32) {
3354        self.hd.instrument_id = instrument_id;
3355    }
3356
3357    #[getter]
3358    fn ts_event(&self) -> u64 {
3359        self.hd.ts_event
3360    }
3361    #[getter]
3362    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3363        new_py_timestamp_or_datetime(py, self.ts_event())
3364    }
3365    #[setter]
3366    fn set_ts_event(&mut self, ts_event: u64) {
3367        self.hd.ts_event = ts_event;
3368    }
3369
3370    #[pyo3(name = "record_size")]
3371    fn py_record_size(&self) -> usize {
3372        self.record_size()
3373    }
3374
3375    #[classattr]
3376    fn size_hint() -> PyResult<usize> {
3377        Ok(mem::size_of::<Self>())
3378    }
3379
3380    #[getter]
3381    fn ts_index(&self) -> u64 {
3382        self.raw_index_ts()
3383    }
3384    #[getter]
3385    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3386        new_py_timestamp_or_datetime(py, self.raw_index_ts())
3387    }
3388
3389    #[getter]
3390    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3391        new_py_timestamp_or_datetime(py, self.ts_recv)
3392    }
3393
3394    #[getter]
3395    fn get_pretty_min_price_increment(&self) -> f64 {
3396        self.min_price_increment_f64()
3397    }
3398
3399    #[getter]
3400    fn get_pretty_display_factor(&self) -> f64 {
3401        self.display_factor_f64()
3402    }
3403
3404    #[getter]
3405    fn get_pretty_expiration<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3406        new_py_timestamp_or_datetime(py, self.expiration)
3407    }
3408
3409    #[getter]
3410    fn get_pretty_activation<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3411        new_py_timestamp_or_datetime(py, self.activation)
3412    }
3413
3414    #[getter]
3415    fn get_pretty_high_limit_price(&self) -> f64 {
3416        self.high_limit_price_f64()
3417    }
3418
3419    #[getter]
3420    fn get_pretty_low_limit_price(&self) -> f64 {
3421        self.low_limit_price_f64()
3422    }
3423
3424    #[getter]
3425    fn get_pretty_max_price_variation(&self) -> f64 {
3426        self.max_price_variation_f64()
3427    }
3428
3429    #[getter]
3430    fn get_pretty_trading_reference_price(&self) -> f64 {
3431        self.trading_reference_price_f64()
3432    }
3433
3434    #[getter]
3435    fn get_pretty_unit_of_measure_qty(&self) -> f64 {
3436        self.unit_of_measure_qty_f64()
3437    }
3438
3439    #[getter]
3440    fn get_pretty_min_price_increment_amount(&self) -> f64 {
3441        self.min_price_increment_amount_f64()
3442    }
3443
3444    #[getter]
3445    fn get_pretty_price_ratio(&self) -> f64 {
3446        self.price_ratio_f64()
3447    }
3448
3449    #[getter]
3450    fn get_currency(&self) -> PyResult<&str> {
3451        Ok(self.currency()?)
3452    }
3453
3454    #[getter]
3455    fn get_settl_currency(&self) -> PyResult<&str> {
3456        Ok(self.settl_currency()?)
3457    }
3458
3459    #[getter]
3460    fn get_secsubtype(&self) -> PyResult<&str> {
3461        Ok(self.secsubtype()?)
3462    }
3463
3464    #[getter]
3465    fn get_raw_symbol(&self) -> PyResult<&str> {
3466        Ok(self.raw_symbol()?)
3467    }
3468
3469    #[getter]
3470    fn get_group(&self) -> PyResult<&str> {
3471        Ok(self.group()?)
3472    }
3473
3474    #[getter]
3475    fn get_exchange(&self) -> PyResult<&str> {
3476        Ok(self.exchange()?)
3477    }
3478
3479    #[getter]
3480    fn get_asset(&self) -> PyResult<&str> {
3481        Ok(self.asset()?)
3482    }
3483
3484    #[getter]
3485    fn get_cfi(&self) -> PyResult<&str> {
3486        Ok(self.cfi()?)
3487    }
3488
3489    #[getter]
3490    fn get_security_type(&self) -> PyResult<&str> {
3491        Ok(self.security_type()?)
3492    }
3493
3494    #[getter]
3495    fn get_unit_of_measure(&self) -> PyResult<&str> {
3496        Ok(self.unit_of_measure()?)
3497    }
3498
3499    #[getter]
3500    fn get_underlying(&self) -> PyResult<&str> {
3501        Ok(self.underlying()?)
3502    }
3503
3504    #[getter]
3505    fn get_strike_price_currency(&self) -> PyResult<&str> {
3506        Ok(self.strike_price_currency()?)
3507    }
3508
3509    #[getter]
3510    fn get_instrument_class<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
3511        self.instrument_class()
3512            .map(|c| c.into_bound_py_any(py))
3513            .unwrap_or_else(|_| (self.instrument_class as u8 as char).into_bound_py_any(py))
3514    }
3515    #[setter]
3516    fn set_instrument_class(&mut self, instrument_class: InstrumentClass) {
3517        self.instrument_class = instrument_class as u8 as c_char;
3518    }
3519
3520    #[getter]
3521    fn get_pretty_strike_price(&self) -> f64 {
3522        self.strike_price_f64()
3523    }
3524
3525    #[getter]
3526    fn get_match_algorithm<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
3527        self.match_algorithm()
3528            .map(|c| c.into_bound_py_any(py))
3529            .unwrap_or_else(|_| (self.match_algorithm as u8 as char).into_bound_py_any(py))
3530    }
3531    #[setter]
3532    fn set_match_algorithm(&mut self, match_algorithm: MatchAlgorithm) {
3533        self.match_algorithm = match_algorithm as u8 as c_char;
3534    }
3535
3536    #[classattr]
3537    #[pyo3(name = "_dtypes")]
3538    fn py_dtypes() -> Vec<(String, String)> {
3539        Self::field_dtypes("")
3540    }
3541
3542    #[classattr]
3543    #[pyo3(name = "_price_fields")]
3544    fn py_price_fields() -> Vec<String> {
3545        Self::price_fields("")
3546    }
3547
3548    #[classattr]
3549    #[pyo3(name = "_timestamp_fields")]
3550    fn py_timestamp_fields() -> Vec<String> {
3551        Self::timestamp_fields("")
3552    }
3553
3554    #[classattr]
3555    #[pyo3(name = "_hidden_fields")]
3556    fn py_hidden_fields() -> Vec<String> {
3557        Self::hidden_fields("")
3558    }
3559
3560    #[classattr]
3561    #[pyo3(name = "_ordered_fields")]
3562    fn py_ordered_fields() -> Vec<String> {
3563        Self::ordered_fields("")
3564    }
3565}
3566
3567#[pymethods]
3568impl v1::StatMsg {
3569    #[new]
3570    #[pyo3(signature = (
3571        publisher_id,
3572        instrument_id,
3573        ts_event,
3574        ts_recv,
3575        ts_ref,
3576        price,
3577        quantity,
3578        stat_type,
3579        sequence = 0,
3580        ts_in_delta = 0,
3581        channel_id = None,
3582        update_action = None,
3583        stat_flags = 0,
3584    ))]
3585    fn py_new(
3586        publisher_id: u16,
3587        instrument_id: u32,
3588        ts_event: u64,
3589        ts_recv: u64,
3590        ts_ref: u64,
3591        price: i64,
3592        quantity: i32,
3593        stat_type: StatType,
3594        sequence: u32,
3595        ts_in_delta: i32,
3596        channel_id: Option<u16>,
3597        update_action: Option<StatUpdateAction>,
3598        stat_flags: u8,
3599    ) -> PyResult<Self> {
3600        Ok(Self {
3601            hd: RecordHeader::new::<Self>(rtype::STATISTICS, publisher_id, instrument_id, ts_event),
3602            ts_recv,
3603            ts_ref,
3604            price,
3605            quantity,
3606            sequence,
3607            ts_in_delta,
3608            stat_type: stat_type as u16,
3609            channel_id: channel_id.unwrap_or(u16::MAX),
3610            update_action: update_action.unwrap_or_default() as u8,
3611            stat_flags,
3612            _reserved: Default::default(),
3613        })
3614    }
3615
3616    fn __bytes__(&self) -> &[u8] {
3617        self.as_ref()
3618    }
3619
3620    fn __repr__(&self) -> String {
3621        format!("{self:?}")
3622    }
3623
3624    #[getter]
3625    fn rtype(&self) -> PyResult<RType> {
3626        self.hd.rtype().map_err(to_py_err)
3627    }
3628
3629    #[getter]
3630    fn get_publisher_id(&self) -> u16 {
3631        self.hd.publisher_id
3632    }
3633    #[setter]
3634    fn set_publisher_id(&mut self, publisher_id: u16) {
3635        self.hd.publisher_id = publisher_id;
3636    }
3637
3638    #[getter]
3639    fn get_instrument_id(&self) -> u32 {
3640        self.hd.instrument_id
3641    }
3642    #[setter]
3643    fn set_instrument_id(&mut self, instrument_id: u32) {
3644        self.hd.instrument_id = instrument_id;
3645    }
3646
3647    #[getter]
3648    fn ts_event(&self) -> u64 {
3649        self.hd.ts_event
3650    }
3651    #[getter]
3652    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3653        new_py_timestamp_or_datetime(py, self.ts_event())
3654    }
3655    #[setter]
3656    fn set_ts_event(&mut self, ts_event: u64) {
3657        self.hd.ts_event = ts_event;
3658    }
3659
3660    #[pyo3(name = "record_size")]
3661    fn py_record_size(&self) -> usize {
3662        self.record_size()
3663    }
3664
3665    #[classattr]
3666    fn size_hint() -> PyResult<usize> {
3667        Ok(mem::size_of::<Self>())
3668    }
3669
3670    #[getter]
3671    fn ts_index(&self) -> u64 {
3672        self.raw_index_ts()
3673    }
3674    #[getter]
3675    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3676        new_py_timestamp_or_datetime(py, self.raw_index_ts())
3677    }
3678
3679    #[getter]
3680    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3681        new_py_timestamp_or_datetime(py, self.ts_recv)
3682    }
3683
3684    #[getter]
3685    fn get_pretty_ts_ref<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3686        new_py_timestamp_or_datetime(py, self.ts_ref)
3687    }
3688
3689    #[getter]
3690    fn get_pretty_price(&self) -> f64 {
3691        self.price_f64()
3692    }
3693
3694    #[getter]
3695    fn get_stat_type<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
3696        self.stat_type()
3697            .map(|c| c.into_bound_py_any(py))
3698            .unwrap_or_else(|_| self.stat_type.into_bound_py_any(py))
3699    }
3700    #[setter]
3701    fn set_stat_type(&mut self, stat_type: StatType) {
3702        self.stat_type = stat_type as u16;
3703    }
3704
3705    #[getter]
3706    fn get_update_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
3707        self.update_action()
3708            .map(|c| c.into_bound_py_any(py))
3709            .unwrap_or_else(|_| self.update_action.into_bound_py_any(py))
3710    }
3711    #[setter]
3712    fn set_update_action(&mut self, update_action: StatUpdateAction) {
3713        self.update_action = update_action as u8;
3714    }
3715
3716    #[classattr]
3717    #[pyo3(name = "_dtypes")]
3718    fn py_dtypes() -> Vec<(String, String)> {
3719        Self::field_dtypes("")
3720    }
3721
3722    #[classattr]
3723    #[pyo3(name = "_price_fields")]
3724    fn py_price_fields() -> Vec<String> {
3725        Self::price_fields("")
3726    }
3727
3728    #[classattr]
3729    #[pyo3(name = "_timestamp_fields")]
3730    fn py_timestamp_fields() -> Vec<String> {
3731        Self::timestamp_fields("")
3732    }
3733
3734    #[classattr]
3735    #[pyo3(name = "_hidden_fields")]
3736    fn py_hidden_fields() -> Vec<String> {
3737        Self::hidden_fields("")
3738    }
3739
3740    #[classattr]
3741    #[pyo3(name = "_ordered_fields")]
3742    fn py_ordered_fields() -> Vec<String> {
3743        Self::ordered_fields("")
3744    }
3745}
3746
3747#[pymethods]
3748impl v1::SymbolMappingMsg {
3749    #[new]
3750    #[pyo3(signature = (
3751        publisher_id,
3752        instrument_id,
3753        ts_event,
3754        stype_in_symbol,
3755        stype_out_symbol,
3756        start_ts,
3757        end_ts,
3758    ))]
3759    fn py_new(
3760        publisher_id: u16,
3761        instrument_id: u32,
3762        ts_event: u64,
3763        stype_in_symbol: &str,
3764        stype_out_symbol: &str,
3765        start_ts: u64,
3766        end_ts: u64,
3767    ) -> PyResult<Self> {
3768        Ok(Self {
3769            hd: RecordHeader::new::<Self>(
3770                rtype::SYMBOL_MAPPING,
3771                publisher_id,
3772                instrument_id,
3773                ts_event,
3774            ),
3775            stype_in_symbol: str_to_c_chars(stype_in_symbol)?,
3776            stype_out_symbol: str_to_c_chars(stype_out_symbol)?,
3777            _dummy: Default::default(),
3778            start_ts,
3779            end_ts,
3780        })
3781    }
3782
3783    fn __bytes__(&self) -> &[u8] {
3784        self.as_ref()
3785    }
3786
3787    fn __repr__(&self) -> String {
3788        format!("{self:?}")
3789    }
3790
3791    #[getter]
3792    fn rtype(&self) -> PyResult<RType> {
3793        self.hd.rtype().map_err(to_py_err)
3794    }
3795
3796    #[getter]
3797    fn get_publisher_id(&self) -> u16 {
3798        self.hd.publisher_id
3799    }
3800    #[setter]
3801    fn set_publisher_id(&mut self, publisher_id: u16) {
3802        self.hd.publisher_id = publisher_id;
3803    }
3804
3805    #[getter]
3806    fn get_instrument_id(&self) -> u32 {
3807        self.hd.instrument_id
3808    }
3809    #[setter]
3810    fn set_instrument_id(&mut self, instrument_id: u32) {
3811        self.hd.instrument_id = instrument_id;
3812    }
3813
3814    #[getter]
3815    fn ts_event(&self) -> u64 {
3816        self.hd.ts_event
3817    }
3818    #[getter]
3819    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3820        new_py_timestamp_or_datetime(py, self.ts_event())
3821    }
3822    #[setter]
3823    fn set_ts_event(&mut self, ts_event: u64) {
3824        self.hd.ts_event = ts_event;
3825    }
3826
3827    #[pyo3(name = "record_size")]
3828    fn py_record_size(&self) -> usize {
3829        self.record_size()
3830    }
3831
3832    #[classattr]
3833    fn size_hint() -> PyResult<usize> {
3834        Ok(mem::size_of::<Self>())
3835    }
3836
3837    #[getter]
3838    fn ts_index(&self) -> u64 {
3839        self.raw_index_ts()
3840    }
3841    #[getter]
3842    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3843        new_py_timestamp_or_datetime(py, self.raw_index_ts())
3844    }
3845
3846    #[getter]
3847    fn get_stype_in_symbol(&self) -> PyResult<&str> {
3848        Ok(self.stype_in_symbol()?)
3849    }
3850
3851    #[getter]
3852    fn get_stype_out_symbol(&self) -> PyResult<&str> {
3853        Ok(self.stype_out_symbol()?)
3854    }
3855
3856    #[getter]
3857    fn get_pretty_start_ts<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3858        new_py_timestamp_or_datetime(py, self.start_ts)
3859    }
3860
3861    #[getter]
3862    fn get_pretty_end_ts<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3863        new_py_timestamp_or_datetime(py, self.end_ts)
3864    }
3865
3866    #[classattr]
3867    #[pyo3(name = "_dtypes")]
3868    fn py_dtypes() -> Vec<(String, String)> {
3869        Self::field_dtypes("")
3870    }
3871
3872    #[classattr]
3873    #[pyo3(name = "_price_fields")]
3874    fn py_price_fields() -> Vec<String> {
3875        Self::price_fields("")
3876    }
3877
3878    #[classattr]
3879    #[pyo3(name = "_timestamp_fields")]
3880    fn py_timestamp_fields() -> Vec<String> {
3881        Self::timestamp_fields("")
3882    }
3883
3884    #[classattr]
3885    #[pyo3(name = "_hidden_fields")]
3886    fn py_hidden_fields() -> Vec<String> {
3887        Self::hidden_fields("")
3888    }
3889
3890    #[classattr]
3891    #[pyo3(name = "_ordered_fields")]
3892    fn py_ordered_fields() -> Vec<String> {
3893        Self::ordered_fields("")
3894    }
3895}
3896
3897#[pymethods]
3898impl v1::SystemMsg {
3899    #[new]
3900    fn py_new(ts_event: u64, msg: &str) -> PyResult<Self> {
3901        Ok(Self::new(ts_event, msg)?)
3902    }
3903
3904    fn __bytes__(&self) -> &[u8] {
3905        self.as_ref()
3906    }
3907
3908    fn __repr__(&self) -> String {
3909        format!("{self:?}")
3910    }
3911
3912    #[getter]
3913    fn rtype(&self) -> PyResult<RType> {
3914        self.hd.rtype().map_err(to_py_err)
3915    }
3916
3917    #[getter]
3918    fn get_publisher_id(&self) -> u16 {
3919        self.hd.publisher_id
3920    }
3921    #[setter]
3922    fn set_publisher_id(&mut self, publisher_id: u16) {
3923        self.hd.publisher_id = publisher_id;
3924    }
3925
3926    #[getter]
3927    fn get_instrument_id(&self) -> u32 {
3928        self.hd.instrument_id
3929    }
3930    #[setter]
3931    fn set_instrument_id(&mut self, instrument_id: u32) {
3932        self.hd.instrument_id = instrument_id;
3933    }
3934
3935    #[getter]
3936    fn ts_event(&self) -> u64 {
3937        self.hd.ts_event
3938    }
3939    #[getter]
3940    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3941        new_py_timestamp_or_datetime(py, self.ts_event())
3942    }
3943    #[setter]
3944    fn set_ts_event(&mut self, ts_event: u64) {
3945        self.hd.ts_event = ts_event;
3946    }
3947
3948    #[pyo3(name = "record_size")]
3949    fn py_record_size(&self) -> usize {
3950        self.record_size()
3951    }
3952
3953    #[classattr]
3954    fn size_hint() -> PyResult<usize> {
3955        Ok(mem::size_of::<Self>())
3956    }
3957
3958    #[getter]
3959    fn ts_index(&self) -> u64 {
3960        self.raw_index_ts()
3961    }
3962    #[getter]
3963    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
3964        new_py_timestamp_or_datetime(py, self.raw_index_ts())
3965    }
3966
3967    #[pyo3(name = "is_heartbeat")]
3968    fn py_is_heartbeat(&self) -> bool {
3969        self.is_heartbeat()
3970    }
3971
3972    #[getter]
3973    fn get_msg(&self) -> PyResult<&str> {
3974        Ok(self.msg()?)
3975    }
3976
3977    #[classattr]
3978    #[pyo3(name = "_dtypes")]
3979    fn py_dtypes() -> Vec<(String, String)> {
3980        Self::field_dtypes("")
3981    }
3982
3983    #[classattr]
3984    #[pyo3(name = "_price_fields")]
3985    fn py_price_fields() -> Vec<String> {
3986        Self::price_fields("")
3987    }
3988
3989    #[classattr]
3990    #[pyo3(name = "_timestamp_fields")]
3991    fn py_timestamp_fields() -> Vec<String> {
3992        Self::timestamp_fields("")
3993    }
3994
3995    #[classattr]
3996    #[pyo3(name = "_hidden_fields")]
3997    fn py_hidden_fields() -> Vec<String> {
3998        Self::hidden_fields("")
3999    }
4000
4001    #[classattr]
4002    #[pyo3(name = "_ordered_fields")]
4003    fn py_ordered_fields() -> Vec<String> {
4004        Self::ordered_fields("")
4005    }
4006}
4007
4008#[pymethods]
4009impl v2::InstrumentDefMsg {
4010    #[new]
4011    #[pyo3(signature = (
4012        publisher_id,
4013        instrument_id,
4014        ts_event,
4015        ts_recv,
4016        min_price_increment,
4017        display_factor,
4018        expiration,
4019        activation,
4020        high_limit_price,
4021        low_limit_price,
4022        max_price_variation,
4023        trading_reference_price,
4024        unit_of_measure_qty,
4025        min_price_increment_amount,
4026        price_ratio,
4027        strike_price,
4028        inst_attrib_value,
4029        underlying_id,
4030        raw_instrument_id,
4031        market_depth_implied,
4032        market_depth,
4033        market_segment_id,
4034        max_trade_vol,
4035        min_lot_size,
4036        min_lot_size_block,
4037        min_lot_size_round_lot,
4038        min_trade_vol,
4039        contract_multiplier,
4040        decay_quantity,
4041        original_contract_size,
4042        trading_reference_date,
4043        appl_id,
4044        maturity_year,
4045        decay_start_date,
4046        channel_id,
4047        currency,
4048        settl_currency,
4049        secsubtype,
4050        raw_symbol,
4051        group,
4052        exchange,
4053        asset,
4054        cfi,
4055        security_type,
4056        unit_of_measure,
4057        underlying,
4058        strike_price_currency,
4059        instrument_class,
4060        match_algorithm,
4061        md_security_trading_status,
4062        main_fraction,
4063        price_display_format,
4064        settl_price_type,
4065        sub_fraction,
4066        underlying_product,
4067        security_update_action,
4068        maturity_month,
4069        maturity_day,
4070        maturity_week,
4071        user_defined_instrument,
4072        contract_multiplier_unit,
4073        flow_schedule_type,
4074        tick_rule,
4075    ))]
4076    fn py_new(
4077        publisher_id: u16,
4078        instrument_id: u32,
4079        ts_event: u64,
4080        ts_recv: u64,
4081        min_price_increment: i64,
4082        display_factor: i64,
4083        expiration: u64,
4084        activation: u64,
4085        high_limit_price: i64,
4086        low_limit_price: i64,
4087        max_price_variation: i64,
4088        trading_reference_price: i64,
4089        unit_of_measure_qty: i64,
4090        min_price_increment_amount: i64,
4091        price_ratio: i64,
4092        strike_price: i64,
4093        inst_attrib_value: i32,
4094        underlying_id: u32,
4095        raw_instrument_id: u32,
4096        market_depth_implied: i32,
4097        market_depth: i32,
4098        market_segment_id: u32,
4099        max_trade_vol: u32,
4100        min_lot_size: i32,
4101        min_lot_size_block: i32,
4102        min_lot_size_round_lot: i32,
4103        min_trade_vol: u32,
4104        contract_multiplier: i32,
4105        decay_quantity: i32,
4106        original_contract_size: i32,
4107        trading_reference_date: u16,
4108        appl_id: i16,
4109        maturity_year: u16,
4110        decay_start_date: u16,
4111        channel_id: u16,
4112        currency: &str,
4113        settl_currency: &str,
4114        secsubtype: &str,
4115        raw_symbol: &str,
4116        group: &str,
4117        exchange: &str,
4118        asset: &str,
4119        cfi: &str,
4120        security_type: &str,
4121        unit_of_measure: &str,
4122        underlying: &str,
4123        strike_price_currency: &str,
4124        instrument_class: InstrumentClass,
4125        match_algorithm: MatchAlgorithm,
4126        md_security_trading_status: u8,
4127        main_fraction: u8,
4128        price_display_format: u8,
4129        settl_price_type: u8,
4130        sub_fraction: u8,
4131        underlying_product: u8,
4132        security_update_action: SecurityUpdateAction,
4133        maturity_month: u8,
4134        maturity_day: u8,
4135        maturity_week: u8,
4136        user_defined_instrument: UserDefinedInstrument,
4137        contract_multiplier_unit: i8,
4138        flow_schedule_type: i8,
4139        tick_rule: u8,
4140    ) -> PyResult<Self> {
4141        Ok(Self {
4142            hd: RecordHeader::new::<Self>(
4143                rtype::INSTRUMENT_DEF,
4144                publisher_id,
4145                instrument_id,
4146                ts_event,
4147            ),
4148            ts_recv,
4149            min_price_increment,
4150            display_factor,
4151            expiration,
4152            activation,
4153            high_limit_price,
4154            low_limit_price,
4155            max_price_variation,
4156            trading_reference_price,
4157            unit_of_measure_qty,
4158            min_price_increment_amount,
4159            price_ratio,
4160            strike_price,
4161            inst_attrib_value,
4162            underlying_id,
4163            raw_instrument_id,
4164            market_depth_implied,
4165            market_depth,
4166            market_segment_id,
4167            max_trade_vol,
4168            min_lot_size,
4169            min_lot_size_block,
4170            min_lot_size_round_lot,
4171            min_trade_vol,
4172            contract_multiplier,
4173            decay_quantity,
4174            original_contract_size,
4175            trading_reference_date,
4176            appl_id,
4177            maturity_year,
4178            decay_start_date,
4179            channel_id,
4180            currency: str_to_c_chars(currency)?,
4181            settl_currency: str_to_c_chars(settl_currency)?,
4182            secsubtype: str_to_c_chars(secsubtype)?,
4183            raw_symbol: str_to_c_chars(raw_symbol)?,
4184            group: str_to_c_chars(group)?,
4185            exchange: str_to_c_chars(exchange)?,
4186            asset: str_to_c_chars(asset)?,
4187            cfi: str_to_c_chars(cfi)?,
4188            security_type: str_to_c_chars(security_type)?,
4189            unit_of_measure: str_to_c_chars(unit_of_measure)?,
4190            underlying: str_to_c_chars(underlying)?,
4191            strike_price_currency: str_to_c_chars(strike_price_currency)?,
4192            instrument_class: instrument_class as u8 as c_char,
4193            match_algorithm: match_algorithm as u8 as c_char,
4194            md_security_trading_status,
4195            main_fraction,
4196            price_display_format,
4197            settl_price_type,
4198            sub_fraction,
4199            underlying_product,
4200            security_update_action: security_update_action as u8 as c_char,
4201            maturity_month,
4202            maturity_day,
4203            maturity_week,
4204            user_defined_instrument,
4205            contract_multiplier_unit,
4206            flow_schedule_type,
4207            tick_rule,
4208            _reserved: Default::default(),
4209        })
4210    }
4211
4212    fn __bytes__(&self) -> &[u8] {
4213        self.as_ref()
4214    }
4215
4216    fn __repr__(&self) -> String {
4217        format!("{self:?}")
4218    }
4219
4220    #[getter]
4221    fn rtype(&self) -> PyResult<RType> {
4222        self.hd.rtype().map_err(to_py_err)
4223    }
4224
4225    #[getter]
4226    fn get_publisher_id(&self) -> u16 {
4227        self.hd.publisher_id
4228    }
4229    #[setter]
4230    fn set_publisher_id(&mut self, publisher_id: u16) {
4231        self.hd.publisher_id = publisher_id;
4232    }
4233
4234    #[getter]
4235    fn get_instrument_id(&self) -> u32 {
4236        self.hd.instrument_id
4237    }
4238    #[setter]
4239    fn set_instrument_id(&mut self, instrument_id: u32) {
4240        self.hd.instrument_id = instrument_id;
4241    }
4242
4243    #[getter]
4244    fn ts_event(&self) -> u64 {
4245        self.hd.ts_event
4246    }
4247    #[getter]
4248    fn get_pretty_ts_event<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
4249        new_py_timestamp_or_datetime(py, self.ts_event())
4250    }
4251    #[setter]
4252    fn set_ts_event(&mut self, ts_event: u64) {
4253        self.hd.ts_event = ts_event;
4254    }
4255
4256    #[pyo3(name = "record_size")]
4257    fn py_record_size(&self) -> usize {
4258        self.record_size()
4259    }
4260
4261    #[classattr]
4262    fn size_hint() -> PyResult<usize> {
4263        Ok(mem::size_of::<Self>())
4264    }
4265
4266    #[getter]
4267    fn ts_index(&self) -> u64 {
4268        self.raw_index_ts()
4269    }
4270    #[getter]
4271    fn get_pretty_ts_index<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
4272        new_py_timestamp_or_datetime(py, self.raw_index_ts())
4273    }
4274
4275    #[getter]
4276    fn get_pretty_ts_recv<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
4277        new_py_timestamp_or_datetime(py, self.ts_recv)
4278    }
4279
4280    #[getter]
4281    fn get_pretty_min_price_increment(&self) -> f64 {
4282        self.min_price_increment_f64()
4283    }
4284
4285    #[getter]
4286    fn get_pretty_display_factor(&self) -> f64 {
4287        self.display_factor_f64()
4288    }
4289
4290    #[getter]
4291    fn get_pretty_expiration<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
4292        new_py_timestamp_or_datetime(py, self.expiration)
4293    }
4294
4295    #[getter]
4296    fn get_pretty_activation<'py>(&self, py: Python<'py>) -> PyResult<Option<Bound<'py, PyAny>>> {
4297        new_py_timestamp_or_datetime(py, self.activation)
4298    }
4299
4300    #[getter]
4301    fn get_pretty_high_limit_price(&self) -> f64 {
4302        self.high_limit_price_f64()
4303    }
4304
4305    #[getter]
4306    fn get_pretty_low_limit_price(&self) -> f64 {
4307        self.low_limit_price_f64()
4308    }
4309
4310    #[getter]
4311    fn get_pretty_max_price_variation(&self) -> f64 {
4312        self.max_price_variation_f64()
4313    }
4314
4315    #[getter]
4316    fn get_pretty_trading_reference_price(&self) -> f64 {
4317        self.trading_reference_price_f64()
4318    }
4319
4320    #[getter]
4321    fn get_pretty_unit_of_measure_qty(&self) -> f64 {
4322        self.unit_of_measure_qty_f64()
4323    }
4324
4325    #[getter]
4326    fn get_pretty_min_price_increment_amount(&self) -> f64 {
4327        self.min_price_increment_amount_f64()
4328    }
4329
4330    #[getter]
4331    fn get_pretty_price_ratio(&self) -> f64 {
4332        self.price_ratio_f64()
4333    }
4334
4335    #[getter]
4336    fn get_pretty_strike_price(&self) -> f64 {
4337        self.strike_price_f64()
4338    }
4339
4340    #[getter]
4341    fn get_currency(&self) -> PyResult<&str> {
4342        Ok(self.currency()?)
4343    }
4344
4345    #[getter]
4346    fn get_settl_currency(&self) -> PyResult<&str> {
4347        Ok(self.settl_currency()?)
4348    }
4349
4350    #[getter]
4351    fn get_secsubtype(&self) -> PyResult<&str> {
4352        Ok(self.secsubtype()?)
4353    }
4354
4355    #[getter]
4356    fn get_raw_symbol(&self) -> PyResult<&str> {
4357        Ok(self.raw_symbol()?)
4358    }
4359
4360    #[getter]
4361    fn get_group(&self) -> PyResult<&str> {
4362        Ok(self.group()?)
4363    }
4364
4365    #[getter]
4366    fn get_exchange(&self) -> PyResult<&str> {
4367        Ok(self.exchange()?)
4368    }
4369
4370    #[getter]
4371    fn get_asset(&self) -> PyResult<&str> {
4372        Ok(self.asset()?)
4373    }
4374
4375    #[getter]
4376    fn get_cfi(&self) -> PyResult<&str> {
4377        Ok(self.cfi()?)
4378    }
4379
4380    #[getter]
4381    fn get_security_type(&self) -> PyResult<&str> {
4382        Ok(self.security_type()?)
4383    }
4384
4385    #[getter]
4386    fn get_unit_of_measure(&self) -> PyResult<&str> {
4387        Ok(self.unit_of_measure()?)
4388    }
4389
4390    #[getter]
4391    fn get_underlying(&self) -> PyResult<&str> {
4392        Ok(self.underlying()?)
4393    }
4394
4395    #[getter]
4396    fn get_strike_price_currency(&self) -> PyResult<&str> {
4397        Ok(self.strike_price_currency()?)
4398    }
4399
4400    #[getter]
4401    fn get_instrument_class<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
4402        self.instrument_class()
4403            .map(|c| c.into_bound_py_any(py))
4404            .unwrap_or_else(|_| (self.instrument_class as u8 as char).into_bound_py_any(py))
4405    }
4406    #[setter]
4407    fn set_instrument_class(&mut self, instrument_class: InstrumentClass) {
4408        self.instrument_class = instrument_class as u8 as c_char;
4409    }
4410
4411    #[getter]
4412    fn get_match_algorithm<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
4413        self.match_algorithm()
4414            .map(|c| c.into_bound_py_any(py))
4415            .unwrap_or_else(|_| (self.match_algorithm as u8 as char).into_bound_py_any(py))
4416    }
4417    #[setter]
4418    fn set_match_algorithm(&mut self, match_algorithm: MatchAlgorithm) {
4419        self.match_algorithm = match_algorithm as u8 as c_char;
4420    }
4421
4422    #[getter]
4423    fn get_security_update_action<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
4424        self.security_update_action()
4425            .map(|c| c.into_bound_py_any(py))
4426            .unwrap_or_else(|_| (self.security_update_action as u8 as char).into_bound_py_any(py))
4427    }
4428    #[setter]
4429    fn set_security_update_action(&mut self, security_update_action: SecurityUpdateAction) {
4430        self.security_update_action = security_update_action as u8 as c_char;
4431    }
4432
4433    #[classattr]
4434    #[pyo3(name = "_dtypes")]
4435    fn py_dtypes() -> Vec<(String, String)> {
4436        Self::field_dtypes("")
4437    }
4438
4439    #[classattr]
4440    #[pyo3(name = "_price_fields")]
4441    fn py_price_fields() -> Vec<String> {
4442        Self::price_fields("")
4443    }
4444
4445    #[classattr]
4446    #[pyo3(name = "_timestamp_fields")]
4447    fn py_timestamp_fields() -> Vec<String> {
4448        Self::timestamp_fields("")
4449    }
4450
4451    #[classattr]
4452    #[pyo3(name = "_hidden_fields")]
4453    fn py_hidden_fields() -> Vec<String> {
4454        Self::hidden_fields("")
4455    }
4456
4457    #[classattr]
4458    #[pyo3(name = "_ordered_fields")]
4459    fn py_ordered_fields() -> Vec<String> {
4460        Self::ordered_fields("")
4461    }
4462}