alpaca_data/crypto/
convenience.rs1use 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}