Skip to content

Commit

Permalink
Add RecordFlag enum
Browse files Browse the repository at this point in the history
  • Loading branch information
cjdsellers committed Apr 11, 2024
1 parent 47a8467 commit a8592cd
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 3 deletions.
1 change: 1 addition & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Released on TBD (UTC).
- Improved `CacheDatabaseAdapter` graceful close and thread join
- Improved `MessageBus` graceful close and thread join
- Improved `modify_order` error logging when order values remain unchanged
- Added `RecordFlag` enum for Rust and Python
- Interactive Brokers further improvements and fixes, thanks @rsmb7z
- Ported Bias indicator to Rust, thanks @Pushkarm029

Expand Down
5 changes: 3 additions & 2 deletions nautilus_core/adapters/src/databento/live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use nautilus_model::{
deltas::{OrderBookDeltas, OrderBookDeltas_API},
Data,
},
enums::RecordFlag,
identifiers::{instrument_id::InstrumentId, symbol::Symbol, venue::Venue},
instruments::InstrumentType,
};
Expand Down Expand Up @@ -267,12 +268,12 @@ impl DatabentoFeedHandler {
);

// Check if last message in the packet
if msg.flags & dbn::flags::LAST == 0 {
if !RecordFlag::LAST.matches(msg.flags) {
continue; // NOT last message
}

// Check if snapshot
if msg.flags & dbn::flags::SNAPSHOT != 0 {
if RecordFlag::SNAPSHOT.matches(msg.flags) {
continue; // Buffer snapshot
}

Expand Down
46 changes: 46 additions & 0 deletions nautilus_core/model/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,52 @@ pub enum PriceType {
Last = 4,
}

/// A bitflag for a data record.
#[repr(C)]
#[derive(
Copy,
Clone,
Debug,
Display,
Hash,
PartialEq,
Eq,
PartialOrd,
Ord,
AsRefStr,
FromRepr,
EnumIter,
EnumString,
)]
#[strum(ascii_case_insensitive)]
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
#[cfg_attr(
feature = "python",
pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model.enums")
)]
#[allow(non_camel_case_types)]
pub enum RecordFlag {
/// Last message in the packet from the venue for a given `instrument_id`.
LAST = 1 << 7, // 128
/// Top-of-book message, not an individual order.
TOB = 1 << 6, // 64
/// Message sourced from a replay, such as a snapshot server.
SNAPSHOT = 1 << 5, // 32
/// Aggregated price level message, not an individual order.
MBP = 1 << 4, // 16
/// Reserved for future use.
RESERVED_2 = 1 << 3, // 8
/// Reserved for future use.
RESERVED_1 = 1 << 2, // 4
}

impl RecordFlag {
/// Checks if the flag matches a given value.
pub fn matches(self, value: u8) -> bool {
(self as u8) & value != 0
}
}

/// The 'Time in Force' instruction for an order in the financial market.
#[repr(C)]
#[derive(
Expand Down
83 changes: 82 additions & 1 deletion nautilus_core/model/src/python/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use crate::{
AccountType, AggregationSource, AggressorSide, AssetClass, BarAggregation, BookAction,
BookType, ContingencyType, CurrencyType, HaltReason, InstrumentClass, InstrumentCloseType,
LiquiditySide, MarketStatus, OmsType, OptionKind, OrderSide, OrderStatus, OrderType,
PositionSide, PriceType, TimeInForce, TradingState, TrailingOffsetType, TriggerType,
PositionSide, PriceType, RecordFlag, TimeInForce, TradingState, TrailingOffsetType,
TriggerType,
},
python::common::EnumIterator,
};
Expand Down Expand Up @@ -1629,6 +1630,86 @@ impl PriceType {
}
}

#[pymethods]
impl RecordFlag {
#[new]
fn py_new(py: Python<'_>, value: &PyAny) -> PyResult<Self> {
let t = Self::type_object(py);
Self::py_from_str(t, value)
}

fn __hash__(&self) -> isize {
*self as isize
}

fn __str__(&self) -> String {
self.to_string()
}

fn __repr__(&self) -> String {
format!(
"<{}.{}: '{}'>",
stringify!(RecordFlag),
self.name(),
self.value(),
)
}

#[getter]
#[must_use]
pub fn name(&self) -> String {
self.to_string()
}

#[getter]
#[must_use]
pub fn value(&self) -> u8 {
*self as u8
}

#[classmethod]
fn variants(_: &PyType, py: Python<'_>) -> EnumIterator {
EnumIterator::new::<Self>(py)
}

#[classmethod]
#[pyo3(name = "from_str")]
fn py_from_str(_: &PyType, data: &PyAny) -> PyResult<Self> {
let data_str: &str = data.str().and_then(|s| s.extract())?;
let tokenized = data_str.to_uppercase();
Self::from_str(&tokenized).map_err(to_pyvalue_err)
}

#[classattr]
#[pyo3(name = "LAST")]
fn py_last() -> Self {
Self::LAST
}

#[classattr]
#[pyo3(name = "TOB")]
fn py_tob() -> Self {
Self::TOB
}

#[classattr]
#[pyo3(name = "SNAPSHOT")]
fn py_snapshot() -> Self {
Self::SNAPSHOT
}

#[classattr]
#[pyo3(name = "MBP")]
fn py_mbp() -> Self {
Self::MBP
}

#[pyo3(name = "matches")]
fn py_matches(&self, value: u8) -> bool {
self.matches(value)
}
}

#[pymethods]
impl TimeInForce {
#[new]
Expand Down
6 changes: 6 additions & 0 deletions nautilus_trader/core/nautilus_pyo3.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,12 @@ class PriceType(Enum):
MID = "MID"
LAST = "LAST"

class RecordFlag(Enum):
LAST = "LAST"
TOB = "TOB"
SNAPSHOT = "SNAPSHOT"
MBP = "MBP"

class TimeInForce(Enum):
GTC = "GTC"
IOC = "IOC"
Expand Down

0 comments on commit a8592cd

Please sign in to comment.