use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use super::common::{Timestamp, string_u64};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BookSide {
#[serde(rename = "SELL")]
Sell,
#[serde(rename = "BUYI")]
Buy,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrderBookLevel {
#[serde(rename = "aid")]
pub asset_id: String,
#[serde(rename = "anm")]
pub asset_name: String,
#[serde(rename = "s")]
pub side: BookSide,
#[serde(rename = "p", with = "rust_decimal::serde::str")]
pub price: Decimal,
#[serde(rename = "pc")]
pub price_currency: String,
#[serde(rename = "pn")]
pub price_notation: String,
#[serde(rename = "q", with = "rust_decimal::serde::str")]
pub quantity: Decimal,
#[serde(rename = "qc")]
pub quantity_currency: String,
#[serde(rename = "qn")]
pub quantity_notation: String,
#[serde(rename = "ve")]
pub venue_of_execution: String,
#[serde(rename = "no", with = "string_u64")]
pub number_of_orders: u64,
#[serde(rename = "ts")]
pub trading_system: String,
#[serde(rename = "pdt")]
pub published_at: Timestamp,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(from = "RawOrderBook")]
pub struct OrderBook {
pub asks: Vec<OrderBookLevel>,
pub bids: Vec<OrderBookLevel>,
pub timestamp: Timestamp,
}
#[derive(Deserialize)]
struct RawOrderBook {
data: RawOrderBookData,
metadata: RawTimestampMeta,
}
#[derive(Deserialize)]
struct RawOrderBookData {
asks: Vec<OrderBookLevel>,
bids: Vec<OrderBookLevel>,
}
#[derive(Deserialize)]
struct RawTimestampMeta {
timestamp: Timestamp,
}
impl From<RawOrderBook> for OrderBook {
fn from(raw: RawOrderBook) -> Self {
let mut asks = raw.data.asks;
let mut bids = raw.data.bids;
asks.sort_by_key(|level| level.price);
bids.sort_by_key(|level| std::cmp::Reverse(level.price));
Self {
asks,
bids,
timestamp: raw.metadata.timestamp,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Candle {
pub start: Timestamp,
#[serde(with = "rust_decimal::serde::str")]
pub open: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub high: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub low: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub close: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub volume: Decimal,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Ticker {
pub symbol: String,
#[serde(with = "rust_decimal::serde::str")]
pub bid: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub ask: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub mid: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub last_price: Decimal,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(from = "RawTickers")]
pub struct Tickers {
pub tickers: Vec<Ticker>,
pub timestamp: Timestamp,
}
#[derive(Deserialize)]
struct RawTickers {
data: Vec<Ticker>,
metadata: RawTimestampMeta,
}
impl From<RawTickers> for Tickers {
fn from(raw: RawTickers) -> Self {
Self {
tickers: raw.data,
timestamp: raw.metadata.timestamp,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Trade {
#[serde(rename = "tdt")]
pub traded_at: Timestamp,
#[serde(rename = "aid")]
pub asset_id: String,
#[serde(rename = "anm")]
pub asset_name: String,
#[serde(rename = "p", with = "rust_decimal::serde::str")]
pub price: Decimal,
#[serde(rename = "pc")]
pub price_currency: String,
#[serde(rename = "pn")]
pub price_notation: String,
#[serde(rename = "q", with = "rust_decimal::serde::str")]
pub quantity: Decimal,
#[serde(rename = "qc")]
pub quantity_currency: String,
#[serde(rename = "qn")]
pub quantity_notation: String,
#[serde(rename = "ve")]
pub venue_of_execution: String,
#[serde(rename = "pdt")]
pub published_at: Timestamp,
#[serde(rename = "vp")]
pub venue_of_publication: String,
#[serde(rename = "tid")]
pub trade_id: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(from = "RawLastTrades")]
pub struct LastTrades {
pub trades: Vec<Trade>,
pub timestamp: Timestamp,
}
#[derive(Deserialize)]
struct RawLastTrades {
data: Vec<Trade>,
metadata: RawTimestampMeta,
}
impl From<RawLastTrades> for LastTrades {
fn from(raw: RawLastTrades) -> Self {
Self {
trades: raw.data,
timestamp: raw.metadata.timestamp,
}
}
}