stock-trek 0.3.0

Stock Trek time-series analysis
Documentation
use crate::{
    market_data::{extract::dec_to_f64, market_quote::MarketQuote, market_tick::MarketTick},
    prelude::TimestampMillis,
};
use std::sync::OnceLock;

#[derive(Debug)]
pub struct MarketTicks {
    ticks: Vec<MarketTick>,
    bids: OnceLock<Vec<(TimestampMillis, f64, f64)>>,
    asks: OnceLock<Vec<(TimestampMillis, f64, f64)>>,
    lasts: OnceLock<Vec<(TimestampMillis, f64, f64)>>,
}

impl MarketTicks {
    pub fn new(ticks: Vec<MarketTick>) -> Self {
        Self {
            ticks,
            bids: OnceLock::new(),
            asks: OnceLock::new(),
            lasts: OnceLock::new(),
        }
    }
    pub fn ticks(&self) -> &Vec<MarketTick> {
        &self.ticks
    }
    pub fn bids(&self) -> &Vec<(TimestampMillis, f64, f64)> {
        self.bids.get_or_init(|| self.values(|tick| tick.bid()))
    }
    pub fn asks(&self) -> &Vec<(TimestampMillis, f64, f64)> {
        self.asks.get_or_init(|| self.values(|tick| tick.ask()))
    }
    pub fn lasts(&self) -> &Vec<(TimestampMillis, f64, f64)> {
        self.lasts.get_or_init(|| self.values(|tick| tick.last()))
    }

    fn values(
        &self,
        to_quote: impl Fn(&MarketTick) -> &MarketQuote,
    ) -> Vec<(TimestampMillis, f64, f64)> {
        self.ticks
            .iter()
            .map(|tick| self.to_tick_tuple(tick, &to_quote))
            .collect()
    }
    fn to_tick_tuple(
        &self,
        tick: &MarketTick,
        to_quote: impl Fn(&MarketTick) -> &MarketQuote,
    ) -> (TimestampMillis, f64, f64) {
        let timestamp = tick.timestamp_millis();
        let quote = to_quote(tick);
        let price = dec_to_f64(quote.price());
        let quantity = dec_to_f64(quote.quantity());
        (timestamp, price, quantity)
    }
}