nautilus_databento/decode/
custom.rs1use std::ffi::c_char;
17
18use databento::dbn;
19use nautilus_core::UnixNanos;
20use nautilus_model::{enums::FromU8, identifiers::InstrumentId, types::Quantity};
21
22use super::primitives::{
23 decode_optional_price, decode_optional_quantity, decode_price_or_undef, parse_order_side,
24};
25use crate::{
26 enums::{DatabentoStatisticType, DatabentoStatisticUpdateAction},
27 types::{DatabentoImbalance, DatabentoStatistics},
28};
29
30pub fn decode_imbalance_msg(
36 msg: &dbn::ImbalanceMsg,
37 instrument_id: InstrumentId,
38 price_precision: u8,
39 ts_init: Option<UnixNanos>,
40) -> anyhow::Result<DatabentoImbalance> {
41 let ts_event = msg.ts_recv.into();
42 let ts_init = ts_init.unwrap_or(ts_event);
43
44 Ok(DatabentoImbalance::new(
45 instrument_id,
46 decode_price_or_undef(msg.ref_price, price_precision),
47 decode_price_or_undef(msg.cont_book_clr_price, price_precision),
48 decode_price_or_undef(msg.auct_interest_clr_price, price_precision),
49 Quantity::new(f64::from(msg.paired_qty), 0),
50 Quantity::new(f64::from(msg.total_imbalance_qty), 0),
51 parse_order_side(msg.side),
52 msg.significant_imbalance as c_char,
53 msg.hd.ts_event.into(),
54 ts_event,
55 ts_init,
56 ))
57}
58
59pub fn decode_statistics_msg(
70 msg: &dbn::StatMsg,
71 instrument_id: InstrumentId,
72 price_precision: u8,
73 ts_init: Option<UnixNanos>,
74) -> anyhow::Result<Option<DatabentoStatistics>> {
75 let Some(stat_type) = u8::try_from(msg.stat_type)
76 .ok()
77 .and_then(DatabentoStatisticType::from_u8)
78 else {
79 log::warn!(
80 "Skipping unsupported `stat_type` {} for {instrument_id}",
81 msg.stat_type,
82 );
83 return Ok(None);
84 };
85 let update_action =
86 DatabentoStatisticUpdateAction::from_u8(msg.update_action).ok_or_else(|| {
87 anyhow::anyhow!("Invalid value for `update_action`: {}", msg.update_action)
88 })?;
89 let ts_event = msg.ts_recv.into();
90 let ts_init = ts_init.unwrap_or(ts_event);
91
92 Ok(Some(DatabentoStatistics::new(
93 instrument_id,
94 stat_type,
95 update_action,
96 decode_optional_price(msg.price, price_precision),
97 decode_optional_quantity(msg.quantity)?,
98 msg.channel_id,
99 msg.stat_flags,
100 msg.sequence,
101 msg.ts_ref.into(),
102 msg.ts_in_delta,
103 msg.hd.ts_event.into(),
104 ts_event,
105 ts_init,
106 )))
107}
108
109#[must_use]
115pub fn is_supported_stat_type(stat_type: u16) -> bool {
116 u8::try_from(stat_type)
117 .ok()
118 .and_then(DatabentoStatisticType::from_u8)
119 .is_some()
120}