barter_data/
event.rs

1use crate::{
2    error::DataError,
3    streams::consumer::MarketStreamResult,
4    subscription::{
5        book::{OrderBookEvent, OrderBookL1},
6        candle::Candle,
7        liquidation::Liquidation,
8        trade::PublicTrade,
9    },
10};
11use barter_instrument::{exchange::ExchangeId, instrument::market_data::MarketDataInstrument};
12use chrono::{DateTime, Utc};
13use derive_more::From;
14use serde::{Deserialize, Serialize};
15
16/// Convenient new type containing a collection of [`MarketEvent<T>`](MarketEvent)s.
17#[derive(Debug)]
18pub struct MarketIter<InstrumentKey, T>(pub Vec<Result<MarketEvent<InstrumentKey, T>, DataError>>);
19
20impl<InstrumentKey, T> FromIterator<Result<MarketEvent<InstrumentKey, T>, DataError>>
21    for MarketIter<InstrumentKey, T>
22{
23    fn from_iter<Iter>(iter: Iter) -> Self
24    where
25        Iter: IntoIterator<Item = Result<MarketEvent<InstrumentKey, T>, DataError>>,
26    {
27        Self(iter.into_iter().collect())
28    }
29}
30
31/// Normalised Barter [`MarketEvent<T>`](Self) wrapping the `T` data variant in metadata.
32///
33/// Note: `T` can be an enum such as the [`DataKind`] if required.
34///
35/// See [`crate::subscription`] for all existing Barter Market event variants.
36///
37/// ### Examples
38/// - [`MarketEvent<PublicTrade>`](PublicTrade)
39/// - [`MarketEvent<OrderBookL1>`](OrderBookL1)
40/// - [`MarketEvent<DataKind>`](DataKind)
41#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize)]
42pub struct MarketEvent<InstrumentKey = MarketDataInstrument, T = DataKind> {
43    pub time_exchange: DateTime<Utc>,
44    pub time_received: DateTime<Utc>,
45    pub exchange: ExchangeId,
46    pub instrument: InstrumentKey,
47    pub kind: T,
48}
49
50impl<InstrumentKey, T> MarketEvent<InstrumentKey, T> {
51    pub fn map_kind<F, O>(self, op: F) -> MarketEvent<InstrumentKey, O>
52    where
53        F: FnOnce(T) -> O,
54    {
55        MarketEvent {
56            time_exchange: self.time_exchange,
57            time_received: self.time_received,
58            exchange: self.exchange,
59            instrument: self.instrument,
60            kind: op(self.kind),
61        }
62    }
63}
64
65impl<InstrumentKey> MarketEvent<InstrumentKey, DataKind> {
66    pub fn as_public_trade(&self) -> Option<MarketEvent<&InstrumentKey, &PublicTrade>> {
67        match &self.kind {
68            DataKind::Trade(public_trade) => Some(self.as_event(public_trade)),
69            _ => None,
70        }
71    }
72
73    pub fn as_order_book_l1(&self) -> Option<MarketEvent<&InstrumentKey, &OrderBookL1>> {
74        match &self.kind {
75            DataKind::OrderBookL1(orderbook) => Some(self.as_event(orderbook)),
76            _ => None,
77        }
78    }
79
80    pub fn as_order_book(&self) -> Option<MarketEvent<&InstrumentKey, &OrderBookEvent>> {
81        match &self.kind {
82            DataKind::OrderBook(orderbook) => Some(self.as_event(orderbook)),
83            _ => None,
84        }
85    }
86
87    pub fn as_candle(&self) -> Option<MarketEvent<&InstrumentKey, &Candle>> {
88        match &self.kind {
89            DataKind::Candle(candle) => Some(self.as_event(candle)),
90            _ => None,
91        }
92    }
93
94    pub fn as_liquidation(&self) -> Option<MarketEvent<&InstrumentKey, &Liquidation>> {
95        match &self.kind {
96            DataKind::Liquidation(liquidation) => Some(self.as_event(liquidation)),
97            _ => None,
98        }
99    }
100
101    fn as_event<'a, K>(&'a self, kind: &'a K) -> MarketEvent<&'a InstrumentKey, &'a K> {
102        MarketEvent {
103            time_exchange: self.time_exchange,
104            time_received: self.time_received,
105            exchange: self.exchange,
106            instrument: &self.instrument,
107            kind,
108        }
109    }
110}
111
112/// Available kinds of normalised Barter [`MarketEvent<T>`](MarketEvent).
113///
114/// ### Notes
115/// - [`Self`] is only used as the [`MarketEvent<DataKind>`](MarketEvent) `Output` when combining
116///   several [`Streams<SubscriptionKind::Event>`](crate::streams::Streams) using the
117///   [`MultiStreamBuilder<Output>`](crate::streams::builder::multi::MultiStreamBuilder), or via
118///   the [`DynamicStreams::select_all`](crate::streams::builder::dynamic::DynamicStreams) method.
119/// - [`Self`] is purposefully not supported in any
120///   [`Subscription`](crate::subscription::Subscription)s directly, it is only used to
121///   make ergonomic [`Streams`](crate::streams::Streams) containing many
122///   [`MarketEvent<T>`](MarketEvent) kinds.
123#[derive(Clone, PartialEq, Debug, Deserialize, Serialize, From)]
124pub enum DataKind {
125    Trade(PublicTrade),
126    OrderBookL1(OrderBookL1),
127    OrderBook(OrderBookEvent),
128    Candle(Candle),
129    Liquidation(Liquidation),
130}
131
132impl DataKind {
133    pub fn kind_name(&self) -> &str {
134        match self {
135            DataKind::Trade(_) => "public_trade",
136            DataKind::OrderBookL1(_) => "l1",
137            DataKind::OrderBook(_) => "l2",
138            DataKind::Candle(_) => "candle",
139            DataKind::Liquidation(_) => "liquidation",
140        }
141    }
142}
143
144impl<InstrumentKey> From<MarketStreamResult<InstrumentKey, PublicTrade>>
145    for MarketStreamResult<InstrumentKey, DataKind>
146{
147    fn from(value: MarketStreamResult<InstrumentKey, PublicTrade>) -> Self {
148        value.map_ok(MarketEvent::from)
149    }
150}
151
152impl<InstrumentKey> From<MarketEvent<InstrumentKey, PublicTrade>>
153    for MarketEvent<InstrumentKey, DataKind>
154{
155    fn from(value: MarketEvent<InstrumentKey, PublicTrade>) -> Self {
156        value.map_kind(PublicTrade::into)
157    }
158}
159
160impl<InstrumentKey> From<MarketStreamResult<InstrumentKey, OrderBookL1>>
161    for MarketStreamResult<InstrumentKey, DataKind>
162{
163    fn from(value: MarketStreamResult<InstrumentKey, OrderBookL1>) -> Self {
164        value.map_ok(MarketEvent::from)
165    }
166}
167
168impl<InstrumentKey> From<MarketEvent<InstrumentKey, OrderBookL1>>
169    for MarketEvent<InstrumentKey, DataKind>
170{
171    fn from(value: MarketEvent<InstrumentKey, OrderBookL1>) -> Self {
172        value.map_kind(OrderBookL1::into)
173    }
174}
175
176impl<InstrumentKey> From<MarketStreamResult<InstrumentKey, OrderBookEvent>>
177    for MarketStreamResult<InstrumentKey, DataKind>
178{
179    fn from(value: MarketStreamResult<InstrumentKey, OrderBookEvent>) -> Self {
180        value.map_ok(MarketEvent::from)
181    }
182}
183
184impl<InstrumentKey> From<MarketEvent<InstrumentKey, OrderBookEvent>>
185    for MarketEvent<InstrumentKey, DataKind>
186{
187    fn from(value: MarketEvent<InstrumentKey, OrderBookEvent>) -> Self {
188        value.map_kind(OrderBookEvent::into)
189    }
190}
191
192impl<InstrumentKey> From<MarketStreamResult<InstrumentKey, Candle>>
193    for MarketStreamResult<InstrumentKey, DataKind>
194{
195    fn from(value: MarketStreamResult<InstrumentKey, Candle>) -> Self {
196        value.map_ok(MarketEvent::from)
197    }
198}
199
200impl<InstrumentKey> From<MarketEvent<InstrumentKey, Candle>>
201    for MarketEvent<InstrumentKey, DataKind>
202{
203    fn from(value: MarketEvent<InstrumentKey, Candle>) -> Self {
204        value.map_kind(Candle::into)
205    }
206}
207
208impl<InstrumentKey> From<MarketStreamResult<InstrumentKey, Liquidation>>
209    for MarketStreamResult<InstrumentKey, DataKind>
210{
211    fn from(value: MarketStreamResult<InstrumentKey, Liquidation>) -> Self {
212        value.map_ok(MarketEvent::from)
213    }
214}
215
216impl<InstrumentKey> From<MarketEvent<InstrumentKey, Liquidation>>
217    for MarketEvent<InstrumentKey, DataKind>
218{
219    fn from(value: MarketEvent<InstrumentKey, Liquidation>) -> Self {
220        value.map_kind(Liquidation::into)
221    }
222}