use crypto_market_type::MarketType;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use strum_macros::{Display, EnumString};
use crate::order::Order;
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, Display, Debug, EnumString)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum MessageType {
Trade,
L2Event,
L2Snapshot,
L3Event,
L3Snapshot,
#[serde(rename = "bbo")]
#[allow(clippy::upper_case_acronyms)]
BBO,
Ticker,
Candlestick,
FundingRate,
}
macro_rules! add_common_fields {
(
$(#[$outer:meta])*
struct $name:ident {
$(
$(#[$inner:meta])*
$field:ident: $ty:ty
),* $(,)*
}
) => {
$(#[$outer])*
pub struct $name {
/// The exchange name, unique for each exchage
pub exchange: String,
pub market_type: MarketType,
pub symbol: String,
pub pair: String,
pub msg_type: MessageType,
pub timestamp: i64,
pub raw: Value,
$(
$(#[$inner])*
pub $field: $ty
),*
}
};
}
add_common_fields!(
#[derive(Serialize, Deserialize)]
struct Msg {}
);
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, Display, Debug, EnumString)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum TradeSide {
Buy,
Sell,
}
#[derive(Serialize, Deserialize)]
pub struct TradeMsg {
pub exchange: String,
pub market_type: MarketType,
pub symbol: String,
pub pair: String,
pub msg_type: MessageType,
pub timestamp: i64,
pub price: f64,
pub quantity_base: f64,
pub quantity_quote: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub quantity_contract: Option<f64>,
pub side: TradeSide,
pub trade_id: String,
pub raw: Value,
}
#[derive(Serialize, Deserialize)]
pub struct OrderBookMsg {
pub exchange: String,
pub market_type: MarketType,
pub symbol: String,
pub pair: String,
pub msg_type: MessageType,
pub timestamp: i64,
pub asks: Vec<Order>,
pub bids: Vec<Order>,
pub snapshot: bool,
pub raw: Value,
}
#[derive(Serialize, Deserialize)]
pub struct FundingRateMsg {
pub exchange: String,
pub market_type: MarketType,
pub symbol: String,
pub pair: String,
pub msg_type: MessageType,
pub timestamp: i64,
pub funding_rate: f64,
pub funding_time: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub estimated_rate: Option<f64>,
pub raw: Value,
}
add_common_fields!(
#[derive(Serialize, Deserialize)]
struct TickerMsg {
open: f64,
high: f64,
low: f64,
close: f64,
volume: f64,
quote_volume: f64,
last_quantity: Option<f64>,
best_bid_price: Option<f64>,
best_bid_quantity: Option<f64>,
best_ask_price: Option<f64>,
best_ask_quantity: Option<f64>,
open_interest: Option<f64>,
open_interest_quote: Option<f64>,
}
);
add_common_fields!(
#[derive(Serialize, Deserialize)]
struct BboMsg {
bid_price: f64,
bid_quantity: f64,
ask_price: f64,
ask_quantity: f64,
}
);
add_common_fields!(
#[derive(Serialize, Deserialize)]
struct KlineMsg {
open: f64,
high: f64,
low: f64,
close: f64,
volume: f64,
period: String,
quote_volume: Option<f64>,
}
);