Skip to content

Commit

Permalink
Adds commonly used attributes to the QuoteResponse struct.
Browse files Browse the repository at this point in the history
  • Loading branch information
z-Wind committed Jun 1, 2024
1 parent 4f9de78 commit e3f77c1
Showing 1 changed file with 302 additions and 1 deletion.
303 changes: 302 additions & 1 deletion src/model/market_data/quote_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,279 @@ pub enum QuoteResponse {
Option(Box<option::OptionResponse>),
}

impl QuoteResponse {
/// Returns the symbol of the quote
pub fn symbol(&self) -> &str {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => &x.symbol,
QuoteResponse::Forex(x) => &x.symbol,
QuoteResponse::Future(x) => &x.symbol,
QuoteResponse::FutureOption(x) => &x.symbol,
QuoteResponse::Index(x) => &x.symbol,
QuoteResponse::MutualFund(x) => &x.symbol,
QuoteResponse::Option(x) => &x.symbol,
}
}

/// Returns the 52-week high price
pub fn n52week_high(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.n52week_high),
QuoteResponse::Forex(x) => Some(x.quote.n52week_high),
QuoteResponse::Future(_) => None,
QuoteResponse::FutureOption(_) => None,
QuoteResponse::Index(x) => Some(x.quote.n52week_high),
QuoteResponse::MutualFund(x) => Some(x.quote.n52week_high),
QuoteResponse::Option(_) => None,
}
}

/// Returns the 52-week low price
pub fn n52week_low(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.n52week_low),
QuoteResponse::Forex(x) => Some(x.quote.n52week_low),
QuoteResponse::Future(_) => None,
QuoteResponse::FutureOption(_) => None,
QuoteResponse::Index(x) => Some(x.quote.n52week_low),
QuoteResponse::MutualFund(x) => Some(x.quote.n52week_low),
QuoteResponse::Option(_) => None,
}
}

/// Returns the current best ask price
pub fn ask_price(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.ask_price),
QuoteResponse::Forex(x) => Some(x.quote.ask_price),
QuoteResponse::Future(x) => Some(x.quote.ask_price),
QuoteResponse::FutureOption(x) => Some(x.quote.ask_price),
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.ask_price),
}
}

/// Returns the number of shares for ask
pub fn ask_size(&self) -> Option<i64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.ask_size),
QuoteResponse::Forex(x) => Some(x.quote.ask_size),
QuoteResponse::Future(x) => Some(x.quote.ask_size),
QuoteResponse::FutureOption(x) => Some(x.quote.ask_size),
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.ask_size),
}
}

/// Returns the last ask time in Utc format
pub fn ask_time(&self) -> Option<chrono::DateTime<chrono::Utc>> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.ask_time),
QuoteResponse::Forex(_) => None,
QuoteResponse::Future(x) => Some(x.quote.ask_time),
QuoteResponse::FutureOption(_) => None,
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(_) => None,
}
}

/// Returns the current best bid price
pub fn bid_price(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.bid_price),
QuoteResponse::Forex(x) => Some(x.quote.bid_price),
QuoteResponse::Future(x) => Some(x.quote.bid_price),
QuoteResponse::FutureOption(x) => Some(x.quote.bid_price),
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.bid_price),
}
}

/// Returns the number of shares for bid
pub fn bid_size(&self) -> Option<i64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.bid_size),
QuoteResponse::Forex(x) => Some(x.quote.bid_size),
QuoteResponse::Future(x) => Some(x.quote.bid_size),
QuoteResponse::FutureOption(x) => Some(x.quote.bid_size),
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.bid_size),
}
}

/// Returns the last bid time in Utc format
pub fn bid_time(&self) -> Option<chrono::DateTime<chrono::Utc>> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.bid_time),
QuoteResponse::Forex(_) => None,
QuoteResponse::Future(x) => Some(x.quote.bid_time),
QuoteResponse::FutureOption(_) => None,
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(_) => None,
}
}

/// Returns the previous day's closing price
pub fn close_price(&self) -> f64 {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => x.quote.close_price,
QuoteResponse::Forex(x) => x.quote.close_price,
QuoteResponse::Future(x) => x.quote.close_price,
QuoteResponse::FutureOption(x) => x.quote.close_price,
QuoteResponse::Index(x) => x.quote.close_price,
QuoteResponse::MutualFund(x) => x.quote.close_price,
QuoteResponse::Option(x) => x.quote.close_price,
}
}

/// Returns the day's high trade price
pub fn high_price(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.high_price),
QuoteResponse::Forex(x) => Some(x.quote.high_price),
QuoteResponse::Future(x) => Some(x.quote.high_price),
QuoteResponse::FutureOption(x) => Some(x.quote.high_price),
QuoteResponse::Index(x) => Some(x.quote.high_price),
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.high_price),
}
}

/// Returns the latest traded price
pub fn last_price(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.last_price),
QuoteResponse::Forex(x) => Some(x.quote.last_price),
QuoteResponse::Future(x) => Some(x.quote.last_price),
QuoteResponse::FutureOption(x) => Some(x.quote.last_price),
QuoteResponse::Index(x) => Some(x.quote.last_price),
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.last_price),
}
}

/// Returns the number of shares traded with the last trade
pub fn last_size(&self) -> Option<i64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.last_size),
QuoteResponse::Forex(x) => Some(x.quote.last_size),
QuoteResponse::Future(x) => Some(x.quote.last_size),
QuoteResponse::FutureOption(x) => Some(x.quote.last_size),
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.last_size),
}
}

/// Returns the day's low trade price
pub fn low_price(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.low_price),
QuoteResponse::Forex(x) => Some(x.quote.low_price),
QuoteResponse::Future(x) => Some(x.quote.low_price),
QuoteResponse::FutureOption(x) => Some(x.quote.low_price),
QuoteResponse::Index(x) => Some(x.quote.low_price),
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.low_price),
}
}

/// Returns the current last-prev close price difference
pub fn net_change(&self) -> f64 {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => x.quote.net_change,
QuoteResponse::Forex(x) => x.quote.net_change,
QuoteResponse::Future(x) => x.quote.net_change,
QuoteResponse::FutureOption(x) => x.quote.net_change,
QuoteResponse::Index(x) => x.quote.net_change,
QuoteResponse::MutualFund(x) => x.quote.net_change,
QuoteResponse::Option(x) => x.quote.net_change,
}
}

/// Returns the day's open trade price
pub fn open_price(&self) -> Option<f64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.open_price),
QuoteResponse::Forex(x) => Some(x.quote.open_price),
QuoteResponse::Future(x) => Some(x.quote.open_price),
QuoteResponse::FutureOption(x) => Some(x.quote.open_price),
QuoteResponse::Index(x) => Some(x.quote.open_price),
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.open_price),
}
}

/// Returns the time of the latest quote in Utc format
pub fn quote_time(&self) -> Option<chrono::DateTime<chrono::Utc>> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.quote_time),
QuoteResponse::Forex(x) => Some(x.quote.quote_time),
QuoteResponse::Future(x) => Some(x.quote.quote_time),
QuoteResponse::FutureOption(x) => Some(x.quote.quote_time),
QuoteResponse::Index(_) => None,
QuoteResponse::MutualFund(_) => None,
QuoteResponse::Option(x) => Some(x.quote.quote_time),
}
}

/// Returns the time of the last trade in Utc format
pub fn trade_time(&self) -> chrono::DateTime<chrono::Utc> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => x.quote.trade_time,
QuoteResponse::Forex(x) => x.quote.trade_time,
QuoteResponse::Future(x) => x.quote.trade_time,
QuoteResponse::FutureOption(x) => x.quote.trade_time,
QuoteResponse::Index(x) => x.quote.trade_time,
QuoteResponse::MutualFund(x) => x.quote.trade_time,
QuoteResponse::Option(x) => x.quote.trade_time,
}
}

/// Returns the total volume of trades for the day including pre/post market
pub fn total_volume(&self) -> Option<u64> {
match self {
QuoteResponse::Bond(x) => unimplemented!("{x}"),
QuoteResponse::Equity(x) => Some(x.quote.total_volume),
QuoteResponse::Forex(x) => Some(x.quote.total_volume),
QuoteResponse::Future(x) => Some(x.quote.total_volume),
QuoteResponse::FutureOption(x) => Some(x.quote.total_volume),
QuoteResponse::Index(x) => Some(x.quote.total_volume),
QuoteResponse::MutualFund(x) => x.quote.total_volume,
QuoteResponse::Option(x) => Some(x.quote.total_volume),
}
}
}

#[cfg(test)]
mod tests {
use super::*;

use std::collections::HashMap;
use float_cmp::assert_approx_eq;

#[test]
fn test_de() {
Expand All @@ -61,5 +329,38 @@ mod tests {
let val = serde_json::from_str::<QuoteResponseMap>(json);
println!("{val:?}");
assert!(val.is_ok());

let result = val.unwrap().responses.remove("AAPL").unwrap();
assert_eq!("AAPL", result.symbol());
assert_approx_eq!(f64, 199.62, result.n52week_high().unwrap());
assert_approx_eq!(f64, 164.075, result.n52week_low().unwrap());
assert_approx_eq!(f64, 189.92, result.ask_price().unwrap());
assert_eq!(1, result.ask_size().unwrap());
assert_eq!(
chrono::DateTime::from_timestamp_millis(1715990363904).unwrap(),
result.ask_time().unwrap()
);
assert_approx_eq!(f64, 189.9, result.bid_price().unwrap());
assert_eq!(6, result.bid_size().unwrap());
assert_eq!(
chrono::DateTime::from_timestamp_millis(1715990363904).unwrap(),
result.bid_time().unwrap()
);
assert_approx_eq!(f64, 189.84, result.close_price());
assert_approx_eq!(f64, 190.81, result.high_price().unwrap());
assert_approx_eq!(f64, 189.9, result.last_price().unwrap());
assert_eq!(2, result.last_size().unwrap());
assert_approx_eq!(f64, 189.18, result.low_price().unwrap());
assert_approx_eq!(f64, 0.06, result.net_change());
assert_approx_eq!(f64, 189.51, result.open_price().unwrap());
assert_eq!(
chrono::DateTime::from_timestamp_millis(1715990363904).unwrap(),
result.quote_time().unwrap()
);
assert_eq!(
chrono::DateTime::from_timestamp_millis(1715990395834).unwrap(),
result.trade_time()
);
assert_eq!(41282925, result.total_volume().unwrap());
}
}

0 comments on commit e3f77c1

Please sign in to comment.