Skip to main content

barter_data/exchange/bitmex/
mod.rs

1use crate::{
2    ExchangeWsStream, NoInitialSnapshots,
3    exchange::{
4        Connector, StreamSelector,
5        bitmex::{
6            channel::BitmexChannel, market::BitmexMarket, subscription::BitmexSubResponse,
7            trade::BitmexTrade,
8        },
9        subscription::ExchangeSub,
10    },
11    instrument::InstrumentData,
12    subscriber::{WebSocketSubscriber, validator::WebSocketSubValidator},
13    subscription::{Map, trade::PublicTrades},
14    transformer::stateless::StatelessTransformer,
15};
16use barter_instrument::exchange::ExchangeId;
17use barter_integration::protocol::websocket::{WebSocketSerdeParser, WsMessage};
18use derive_more::Display;
19use serde::de::{Error, Unexpected};
20use std::fmt::Debug;
21use url::Url;
22
23/// Defines the type that translates a Barter [`Subscription`](crate::subscription::Subscription)
24/// into an exchange [`Connector`] specific channel used for generating [`Connector::requests`].
25pub mod channel;
26
27/// Defines the type that translates a Barter [`Subscription`](crate::subscription::Subscription)
28/// into an exchange [`Connector`] specific market used for generating [`Connector::requests`].
29pub mod market;
30
31/// Generic [`BitmexMessage<T>`](message::BitmexMessage)
32pub mod message;
33
34/// [`Subscription`](crate::subscription::Subscription) response type and response
35/// [`Validator`](barter_integration::Validator) for [`Bitmex`].
36pub mod subscription;
37
38/// Public trade types for [`Bitmex`].
39pub mod trade;
40
41/// Convenient type alias for a Bitmex [`ExchangeWsStream`] using [`WebSocketSerdeParser`](barter_integration::protocol::websocket::WebSocketSerdeParser).
42pub type BitmexWsStream<Transformer> = ExchangeWsStream<WebSocketSerdeParser, Transformer>;
43
44/// [`Bitmex`] server base url.
45///
46/// See docs: <https://www.bitmex.com/app/wsAPI>
47pub const BASE_URL_BITMEX: &str = "wss://ws.bitmex.com/realtime";
48
49#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Display)]
50pub struct Bitmex;
51
52impl Connector for Bitmex {
53    const ID: ExchangeId = ExchangeId::Bitmex;
54    type Channel = BitmexChannel;
55    type Market = BitmexMarket;
56    type Subscriber = WebSocketSubscriber;
57    type SubValidator = WebSocketSubValidator;
58    type SubResponse = BitmexSubResponse;
59
60    fn url() -> Result<Url, url::ParseError> {
61        Url::parse(BASE_URL_BITMEX)
62    }
63
64    fn requests(exchange_subs: Vec<ExchangeSub<Self::Channel, Self::Market>>) -> Vec<WsMessage> {
65        let stream_names = exchange_subs
66            .into_iter()
67            .map(|sub| format!("{}:{}", sub.channel.as_ref(), sub.market.as_ref(),))
68            .collect::<Vec<String>>();
69
70        vec![WsMessage::text(
71            serde_json::json!({
72                "op": "subscribe",
73                "args": stream_names
74            })
75            .to_string(),
76        )]
77    }
78
79    fn expected_responses<InstrumentKey>(_: &Map<InstrumentKey>) -> usize {
80        1
81    }
82}
83
84impl<Instrument> StreamSelector<Instrument, PublicTrades> for Bitmex
85where
86    Instrument: InstrumentData,
87{
88    type SnapFetcher = NoInitialSnapshots;
89    type Stream =
90        BitmexWsStream<StatelessTransformer<Self, Instrument::Key, PublicTrades, BitmexTrade>>;
91}
92
93impl<'de> serde::Deserialize<'de> for Bitmex {
94    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
95    where
96        D: serde::de::Deserializer<'de>,
97    {
98        let input = <&str as serde::Deserialize>::deserialize(deserializer)?;
99        if input == Self::ID.as_str() {
100            Ok(Self)
101        } else {
102            Err(Error::invalid_value(
103                Unexpected::Str(input),
104                &Self::ID.as_str(),
105            ))
106        }
107    }
108}
109
110impl serde::Serialize for Bitmex {
111    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
112    where
113        S: serde::ser::Serializer,
114    {
115        serializer.serialize_str(Self::ID.as_str())
116    }
117}