use crate::Decimal;
#[cfg(feature = "serde")]
use pretty_simple_display::{DebugPretty, DisplaySimple};
#[derive(Clone, PartialEq)]
#[cfg_attr(not(feature = "serde"), derive(Debug))]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize, DebugPretty, DisplaySimple)
)]
pub struct Quote {
pub bid_price: Decimal,
pub bid_size: Decimal,
pub ask_price: Decimal,
pub ask_size: Decimal,
pub timestamp: u64,
}
impl Quote {
#[must_use]
pub fn spread(&self) -> Decimal {
self.ask_price - self.bid_price
}
#[must_use]
pub fn mid_price(&self) -> Decimal {
(self.bid_price + self.ask_price) / Decimal::from(2)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::dec;
#[test]
fn test_quote_spread() {
let quote = Quote {
bid_price: dec!(100.0),
bid_size: dec!(10.0),
ask_price: dec!(101.0),
ask_size: dec!(10.0),
timestamp: 1000,
};
assert_eq!(quote.spread(), dec!(1.0));
}
#[test]
fn test_quote_mid_price() {
let quote = Quote {
bid_price: dec!(100.0),
bid_size: dec!(10.0),
ask_price: dec!(102.0),
ask_size: dec!(10.0),
timestamp: 1000,
};
assert_eq!(quote.mid_price(), dec!(101.0));
}
#[test]
fn test_quote_creation() {
let quote = Quote {
bid_price: dec!(99.5),
bid_size: dec!(5.0),
ask_price: dec!(100.5),
ask_size: dec!(7.5),
timestamp: 123456789,
};
assert_eq!(quote.bid_price, dec!(99.5));
assert_eq!(quote.bid_size, dec!(5.0));
assert_eq!(quote.ask_price, dec!(100.5));
assert_eq!(quote.ask_size, dec!(7.5));
assert_eq!(quote.timestamp, 123456789);
}
#[cfg(feature = "serde")]
#[test]
fn test_quote_display() {
let quote = Quote {
bid_price: dec!(100.0),
bid_size: dec!(10.0),
ask_price: dec!(101.0),
ask_size: dec!(10.0),
timestamp: 1000,
};
let display_str = format!("{}", quote);
assert!(display_str.contains("bid_price"));
assert!(display_str.contains("100"));
assert!(display_str.contains("ask_price"));
assert!(display_str.contains("101"));
}
}