exc_types/
ticker.rs

1use crate::Str;
2use derive_more::Display;
3use exc_service::{ExchangeError, Request};
4use futures::stream::BoxStream;
5use indicator::{Tick, TickValue, Tickable};
6use rust_decimal::Decimal;
7use serde::{Deserialize, Serialize};
8use time::OffsetDateTime;
9
10/// Ticker Stream.
11pub type TickerStream = BoxStream<'static, Result<Ticker, ExchangeError>>;
12
13/// Subscribe tickers.
14#[derive(Debug, Clone)]
15pub struct SubscribeTickers {
16    /// Instrument.
17    pub instrument: Str,
18}
19
20impl SubscribeTickers {
21    /// Create a new [`SubscribeTickers`] request.
22    pub fn new(inst: impl AsRef<str>) -> Self {
23        Self {
24            instrument: Str::new(inst),
25        }
26    }
27}
28
29impl Request for SubscribeTickers {
30    type Response = TickerStream;
31}
32
33/// Ticker.
34#[derive(Debug, Clone, Copy, Serialize, Deserialize, Display)]
35#[display(
36    fmt = "ts={ts}, last=({last}, {size}), bid=({bid:?}, {bid_size:?}), ask=({ask:?}, {ask_size:?})"
37)]
38pub struct Ticker {
39    /// Timestamp.
40    #[serde(with = "time::serde::rfc3339")]
41    pub ts: OffsetDateTime,
42    /// Last traded price.
43    pub last: Decimal,
44    /// Last traded size.
45    #[serde(default)]
46    pub size: Decimal,
47    /// Last traded side.
48    #[serde(default)]
49    pub buy: Option<bool>,
50    /// Current best bid.
51    #[serde(default)]
52    pub bid: Option<Decimal>,
53    /// The size of current best bid.
54    #[serde(default)]
55    pub bid_size: Option<Decimal>,
56    /// Current best ask.
57    #[serde(default)]
58    pub ask: Option<Decimal>,
59    /// The size of current best ask.
60    #[serde(default)]
61    pub ask_size: Option<Decimal>,
62}
63
64impl Tickable for Ticker {
65    type Value = Self;
66
67    fn tick(&self) -> Tick {
68        Tick::new(self.ts)
69    }
70
71    fn value(&self) -> &Self::Value {
72        self
73    }
74
75    fn into_tick_value(self) -> TickValue<Self::Value> {
76        TickValue::new(self.ts, self)
77    }
78}