barter_data/exchange/bitmex/
mod.rs1use 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
23pub mod channel;
26
27pub mod market;
30
31pub mod message;
33
34pub mod subscription;
37
38pub mod trade;
40
41pub type BitmexWsStream<Transformer> = ExchangeWsStream<WebSocketSerdeParser, Transformer>;
43
44pub 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}