Skip to main content

alpaca_data/crypto/
convenience.rs

1use std::collections::HashMap;
2
3use rust_decimal::Decimal;
4
5use super::{Location, Snapshot};
6
7impl Snapshot {
8    #[must_use]
9    pub fn timestamp(&self) -> Option<&str> {
10        [
11            self.latest_trade
12                .as_ref()
13                .and_then(|trade| trade.t.as_deref()),
14            self.latest_quote
15                .as_ref()
16                .and_then(|quote| quote.t.as_deref()),
17            self.minute_bar.as_ref().and_then(|bar| bar.t.as_deref()),
18            self.daily_bar.as_ref().and_then(|bar| bar.t.as_deref()),
19            self.prev_daily_bar
20                .as_ref()
21                .and_then(|bar| bar.t.as_deref()),
22        ]
23        .into_iter()
24        .flatten()
25        .filter(|value| !value.trim().is_empty())
26        .max()
27    }
28
29    #[must_use]
30    pub fn bid_price(&self) -> Option<Decimal> {
31        self.latest_quote.as_ref().and_then(|quote| quote.bp)
32    }
33
34    #[must_use]
35    pub fn ask_price(&self) -> Option<Decimal> {
36        self.latest_quote.as_ref().and_then(|quote| quote.ap)
37    }
38
39    #[must_use]
40    pub fn last_price(&self) -> Option<Decimal> {
41        self.latest_trade.as_ref().and_then(|trade| trade.p)
42    }
43
44    #[must_use]
45    pub fn mark_price(&self) -> Option<Decimal> {
46        match (self.bid_price(), self.ask_price()) {
47            (Some(bid), Some(ask)) => Some((bid + ask) / Decimal::from(2u8)),
48            (Some(bid), None) => Some(bid),
49            (None, Some(ask)) => Some(ask),
50            (None, None) => None,
51        }
52    }
53
54    #[must_use]
55    pub fn price(&self) -> Option<Decimal> {
56        self.last_price().or_else(|| self.mark_price())
57    }
58}
59
60#[must_use]
61pub fn ordered_snapshots(snapshots: &HashMap<String, Snapshot>) -> Vec<(&str, &Snapshot)> {
62    let mut symbols = snapshots.keys().map(String::as_str).collect::<Vec<_>>();
63    symbols.sort_unstable();
64    symbols
65        .into_iter()
66        .filter_map(|symbol| {
67            snapshots
68                .get_key_value(symbol)
69                .map(|(symbol, snapshot)| (symbol.as_str(), snapshot))
70        })
71        .collect()
72}
73
74#[must_use]
75pub fn preferred_location() -> Location {
76    Location::Us
77}