use pricelevel::PriceLevelSnapshot;
use serde::{Deserialize, Serialize};
use tracing::trace;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrderBookSnapshot {
pub symbol: String,
pub timestamp: u64,
pub bids: Vec<PriceLevelSnapshot>,
pub asks: Vec<PriceLevelSnapshot>,
}
impl OrderBookSnapshot {
pub fn best_bid(&self) -> Option<(u64, u64)> {
let bids = self
.bids
.iter()
.map(|level| (level.price, level.visible_quantity))
.max_by_key(|&(price, _)| price);
trace!("best_bid: {:?}", bids);
bids
}
pub fn best_ask(&self) -> Option<(u64, u64)> {
let ask = self
.asks
.iter()
.map(|level| (level.price, level.visible_quantity))
.min_by_key(|&(price, _)| price);
trace!("best_ask: {:?}", ask);
ask
}
pub fn mid_price(&self) -> Option<f64> {
let mid_price = match (self.best_bid(), self.best_ask()) {
(Some((bid_price, _)), Some((ask_price, _))) => {
Some((bid_price as f64 + ask_price as f64) / 2.0)
}
_ => None,
};
trace!("mid_price: {:?}", mid_price);
mid_price
}
pub fn spread(&self) -> Option<u64> {
let spread = match (self.best_bid(), self.best_ask()) {
(Some((bid_price, _)), Some((ask_price, _))) => {
Some(ask_price.saturating_sub(bid_price))
}
_ => None,
};
trace!("spread: {:?}", spread);
spread
}
pub fn total_bid_volume(&self) -> u64 {
let volume = self.bids.iter().map(|level| level.total_quantity()).sum();
trace!("total_bid_volume: {:?}", volume);
volume
}
pub fn total_ask_volume(&self) -> u64 {
let volume = self.asks.iter().map(|level| level.total_quantity()).sum();
trace!("total_ask_volume: {:?}", volume);
volume
}
pub fn total_bid_value(&self) -> u64 {
let value = self
.bids
.iter()
.map(|level| level.price * level.total_quantity())
.sum();
trace!("total_bid_value: {:?}", value);
value
}
pub fn total_ask_value(&self) -> u64 {
let value = self
.asks
.iter()
.map(|level| level.price * level.total_quantity())
.sum();
trace!("total_ask_value: {:?}", value);
value
}
}