Skip to main content

wmjtyd_libstock/data/
types.rs

1//! The utilities such as serialization and deserialization
2//! for `crypto-market`'s types.
3
4use bimap::BiMap;
5use crypto_crawler::{MarketType, MessageType};
6use crypto_msg_parser::TradeSide;
7use strum::{EnumString, FromRepr};
8
9macro_rules! create_bimap {
10    ($idn:ident { $lt:ty => $rt:ty, $($l:expr => $r:expr,)* }) => {
11        pub static $idn: once_cell::sync::Lazy<BiMap<$lt, $rt>> = once_cell::sync::Lazy::new(|| {
12            let mut map = BiMap::new();
13            $(map.insert($l, $r);)*
14            map
15        });
16    }
17}
18
19#[derive(Copy, Clone, FromRepr, strum::Display, EnumString, Debug, PartialEq)]
20#[strum(serialize_all = "lowercase")]
21pub enum Exchange {
22    Crypto = 1,
23    Ftx = 2,
24    Binance = 3,
25    Huobi = 8,
26    Kucoin = 10,
27    Okx = 11,
28}
29
30#[derive(Copy, Clone, FromRepr, strum::Display, EnumString, Debug, PartialEq)]
31#[strum(serialize_all = "lowercase")]
32pub enum InfoType {
33    Asks = 1,
34    Bids = 2,
35}
36
37create_bimap!(SYMBOL_PAIR {
38    u16 => &'static str,
39    1 => "BTC/USDT",
40    2 => "BTC/USD",
41    3 => "USDT/USD",
42});
43
44create_bimap!(PERIOD {
45    &'static str => u8,
46    "1m" => 1,
47    "5m" => 2,
48    "30m" => 3,
49    "1h" => 4,
50});
51
52create_bimap!(MARKET_TYPE_BIT {
53    MarketType => u8,
54    MarketType::Spot => 1,
55    MarketType::LinearFuture => 2,
56    MarketType::InverseFuture => 3,
57    MarketType::LinearSwap => 4,
58    MarketType::InverseSwap => 5,
59    MarketType::EuropeanOption => 6,
60    MarketType::QuantoFuture => 7,
61    MarketType::QuantoSwap => 8,
62    // Default: MarketType::Unknown => 0,
63});
64
65/// Serialize [`MessageType`] to 1 bit identifier.
66pub fn bit_serialize_message_type(mt: MessageType) -> u8 {
67    match mt {
68        MessageType::Trade => 1,
69        MessageType::BBO => 2,
70        MessageType::L2TopK => 3,
71        MessageType::L2Snapshot => 4,
72        MessageType::L2Event => 5,
73        MessageType::L3Snapshot => 6,
74        MessageType::L3Event => 7,
75        MessageType::Ticker => 8,
76        MessageType::Candlestick => 9,
77        MessageType::OpenInterest => 10,
78        MessageType::FundingRate => 11,
79        MessageType::LongShortRatio => 12,
80        MessageType::TakerVolume => 13,
81        _ => 0,
82    }
83}
84
85/// Deserialize a 1 bit identifier to a [`MessageType`].
86pub fn bit_deserialize_message_type(id: u8) -> MessageType {
87    match id {
88        1 => MessageType::Trade,
89        2 => MessageType::BBO,
90        3 => MessageType::L2TopK,
91        4 => MessageType::L2Snapshot,
92        5 => MessageType::L2Event,
93        6 => MessageType::L3Snapshot,
94        7 => MessageType::L3Event,
95        8 => MessageType::Ticker,
96        9 => MessageType::Candlestick,
97        10 => MessageType::OpenInterest,
98        11 => MessageType::FundingRate,
99        _ => MessageType::Other,
100    }
101}
102
103/// Serialize [`TradeSide`] to 1 bit identifier.
104pub fn bit_serialize_trade_side(side: TradeSide) -> u8 {
105    match side {
106        TradeSide::Buy => 1,
107        TradeSide::Sell => 2,
108    }
109}
110
111/// Deserialize a 1 bit identifier to a [`TradeSide`].
112pub fn bit_deserialize_trade_side(id: u8) -> DataTypesResult<TradeSide> {
113    Ok(match id {
114        1 => TradeSide::Buy,
115        2 => TradeSide::Sell,
116        _ => return Err(DataTypesError::UnexpectedTradeSide(id)),
117    })
118}
119
120#[derive(thiserror::Error, Debug)]
121pub enum DataTypesError {
122    #[error("unexpected trade side ID: {0}")]
123    UnexpectedTradeSide(u8),
124}
125
126pub type DataTypesResult<T> = Result<T, DataTypesError>;