use std::{collections::HashMap, ffi::c_char, sync::Arc};
use databento::dbn;
use nautilus_core::UnixNanos;
use nautilus_model::{
data::{HasTsInit, custom::CustomDataTrait},
enums::OrderSide,
identifiers::InstrumentId,
types::{Price, Quantity},
};
use serde::{Deserialize, Serialize};
use ustr::Ustr;
use super::enums::{DatabentoStatisticType, DatabentoStatisticUpdateAction};
#[derive(Debug, Clone)]
pub struct SubscriptionAckEvent {
pub schema: String,
pub message: String,
pub ts_received: UnixNanos,
}
pub type PublisherId = u16;
pub type Dataset = Ustr;
#[cfg_attr(
feature = "python",
pyo3::pyclass(
module = "nautilus_trader.core.nautilus_pyo3.databento",
from_py_object
)
)]
#[cfg_attr(
feature = "python",
pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.databento")
)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
pub struct DatabentoPublisher {
pub publisher_id: PublisherId,
pub dataset: dbn::Dataset,
pub venue: dbn::Venue,
pub description: String,
}
#[cfg_attr(
feature = "python",
pyo3::pyclass(
module = "nautilus_trader.core.nautilus_pyo3.databento",
from_py_object
)
)]
#[cfg_attr(
feature = "python",
pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.databento")
)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct DatabentoImbalance {
pub instrument_id: InstrumentId,
pub ref_price: Price,
pub cont_book_clr_price: Price,
pub auct_interest_clr_price: Price,
pub paired_qty: Quantity,
pub total_imbalance_qty: Quantity,
pub side: OrderSide,
pub significant_imbalance: c_char,
pub ts_event: UnixNanos,
pub ts_recv: UnixNanos,
pub ts_init: UnixNanos,
}
impl DatabentoImbalance {
#[must_use]
pub fn get_metadata(
instrument_id: &InstrumentId,
price_precision: u8,
size_precision: u8,
) -> HashMap<String, String> {
let mut metadata = HashMap::new();
metadata.insert("instrument_id".to_string(), instrument_id.to_string());
metadata.insert("price_precision".to_string(), price_precision.to_string());
metadata.insert("size_precision".to_string(), size_precision.to_string());
metadata
}
#[allow(clippy::too_many_arguments)]
#[must_use]
pub const fn new(
instrument_id: InstrumentId,
ref_price: Price,
cont_book_clr_price: Price,
auct_interest_clr_price: Price,
paired_qty: Quantity,
total_imbalance_qty: Quantity,
side: OrderSide,
significant_imbalance: c_char,
ts_event: UnixNanos,
ts_recv: UnixNanos,
ts_init: UnixNanos,
) -> Self {
Self {
instrument_id,
ref_price,
cont_book_clr_price,
auct_interest_clr_price,
paired_qty,
total_imbalance_qty,
side,
significant_imbalance,
ts_event,
ts_recv,
ts_init,
}
}
}
impl HasTsInit for DatabentoImbalance {
fn ts_init(&self) -> UnixNanos {
self.ts_init
}
}
impl CustomDataTrait for DatabentoImbalance {
fn type_name(&self) -> &'static str {
"DatabentoImbalance"
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn ts_event(&self) -> UnixNanos {
self.ts_event
}
fn to_json(&self) -> anyhow::Result<String> {
Ok(serde_json::to_string(self)?)
}
fn clone_arc(&self) -> Arc<dyn CustomDataTrait> {
Arc::new(self.clone())
}
fn eq_arc(&self, other: &dyn CustomDataTrait) -> bool {
if let Some(o) = other.as_any().downcast_ref::<Self>() {
self == o
} else {
false
}
}
#[cfg(feature = "python")]
fn to_pyobject(&self, py: pyo3::Python<'_>) -> pyo3::PyResult<pyo3::Py<pyo3::PyAny>> {
nautilus_model::data::custom::clone_pyclass_to_pyobject(self, py)
}
fn type_name_static() -> &'static str {
"DatabentoImbalance"
}
fn from_json(value: serde_json::Value) -> anyhow::Result<Arc<dyn CustomDataTrait>> {
let parsed: Self = serde_json::from_value(value)?;
Ok(Arc::new(parsed))
}
}
#[cfg_attr(
feature = "python",
pyo3::pyclass(
module = "nautilus_trader.core.nautilus_pyo3.databento",
from_py_object
)
)]
#[cfg_attr(
feature = "python",
pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.databento")
)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct DatabentoStatistics {
pub instrument_id: InstrumentId,
pub stat_type: DatabentoStatisticType,
pub update_action: DatabentoStatisticUpdateAction,
pub price: Option<Price>,
pub quantity: Option<Quantity>,
pub channel_id: u16,
pub stat_flags: u8,
pub sequence: u32,
pub ts_ref: UnixNanos,
pub ts_in_delta: i32,
pub ts_event: UnixNanos,
pub ts_recv: UnixNanos,
pub ts_init: UnixNanos,
}
impl DatabentoStatistics {
#[must_use]
pub fn get_metadata(
instrument_id: &InstrumentId,
price_precision: u8,
size_precision: u8,
) -> HashMap<String, String> {
let mut metadata = HashMap::new();
metadata.insert("instrument_id".to_string(), instrument_id.to_string());
metadata.insert("price_precision".to_string(), price_precision.to_string());
metadata.insert("size_precision".to_string(), size_precision.to_string());
metadata
}
#[allow(clippy::too_many_arguments)]
#[must_use]
pub const fn new(
instrument_id: InstrumentId,
stat_type: DatabentoStatisticType,
update_action: DatabentoStatisticUpdateAction,
price: Option<Price>,
quantity: Option<Quantity>,
channel_id: u16,
stat_flags: u8,
sequence: u32,
ts_ref: UnixNanos,
ts_in_delta: i32,
ts_event: UnixNanos,
ts_recv: UnixNanos,
ts_init: UnixNanos,
) -> Self {
Self {
instrument_id,
stat_type,
update_action,
price,
quantity,
channel_id,
stat_flags,
sequence,
ts_ref,
ts_in_delta,
ts_event,
ts_recv,
ts_init,
}
}
}
impl HasTsInit for DatabentoStatistics {
fn ts_init(&self) -> UnixNanos {
self.ts_init
}
}
impl CustomDataTrait for DatabentoStatistics {
fn type_name(&self) -> &'static str {
"DatabentoStatistics"
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn ts_event(&self) -> UnixNanos {
self.ts_event
}
fn to_json(&self) -> anyhow::Result<String> {
Ok(serde_json::to_string(self)?)
}
fn clone_arc(&self) -> Arc<dyn CustomDataTrait> {
Arc::new(self.clone())
}
fn eq_arc(&self, other: &dyn CustomDataTrait) -> bool {
if let Some(o) = other.as_any().downcast_ref::<Self>() {
self == o
} else {
false
}
}
#[cfg(feature = "python")]
fn to_pyobject(&self, py: pyo3::Python<'_>) -> pyo3::PyResult<pyo3::Py<pyo3::PyAny>> {
nautilus_model::data::custom::clone_pyclass_to_pyobject(self, py)
}
fn type_name_static() -> &'static str {
"DatabentoStatistics"
}
fn from_json(value: serde_json::Value) -> anyhow::Result<Arc<dyn CustomDataTrait>> {
let parsed: Self = serde_json::from_value(value)?;
Ok(Arc::new(parsed))
}
}