1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use async_trait::async_trait;
use crate::{
clients::common_traits::{
Candlestick, Level3OrderBook, OrderBook, OrderBookTopK, Ticker, Trade, BBO,
},
common::{command_translator::CommandTranslator, ws_client_internal::WSClientInternal},
WSClient,
};
use super::utils::{BybitMessageHandler, EXCHANGE_NAME};
const WEBSOCKET_URL: &str = "wss://stream.bybit.com/realtime_public";
pub struct BybitLinearSwapWSClient {
client: WSClientInternal<BybitMessageHandler>,
translator: BybitLinearCommandTranslator,
}
impl_new_constructor!(
BybitLinearSwapWSClient,
EXCHANGE_NAME,
WEBSOCKET_URL,
BybitMessageHandler {},
BybitLinearCommandTranslator {}
);
impl_trait!(Trade, BybitLinearSwapWSClient, subscribe_trade, "trade");
#[rustfmt::skip]
impl_trait!(OrderBook, BybitLinearSwapWSClient, subscribe_orderbook, "orderBookL2_25");
#[rustfmt::skip]
impl_trait!(Ticker, BybitLinearSwapWSClient, subscribe_ticker, "instrument_info.100ms");
impl_candlestick!(BybitLinearSwapWSClient);
panic_bbo!(BybitLinearSwapWSClient);
panic_l3_orderbook!(BybitLinearSwapWSClient);
panic_l2_topk!(BybitLinearSwapWSClient);
impl_ws_client_trait!(BybitLinearSwapWSClient);
struct BybitLinearCommandTranslator {}
impl BybitLinearCommandTranslator {
fn to_candlestick_raw_channel(interval: usize) -> String {
let interval_str = match interval {
60 => "1",
180 => "3",
300 => "5",
900 => "15",
1800 => "30",
3600 => "60",
7200 => "120",
14400 => "240",
21600 => "360",
86400 => "D",
604800 => "W",
2592000 => "M",
_ => panic!(
"Bybit LinearSwap has intervals 1min,5min,15min,30min,60min,4hour,1day,1week,1mon"
),
};
format!("candle.{}", interval_str)
}
}
impl CommandTranslator for BybitLinearCommandTranslator {
fn translate_to_commands(&self, subscribe: bool, topics: &[(String, String)]) -> Vec<String> {
vec![super::utils::topics_to_command(topics, subscribe)]
}
fn translate_to_candlestick_commands(
&self,
subscribe: bool,
symbol_interval_list: &[(String, usize)],
) -> Vec<String> {
let topics = symbol_interval_list
.iter()
.map(|(symbol, interval)| {
let channel = Self::to_candlestick_raw_channel(*interval);
(channel, symbol.to_string())
})
.collect::<Vec<(String, String)>>();
self.translate_to_commands(subscribe, &topics)
}
}