exchange_test.rs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. use std::collections::{BTreeMap};
  2. use std::{env};
  3. use std::fs::File;
  4. use toml::from_str;
  5. use std::io::{Error, Read};
  6. use std::sync::Arc;
  7. use std::sync::atomic::AtomicBool;
  8. use std::time::Duration;
  9. use rust_decimal_macros::dec;
  10. use serde::Deserialize;
  11. use tokio::sync::mpsc::{channel, Receiver, Sender};
  12. use tokio::try_join;
  13. use tracing::{error, trace};
  14. // use exchanges::bitget_spot_ws::{BitgetSpotWs, BitgetSubscribeType, BitgetWsType};
  15. use exchanges::kucoin_spot_ws::{KucoinSpotWs, KucoinSubscribeType, KucoinWsType};
  16. // use exchanges::binance_spot_ws::{BinanceSpotSubscribeType, BinanceSpotWs, BinanceSpotWsType};
  17. // use exchanges::okx_swap_ws::{OkxSubscribeType, OkxSwapWs, OkxWsType};
  18. // use exchanges::kucoin_swap_ws::{KucoinSubscribeType, KucoinSwapWs, KucoinWsType};
  19. use exchanges::response_base::ResponseData;
  20. use standard::exchange::{Exchange, ExchangeEnum};
  21. // use standard::{binance_handle, Order, Platform, utils};
  22. // use standard::{okx_handle, Order, Platform, utils};
  23. // use standard::{kucoin_handle, Order, Platform, utils};
  24. use standard::{kucoin_spot_handle, Order, Platform, utils};
  25. // use standard::{bitget_spot_handle, Order, Platform, utils};
  26. #[derive(Debug, Deserialize, Clone)]
  27. pub struct AccountInfo {
  28. pub gate_access_key: String,
  29. pub gate_secret_key: String,
  30. pub binance_access_key: String,
  31. pub binance_secret_key: String,
  32. pub kucoin_access_key: String,
  33. pub kucoin_secret_key: String,
  34. pub kucoin_pass: String,
  35. pub okx_access_key: String,
  36. pub okx_secret_key: String,
  37. pub okx_pass: String,
  38. pub bitget_access_key: String,
  39. pub bitget_secret_key: String,
  40. pub bitget_pass: String,
  41. }
  42. impl AccountInfo {
  43. pub fn new() -> AccountInfo {
  44. AccountInfo {
  45. gate_access_key: "".to_string(),
  46. gate_secret_key: "".to_string(),
  47. binance_access_key: "".to_string(),
  48. binance_secret_key: "".to_string(),
  49. kucoin_access_key: "".to_string(),
  50. kucoin_secret_key: "".to_string(),
  51. kucoin_pass: "".to_string(),
  52. okx_access_key: "".to_string(),
  53. okx_secret_key: "".to_string(),
  54. okx_pass: "".to_string(),
  55. bitget_access_key: "".to_string(),
  56. bitget_secret_key: "".to_string(),
  57. bitget_pass: "".to_string(),
  58. }
  59. }
  60. }
  61. // 获取文件内容
  62. pub fn get_account_info(file_path: &str) -> AccountInfo {
  63. let file = File::open(file_path);
  64. let mut contents = String::new();
  65. let result = match file {
  66. Ok(mut value) => {
  67. value.read_to_string(&mut contents).unwrap_or_default();
  68. from_str(&contents).unwrap_or(AccountInfo::new())
  69. }
  70. Err(_) => {
  71. trace!("没有获取到账号配置文件!");
  72. AccountInfo::new()
  73. }
  74. };
  75. result
  76. }
  77. // 创建实体
  78. #[allow(dead_code)]
  79. pub async fn test_new_exchange(exchange: ExchangeEnum, symbol: &str) -> Box<dyn Platform> {
  80. utils::proxy_handle();
  81. let (order_sender, _order_receiver): (Sender<Order>, Receiver<Order>) = channel(1024);
  82. let (error_sender, _error_receiver): (Sender<Error>, Receiver<Error>) = channel(1024);
  83. let account_info = get_account_info("config.toml");
  84. match exchange {
  85. ExchangeEnum::BinanceSwap => {
  86. let mut params: BTreeMap<String, String> = BTreeMap::new();
  87. let access_key = account_info.binance_access_key;
  88. let secret_key = account_info.binance_secret_key;
  89. params.insert("access_key".to_string(), access_key);
  90. params.insert("secret_key".to_string(), secret_key);
  91. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  92. }
  93. ExchangeEnum::BinanceSpot => {
  94. let mut params: BTreeMap<String, String> = BTreeMap::new();
  95. let access_key = account_info.binance_access_key;
  96. let secret_key = account_info.binance_secret_key;
  97. params.insert("access_key".to_string(), access_key);
  98. params.insert("secret_key".to_string(), secret_key);
  99. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  100. }
  101. ExchangeEnum::GateSwap => {
  102. let mut params: BTreeMap<String, String> = BTreeMap::new();
  103. let access_key = account_info.gate_access_key;
  104. let secret_key = account_info.gate_secret_key;
  105. params.insert("access_key".to_string(), access_key);
  106. params.insert("secret_key".to_string(), secret_key);
  107. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  108. }
  109. ExchangeEnum::GateSpot => {
  110. let mut params: BTreeMap<String, String> = BTreeMap::new();
  111. let access_key = account_info.gate_access_key;
  112. let secret_key = account_info.gate_secret_key;
  113. params.insert("access_key".to_string(), access_key);
  114. params.insert("secret_key".to_string(), secret_key);
  115. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  116. }
  117. ExchangeEnum::KucoinSwap => {
  118. let mut params: BTreeMap<String, String> = BTreeMap::new();
  119. let access_key = account_info.kucoin_access_key;
  120. let secret_key = account_info.kucoin_secret_key;
  121. let pass_key = account_info.kucoin_pass;
  122. params.insert("access_key".to_string(), access_key);
  123. params.insert("secret_key".to_string(), secret_key);
  124. params.insert("pass_key".to_string(), pass_key);
  125. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  126. }
  127. ExchangeEnum::KucoinSpot => {
  128. let mut params: BTreeMap<String, String> = BTreeMap::new();
  129. let access_key = account_info.kucoin_access_key;
  130. let secret_key = account_info.kucoin_secret_key;
  131. let pass_key = account_info.kucoin_pass;
  132. params.insert("access_key".to_string(), access_key);
  133. params.insert("secret_key".to_string(), secret_key);
  134. params.insert("pass_key".to_string(), pass_key);
  135. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  136. }
  137. ExchangeEnum::OkxSwap => {
  138. let mut params: BTreeMap<String, String> = BTreeMap::new();
  139. let access_key = account_info.okx_access_key;
  140. let secret_key = account_info.okx_secret_key;
  141. let pass_key = account_info.okx_pass;
  142. params.insert("access_key".to_string(), access_key);
  143. params.insert("secret_key".to_string(), secret_key);
  144. params.insert("pass_key".to_string(), pass_key);
  145. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  146. }
  147. ExchangeEnum::BitgetSpot => {
  148. let mut params: BTreeMap<String, String> = BTreeMap::new();
  149. let access_key = account_info.bitget_access_key;
  150. let secret_key = account_info.bitget_secret_key;
  151. let pass_key = account_info.bitget_pass;
  152. params.insert("access_key".to_string(), access_key);
  153. params.insert("secret_key".to_string(), secret_key);
  154. params.insert("pass_key".to_string(), pass_key);
  155. Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
  156. }
  157. }
  158. }
  159. #[allow(dead_code)]
  160. pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subscriber_type: T, mold: &str) where Vec<KucoinSubscribeType>: From<T> {
  161. utils::proxy_handle();
  162. match exchange {
  163. ExchangeEnum::BinanceSpot => {
  164. // let symbol_format = utils::format_symbol(symbol.to_string(), "").to_uppercase();
  165. // trace!(symbol_format);
  166. // let name = format!("binance_usdt_swap@{}", symbol.to_string().to_lowercase());
  167. // let bool_v1 = Arc::new(AtomicBool::new(true));
  168. //
  169. // let (res_sender, mut res_receiver): (Sender<ResponseData>, Receiver<ResponseData>) = channel(1024);
  170. // let mut params: BTreeMap<String, String> = BTreeMap::new();
  171. // let access_key = env::var("binance_access_key").unwrap_or("".to_string());
  172. // let secret_key = env::var("binance_secret_key").unwrap_or("".to_string());
  173. // params.insert("access_key".to_string(), access_key);
  174. // params.insert("secret_key".to_string(), secret_key);
  175. // let mut exchange_wss;
  176. // exchange_wss = BinanceSpotWs::new_label(name, false, params, BinanceSpotWsType::PublicAndPrivate, res_sender);
  177. // exchange_wss.set_subscribe(subscriber_type.into());
  178. //
  179. // let t1 = tokio::spawn(async move {
  180. // exchange_wss.custom_subscribe(bool_v1, vec![symbol_format]).await;
  181. // });
  182. // let mold_arc = Arc::new(mold.to_string());
  183. // let t2 = tokio::spawn(async move {
  184. // let mold_clone = Arc::clone(&mold_arc);
  185. // loop {
  186. // tokio::time::sleep(Duration::from_millis(1)).await;
  187. // if let Ok(received) = res_receiver.try_recv() {
  188. // match mold_clone.as_str() {
  189. // "depth" => {
  190. // if received.data != "" {
  191. // let result = binance_handle::handle_special_depth(received);
  192. // trace!(?result)
  193. // }
  194. // }
  195. // "ticker" => {
  196. // if received.data != "" {
  197. // let result = binance_handle::handle_special_ticker(received);
  198. // trace!(?result)
  199. // }
  200. // }
  201. // _ => {
  202. // error!("没有该命令!mode={}", mold_clone);
  203. // panic!("没有该命令!mode={}", mold_clone)
  204. // }
  205. // }
  206. // }
  207. // }
  208. // });
  209. // try_join!(t1, t2).unwrap();
  210. error!("该交易所不支持!test_new_exchange_wss:{:?}",exchange);
  211. panic!("该交易所不支持!test_new_exchange_wss:{:?}", exchange)
  212. }
  213. ExchangeEnum::BinanceSwap => {
  214. error!("该交易所不支持!test_new_exchange_wss:{:?}",exchange);
  215. panic!("该交易所不支持!test_new_exchange_wss:{:?}", exchange)
  216. }
  217. ExchangeEnum::GateSwap => {
  218. error!("该交易所不支持!test_new_exchange_wss:{:?}",exchange);
  219. panic!("该交易所不支持!test_new_exchange_wss:{:?}", exchange)
  220. }
  221. ExchangeEnum::KucoinSwap => {
  222. // let symbol_format = format!("{}M", utils::format_symbol(symbol.to_string(), ""));
  223. // let symbol_back = utils::format_symbol(symbol.to_string(), "_");
  224. // let name = format!("kucoin_usdt_swap@{}", symbol.to_string().to_lowercase());
  225. // let bool_v1 = Arc::new(AtomicBool::new(true));
  226. //
  227. // let (res_sender, mut res_receiver): (Sender<ResponseData>, Receiver<ResponseData>) = channel(1024);
  228. // let mut params: BTreeMap<String, String> = BTreeMap::new();
  229. // let access_key = env::var("kucoin_access_key").unwrap_or("".to_string());
  230. // let secret_key = env::var("kucoin_secret_key").unwrap_or("".to_string());
  231. // let pass_key = env::var("kucoin_pass_key").unwrap_or("".to_string());
  232. // params.insert("access_key".to_string(), access_key);
  233. // params.insert("secret_key".to_string(), secret_key);
  234. // params.insert("pass_key".to_string(), pass_key);
  235. // let mut exchange_wss;
  236. // if ["depth", "ticker"].contains(&mold) {
  237. // exchange_wss = KucoinSwapWs::new_label(name, false, params, KucoinWsType::Public, res_sender).await
  238. // } else {
  239. // exchange_wss = KucoinSwapWs::new_label(name, false, params, KucoinWsType::Private, res_sender).await
  240. // }
  241. // exchange_wss.set_subscribe(subscriber_type.into());
  242. //
  243. // let t1 = tokio::spawn(async move {
  244. // exchange_wss.custom_subscribe(bool_v1, vec![symbol_format]).await;
  245. // });
  246. // let mold_arc = Arc::new(mold.to_string());
  247. // let t2 = tokio::spawn(async move {
  248. // let mold_clone = Arc::clone(&mold_arc);
  249. // loop {
  250. // tokio::time::sleep(Duration::from_millis(1)).await;
  251. // if let Ok(received) = res_receiver.try_recv() {
  252. // match mold_clone.as_str() {
  253. // "depth" => {
  254. // let result = kucoin_handle::handle_special_depth(received);
  255. // trace!(?result)
  256. // }
  257. // "ticker" => {
  258. // let result = kucoin_handle::handle_special_ticker(received);
  259. // trace!(?result)
  260. // }
  261. // "account" => {
  262. // trace!(?received);
  263. // let result = kucoin_handle::handle_account_info(received, symbol_back.clone());
  264. // trace!(?result)
  265. // }
  266. // "position" => {
  267. // trace!(?received);
  268. // let result = kucoin_handle::handle_position(received, dec!(1));
  269. // trace!(?result)
  270. // }
  271. // "orders" => {
  272. // trace!(?received);
  273. // let result = kucoin_handle::handle_order(received, dec!(0.001));
  274. // trace!(?result)
  275. // }
  276. // _ => {
  277. // error!("没有该命令!mode={}", mold_clone);
  278. // panic!("没有该命令!mode={}", mold_clone)
  279. // }
  280. // }
  281. // }
  282. // }
  283. // });
  284. // try_join!(t1, t2).unwrap();
  285. }
  286. ExchangeEnum::KucoinSpot => {
  287. let symbol_format = utils::format_symbol(symbol.to_string(), "-").to_uppercase();
  288. let symbol_back = utils::format_symbol(symbol.to_string(), "_");
  289. trace!(symbol_format);
  290. let name = format!("kucoin_usdt_spot@{}", symbol.to_string().to_lowercase());
  291. let bool_v1 = Arc::new(AtomicBool::new(true));
  292. let (res_sender, mut res_receiver): (Sender<ResponseData>, Receiver<ResponseData>) = channel(1024);
  293. let mut params: BTreeMap<String, String> = BTreeMap::new();
  294. let access_key = env::var("kucoin_access_key").unwrap_or("".to_string());
  295. let secret_key = env::var("kucoin_secret_key").unwrap_or("".to_string());
  296. let pass_key = env::var("kucoin_pass_key").unwrap_or("".to_string());
  297. params.insert("access_key".to_string(), access_key);
  298. params.insert("secret_key".to_string(), secret_key);
  299. params.insert("pass_key".to_string(), pass_key);
  300. let mut exchange_wss = if ["depth", "ticker"].contains(&mold) {
  301. KucoinSpotWs::new_label(name, false, params, KucoinWsType::Public, res_sender).await
  302. } else {
  303. KucoinSpotWs::new_label(name, false, params, KucoinWsType::Private, res_sender).await
  304. };
  305. exchange_wss.set_subscribe(subscriber_type.into());
  306. let t1 = tokio::spawn(async move {
  307. exchange_wss.custom_subscribe(bool_v1, vec![symbol_format]).await;
  308. });
  309. let mold_arc = Arc::new(mold.to_string());
  310. let t2 = tokio::spawn(async move {
  311. let mold_clone = Arc::clone(&mold_arc);
  312. loop {
  313. tokio::time::sleep(Duration::from_millis(1)).await;
  314. if let Ok(received) = res_receiver.try_recv() {
  315. trace!(?received);
  316. match mold_clone.as_str() {
  317. "depth" => {
  318. if received.data != "" {
  319. let result = kucoin_spot_handle::handle_special_depth(received);
  320. trace!(?result)
  321. }
  322. }
  323. "ticker" => {
  324. if received.data != "" {
  325. let result = kucoin_spot_handle::handle_special_ticker(received);
  326. trace!(?result)
  327. }
  328. }
  329. "account" => {
  330. if received.data != "" {
  331. let result = kucoin_spot_handle::handle_account_info(received, symbol_back.clone());
  332. trace!(?result)
  333. }
  334. }
  335. "orders" => {
  336. if received.data != "" {
  337. let result = kucoin_spot_handle::handle_order(received, dec!(1));
  338. trace!(?result)
  339. }
  340. }
  341. _ => {
  342. error!("没有该命令!mode={}", mold_clone);
  343. panic!("没有该命令!mode={}", mold_clone)
  344. }
  345. }
  346. }
  347. }
  348. });
  349. try_join!(t1, t2).unwrap();
  350. }
  351. ExchangeEnum::BitgetSpot => {
  352. // let symbol_format = utils::format_symbol(symbol.to_string(), "-").to_uppercase();
  353. // let symbol_back = utils::format_symbol(symbol.to_string(), "_");
  354. // trace!(symbol_format);
  355. // let name = format!("bitget_usdt_spot@{}", symbol.to_string().to_lowercase());
  356. // let bool_v1 = Arc::new(AtomicBool::new(true));
  357. //
  358. // let (res_sender, mut res_receiver): (Sender<ResponseData>, Receiver<ResponseData>) = channel(1024);
  359. // let mut params: BTreeMap<String, String> = BTreeMap::new();
  360. // let access_key = env::var("bitget_access_key").unwrap_or("".to_string());
  361. // let secret_key = env::var("bitget_secret_key").unwrap_or("".to_string());
  362. // let pass_key = env::var("bitget_pass_key").unwrap_or("".to_string());
  363. // params.insert("access_key".to_string(), access_key);
  364. // params.insert("secret_key".to_string(), secret_key);
  365. // params.insert("pass_key".to_string(), pass_key);
  366. //
  367. // let mut exchange_wss = if ["depth", "ticker"].contains(&mold) {
  368. // BitgetSpotWs::new_label(name, false, params, BitgetWsType::Public, res_sender)
  369. // } else {
  370. // BitgetSpotWs::new_label(name, false, params, BitgetWsType::Private, res_sender)
  371. // };
  372. //
  373. // exchange_wss.set_subscribe(subscriber_type.into());
  374. //
  375. // let t1 = tokio::spawn(async move {
  376. // exchange_wss.custom_subscribe(bool_v1, vec![symbol_format]).await;
  377. // });
  378. // let mold_arc = Arc::new(mold.to_string());
  379. // let t2 = tokio::spawn(async move {
  380. // let mold_clone = Arc::clone(&mold_arc);
  381. // loop {
  382. // tokio::time::sleep(Duration::from_millis(1)).await;
  383. // if let Ok(received) = res_receiver.try_recv() {
  384. // match mold_clone.as_str() {
  385. // "depth" => {
  386. // if received.data != "" {
  387. // let result = bitget_spot_handle::handle_special_depth(received);
  388. // trace!(?result)
  389. // }
  390. // }
  391. // "ticker" => {
  392. // if received.data != "" {
  393. // let result = bitget_spot_handle::handle_special_ticker(received);
  394. // trace!(?result)
  395. // }
  396. // }
  397. // "account" => {
  398. // if received.data != "" {
  399. // let result = bitget_spot_handle::handle_account_info(received, symbol_back.clone());
  400. // trace!(?result)
  401. // }
  402. // }
  403. // "orders" => {
  404. // if received.data != "" {
  405. // let result = bitget_spot_handle::handle_order(received, dec!(1));
  406. // trace!(?result)
  407. // }
  408. // }
  409. // _ => {
  410. // error!("没有该命令!mode={}", mold_clone);
  411. // panic!("没有该命令!mode={}", mold_clone)
  412. // }
  413. // }
  414. // }
  415. // }
  416. // });
  417. // try_join!(t1, t2).unwrap();
  418. }
  419. ExchangeEnum::OkxSwap => {
  420. // let symbol_format = utils::format_symbol(symbol.to_string(), "-").to_uppercase();
  421. // let symbol_back = utils::format_symbol(symbol.to_string(), "_");
  422. // trace!(symbol_format);
  423. // let name = format!("okx_usdt_swap@{}", symbol.to_string().to_lowercase());
  424. // let bool_v1 = Arc::new(AtomicBool::new(true));
  425. //
  426. // let (res_sender, mut res_receiver): (Sender<ResponseData>, Receiver<ResponseData>) = channel(1024);
  427. // let mut params: BTreeMap<String, String> = BTreeMap::new();
  428. // let access_key = env::var("okx_access_key").unwrap_or("".to_string());
  429. // let secret_key = env::var("okx_secret_key").unwrap_or("".to_string());
  430. // let passphrase = env::var("okx_passphrase").unwrap_or("".to_string());
  431. // params.insert("access_key".to_string(), access_key);
  432. // params.insert("secret_key".to_string(), secret_key);
  433. // params.insert("pass_key".to_string(), passphrase);
  434. //
  435. // let mut exchange_wss = if ["depth", "ticker"].contains(&mold) {
  436. // OkxSwapWs::new_label(name, false, params, OkxWsType::Public, res_sender)
  437. // } else if ["account", "orders", "position"].contains(&mold) {
  438. // OkxSwapWs::new_label(name, false, params, OkxWsType::Private, res_sender)
  439. // } else {
  440. // OkxSwapWs::new_label(name, false, params, OkxWsType::Business, res_sender)
  441. // };
  442. //
  443. // exchange_wss.set_subscribe(subscriber_type.into());
  444. //
  445. // let t1 = tokio::spawn(async move {
  446. // exchange_wss.custom_subscribe(bool_v1, vec![symbol_format]).await;
  447. // });
  448. // let mold_arc = Arc::new(mold.to_string());
  449. // let t2 = tokio::spawn(async move {
  450. // let mold_clone = Arc::clone(&mold_arc);
  451. // loop {
  452. // tokio::time::sleep(Duration::from_millis(1)).await;
  453. // if let Ok(received) = res_receiver.try_recv() {
  454. // match mold_clone.as_str() {
  455. // "depth" => {
  456. // if received.data != "" {
  457. // let result = okx_handle::handle_special_depth(received);
  458. // trace!(?result)
  459. // }
  460. // }
  461. // "ticker" => {
  462. // if received.data != "" {
  463. // let result = okx_handle::handle_special_ticker(received);
  464. // trace!(?result)
  465. // }
  466. // }
  467. // "account" => {
  468. // if received.data != "" {
  469. // let result = okx_handle::handle_account_info(received, symbol_back.clone());
  470. // trace!(?result)
  471. // }
  472. // }
  473. // "position" => {
  474. // if received.data != "" {
  475. // let result = okx_handle::handle_position(received, dec!(10));
  476. // trace!(?result)
  477. // }
  478. // }
  479. // "orders" => {
  480. // if received.data != "" {
  481. // let result = okx_handle::handle_order(received, dec!(10));
  482. // trace!(?result)
  483. // }
  484. // }
  485. // _ => {
  486. // error!("没有该命令!mode={}", mold_clone);
  487. // panic!("没有该命令!mode={}", mold_clone)
  488. // }
  489. // }
  490. // }
  491. // }
  492. // });
  493. // try_join!(t1, t2).unwrap();
  494. }
  495. _ => {
  496. error!("该交易所不支持!test_new_exchange_wss:{:?}",exchange);
  497. panic!("该交易所不支持!test_new_exchange_wss:{:?}", exchange)
  498. }
  499. }
  500. }