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
use crate::{Level3OrderBook, WSClient};
use std::sync::{Arc, Mutex};
use super::super::ws_client_internal::WSClientInternal;
use super::super::{Candlestick, OrderBook, OrderBookSnapshot, Ticker, Trade, BBO};
use super::utils::{
channels_to_commands, fetch_ws_token, on_misc_msg, to_raw_channel, WebsocketToken,
CLIENT_PING_INTERVAL_AND_MSG, EXCHANGE_NAME,
};
use lazy_static::lazy_static;
lazy_static! {
static ref WS_TOKEN: WebsocketToken = fetch_ws_token();
static ref WEBSOCKET_URL: String = format!("{}?token={}", WS_TOKEN.endpoint, WS_TOKEN.token);
}
pub struct KuCoinSwapWSClient<'a> {
client: WSClientInternal<'a>,
}
#[rustfmt::skip]
impl_trait!(Trade, KuCoinSwapWSClient, subscribe_trade, "/contractMarket/execution", to_raw_channel);
#[rustfmt::skip]
impl_trait!(BBO, KuCoinSwapWSClient, subscribe_bbo, "/contractMarket/ticker", to_raw_channel);
#[rustfmt::skip]
impl_trait!(OrderBook, KuCoinSwapWSClient, subscribe_orderbook, "/contractMarket/level2", to_raw_channel);
#[rustfmt::skip]
impl_trait!(OrderBookSnapshot, KuCoinSwapWSClient, subscribe_orderbook_snapshot, "/contractMarket/level2Depth50", to_raw_channel);
#[rustfmt::skip]
impl_trait!(Ticker, KuCoinSwapWSClient, subscribe_ticker, "/contractMarket/snapshot", to_raw_channel);
fn to_candlestick_raw_channel(pair: &str, interval: u32) -> String {
let valid_set: Vec<u32> = vec![
60, 300, 900, 1800, 3600, 7200, 14400, 28800, 43200, 86400, 604800,
];
if !valid_set.contains(&interval) {
let joined = valid_set
.into_iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join(",");
panic!("KuCoin Swap available intervals {}", joined);
}
format!(
r#"{{"id":"crypto-ws-client","type":"subscribe","topic":"/contractMarket/candle:{}_{}","privateChannel":false,"response":true}}"#,
pair,
interval / 60,
)
}
impl_candlestick!(KuCoinSwapWSClient);
impl<'a> Level3OrderBook for KuCoinSwapWSClient<'a> {
fn subscribe_l3_orderbook(&self, symbols: &[String]) {
let raw_channels: Vec<String> = symbols
.iter()
.map(|symbol| to_raw_channel("/contractMarket/level3v2", symbol))
.collect();
self.client.subscribe(&raw_channels);
}
}
define_client!(
KuCoinSwapWSClient,
EXCHANGE_NAME,
WEBSOCKET_URL.as_str(),
channels_to_commands,
on_misc_msg,
Some(CLIENT_PING_INTERVAL_AND_MSG),
None
);