nautilus_model/data/status.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
// -------------------------------------------------------------------------------------------------
// Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
// https://nautechsystems.io
//
// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -------------------------------------------------------------------------------------------------
//! An `InstrumentStatus` data type representing a change in an instrument market status.
use std::{
collections::HashMap,
fmt::{Display, Formatter},
hash::Hash,
};
use derive_builder::Builder;
use nautilus_core::{nanos::UnixNanos, serialization::Serializable};
use serde::{Deserialize, Serialize};
use ustr::Ustr;
use super::GetTsInit;
use crate::{enums::MarketStatusAction, identifiers::InstrumentId};
/// Represents an event that indicates a change in an instrument market status.
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Builder)]
#[serde(tag = "type")]
#[cfg_attr(
feature = "python",
pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model")
)]
#[cfg_attr(feature = "trivial_copy", derive(Copy))]
pub struct InstrumentStatus {
/// The instrument ID for the status change.
pub instrument_id: InstrumentId,
/// The instrument market status action.
pub action: MarketStatusAction,
/// UNIX timestamp (nanoseconds) when the status event occurred.
pub ts_event: UnixNanos,
/// UNIX timestamp (nanoseconds) when the struct was initialized.
pub ts_init: UnixNanos,
/// Additional details about the cause of the status change.
pub reason: Option<Ustr>,
/// Further information about the status change (if provided).
pub trading_event: Option<Ustr>,
/// The state of trading in the instrument.
pub is_trading: Option<bool>,
/// The state of quoting in the instrument.
pub is_quoting: Option<bool>,
/// The state of short sell restrictions for the instrument (if applicable).
pub is_short_sell_restricted: Option<bool>,
}
impl InstrumentStatus {
/// Creates a new [`InstrumentStatus`] instance.
#[allow(clippy::too_many_arguments)]
pub fn new(
instrument_id: InstrumentId,
action: MarketStatusAction,
ts_event: UnixNanos,
ts_init: UnixNanos,
reason: Option<Ustr>,
trading_event: Option<Ustr>,
is_trading: Option<bool>,
is_quoting: Option<bool>,
is_short_sell_restricted: Option<bool>,
) -> Self {
Self {
instrument_id,
action,
ts_event,
ts_init,
reason,
trading_event,
is_trading,
is_quoting,
is_short_sell_restricted,
}
}
/// Returns the metadata for the type, for use with serialization formats.
#[must_use]
pub fn get_metadata(instrument_id: &InstrumentId) -> HashMap<String, String> {
let mut metadata = HashMap::new();
metadata.insert("instrument_id".to_string(), instrument_id.to_string());
metadata
}
}
// TODO: Revisit this
impl Display for InstrumentStatus {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{},{},{},{}",
self.instrument_id, self.action, self.ts_event, self.ts_init,
)
}
}
impl Serializable for InstrumentStatus {}
impl GetTsInit for InstrumentStatus {
fn ts_init(&self) -> UnixNanos {
self.ts_init
}
}
////////////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////////////
#[cfg(test)]
mod tests {
use nautilus_core::serialization::Serializable;
use rstest::rstest;
use super::*;
use crate::data::stubs::stub_instrument_status;
#[rstest]
fn test_to_string(stub_instrument_status: InstrumentStatus) {
assert_eq!(stub_instrument_status.to_string(), "MSFT.XNAS,TRADING,1,2");
}
#[rstest]
fn test_json_serialization(stub_instrument_status: InstrumentStatus) {
let serialized = stub_instrument_status.as_json_bytes().unwrap();
let deserialized = InstrumentStatus::from_json_bytes(serialized.as_ref()).unwrap();
assert_eq!(deserialized, stub_instrument_status);
}
#[rstest]
fn test_msgpack_serialization(stub_instrument_status: InstrumentStatus) {
let serialized = stub_instrument_status.as_msgpack_bytes().unwrap();
let deserialized = InstrumentStatus::from_msgpack_bytes(serialized.as_ref()).unwrap();
assert_eq!(deserialized, stub_instrument_status);
}
}