kucoin_swap.rs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. // use std::collections::{BTreeMap};
  2. // use std::io::{Error, ErrorKind};
  3. // use std::str::FromStr;
  4. // use tokio::sync::mpsc::Sender;
  5. // use async_trait::async_trait;
  6. // use futures::stream::FuturesUnordered;
  7. // use futures::TryStreamExt;
  8. // use rust_decimal::Decimal;
  9. // use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
  10. // use rust_decimal_macros::dec;
  11. // use serde_json::{json, Value};
  12. // use tokio::time::Instant;
  13. // use tracing::{error, info};
  14. // use exchanges::kucoin_swap_rest::KucoinSwapRest;
  15. // use global::trace_stack::TraceStack;
  16. // use crate::exchange::ExchangeEnum;
  17. // use crate::{Account, kucoin_handle, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
  18. //
  19. // #[allow(dead_code)]
  20. // #[derive(Clone)]
  21. // pub struct KucoinSwap {
  22. // exchange: ExchangeEnum,
  23. // symbol: String,
  24. // is_colo: bool,
  25. // params: BTreeMap<String, String>,
  26. // request: KucoinSwapRest,
  27. // market: Market,
  28. // order_sender: Sender<Order>,
  29. // error_sender: Sender<Error>,
  30. // }
  31. //
  32. // impl KucoinSwap {
  33. // pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> KucoinSwap {
  34. // let market = Market::new();
  35. // let mut kucoin_swap = KucoinSwap {
  36. // exchange: ExchangeEnum::KucoinSwap,
  37. // symbol: symbol.to_uppercase(),
  38. // is_colo,
  39. // params: params.clone(),
  40. // request: KucoinSwapRest::new(is_colo, params.clone()),
  41. // market,
  42. // order_sender,
  43. // error_sender,
  44. // };
  45. // kucoin_swap.market = KucoinSwap::get_market(&mut kucoin_swap).await.unwrap_or(kucoin_swap.market);
  46. //
  47. // // 开启自动追加保证金
  48. // let append_rst = kucoin_swap.set_auto_deposit_status(true).await;
  49. //
  50. // info!("设置自动追加保证金:{:?}", append_rst.unwrap());
  51. //
  52. // return kucoin_swap;
  53. // }
  54. // }
  55. //
  56. // #[async_trait]
  57. // impl Platform for KucoinSwap {
  58. // // 克隆方法
  59. // fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
  60. // fn get_self_exchange(&self) -> ExchangeEnum {
  61. // ExchangeEnum::KucoinSwap
  62. // }
  63. // // 获取交易对
  64. // fn get_self_symbol(&self) -> String { self.symbol.clone() }
  65. // // 获取是否使用高速通道
  66. // fn get_self_is_colo(&self) -> bool {
  67. // self.is_colo
  68. // }
  69. // // 获取params信息
  70. // fn get_self_params(&self) -> BTreeMap<String, String> {
  71. // self.params.clone()
  72. // }
  73. // // 获取market信息
  74. // fn get_self_market(&self) -> Market { self.market.clone() }
  75. // // 获取请求时间
  76. // fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
  77. // // 获取请求平均时间
  78. // fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
  79. // // 获取请求最大时间
  80. // fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
  81. // // 获取服务器时间
  82. // async fn get_server_time(&mut self) -> Result<String, Error> {
  83. // let res_data = self.request.get_server_time().await;
  84. // if res_data.code == 200 {
  85. // Ok(res_data.data.to_string())
  86. // } else {
  87. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  88. // }
  89. // }
  90. // // 获取账号信息
  91. // async fn get_account(&mut self) -> Result<Account, Error> {
  92. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  93. // let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
  94. // let res_data = self.request.get_account(symbol_array[1].to_string()).await;
  95. // if res_data.code == 200 {
  96. // let res_data_json = res_data.data;
  97. //
  98. // let balance = Decimal::from_f64(res_data_json["marginBalance"].as_f64().unwrap()).unwrap();
  99. // let available_balance = Decimal::from_f64(res_data_json["availableBalance"].as_f64().unwrap()).unwrap();
  100. // let frozen_balance = balance - available_balance;
  101. // let result = Account {
  102. // coin: symbol_array[1].to_string(),
  103. // balance,
  104. // available_balance,
  105. // frozen_balance,
  106. // stocks: Decimal::ZERO,
  107. // available_stocks: Decimal::ZERO,
  108. // frozen_stocks: Decimal::ZERO,
  109. // };
  110. // Ok(result)
  111. // } else {
  112. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  113. // }
  114. // }
  115. //
  116. // async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
  117. // Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
  118. // }
  119. //
  120. // async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
  121. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  122. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  123. // let ct_val = self.market.ct_val;
  124. // let res_data = self.request.get_position(symbol_format).await;
  125. // if res_data.code == 200 {
  126. // let result = kucoin_handle::format_position_item(&res_data.data, &ct_val);
  127. // Ok(vec![result])
  128. // } else {
  129. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  130. // }
  131. // }
  132. //
  133. // async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
  134. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  135. // let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
  136. // let res_data = self.request.get_positions(symbol_array[1].to_string()).await;
  137. // if res_data.code == 200 {
  138. // info!("{}", res_data.data.to_string());
  139. // let res_data_json = res_data.data.as_array().unwrap();
  140. // let mut result = Vec::new();
  141. // for item in res_data_json.iter() {
  142. // result.push(kucoin_handle::format_position_item(item, &Decimal::ONE))
  143. // }
  144. // Ok(result)
  145. // } else {
  146. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  147. // }
  148. // }
  149. //
  150. // async fn get_ticker(&mut self) -> Result<Ticker, Error> {
  151. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  152. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  153. // let res_data = self.request.get_ticker(symbol_format).await;
  154. // if res_data.code == 200 {
  155. // let res_data_json = res_data.data;
  156. // let ticker_info = res_data_json;
  157. // let time = (Decimal::from_str(&*ticker_info["ts"].to_string()).unwrap() / dec!(1000000)).floor().to_i64().unwrap();
  158. //
  159. // let result = Ticker {
  160. // time,
  161. // high: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
  162. // low: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
  163. // sell: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
  164. // buy: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
  165. // last: Decimal::from_str(ticker_info["price"].as_str().unwrap()).unwrap(),
  166. // volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
  167. // };
  168. // Ok(result)
  169. // } else {
  170. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  171. // }
  172. // }
  173. //
  174. // async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
  175. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
  176. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper, ""));
  177. // let res_data = self.request.get_ticker(symbol_format).await;
  178. // if res_data.code == 200 {
  179. // let res_data_json = res_data.data;
  180. // let ticker_info = res_data_json;
  181. // let time = (Decimal::from_str(&*ticker_info["ts"].to_string()).unwrap() / dec!(1000000)).floor().to_i64().unwrap();
  182. // let result = Ticker {
  183. // time,
  184. // high: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
  185. // low: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
  186. // sell: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
  187. // buy: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
  188. // last: Decimal::from_str(ticker_info["price"].as_str().unwrap()).unwrap(),
  189. // volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
  190. // };
  191. // Ok(result)
  192. // } else {
  193. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  194. // }
  195. // }
  196. //
  197. // async fn get_market(&mut self) -> Result<Market, Error> {
  198. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  199. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  200. // let res_data = self.request.get_market_details().await;
  201. // if res_data.code == 200 {
  202. // let res_data_json = res_data.data.as_array().unwrap();
  203. //
  204. // let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
  205. // match market_info {
  206. // None => {
  207. // error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
  208. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  209. // }
  210. // Some(value) => {
  211. // let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
  212. // let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
  213. // let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
  214. // let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
  215. // let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
  216. // let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
  217. // let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
  218. //
  219. // let amount_size = min_qty * ct_val;
  220. // let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
  221. // let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
  222. // let min_notional = min_qty * ct_val;
  223. //
  224. // let result = Market {
  225. // symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
  226. // base_asset: base_asset_mapper,
  227. // quote_asset: quote_asset_mapper,
  228. // tick_size,
  229. // amount_size,
  230. // price_precision,
  231. // amount_precision,
  232. // min_qty,
  233. // max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
  234. // min_notional,
  235. // max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
  236. // ct_val,
  237. // };
  238. // Ok(result)
  239. // }
  240. // }
  241. // } else {
  242. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  243. // }
  244. // }
  245. //
  246. // async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
  247. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
  248. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  249. // let res_data = self.request.get_market_details().await;
  250. // if res_data.code == 200 {
  251. // let res_data_json = res_data.data.as_array().unwrap();
  252. // let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
  253. // match market_info {
  254. // None => {
  255. // error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
  256. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  257. // }
  258. // Some(value) => {
  259. // let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
  260. // let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
  261. // let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
  262. // let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
  263. // let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
  264. // let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
  265. // let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
  266. //
  267. // let amount_size = min_qty * ct_val;
  268. // let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
  269. // let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
  270. // let min_notional = min_qty * ct_val;
  271. //
  272. // let result = Market {
  273. // symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
  274. // base_asset: base_asset_mapper,
  275. // quote_asset: quote_asset_mapper,
  276. // tick_size,
  277. // amount_size,
  278. // price_precision,
  279. // amount_precision,
  280. // min_qty,
  281. // max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
  282. // min_notional,
  283. // max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
  284. // ct_val,
  285. // };
  286. // Ok(result)
  287. // }
  288. // }
  289. // } else {
  290. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  291. // }
  292. // }
  293. //
  294. // async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
  295. // let ct_val = self.market.ct_val;
  296. // let res_data = self.request.get_orders_details(order_id.to_string(), custom_id.to_string()).await;
  297. // if res_data.code == 200 {
  298. // let res_data_json = res_data.data;
  299. // let result = format_order_item(res_data_json, ct_val);
  300. // Ok(result)
  301. // } else {
  302. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  303. // }
  304. // }
  305. //
  306. // async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error> {
  307. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  308. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  309. // let ct_val = self.market.ct_val;
  310. // let res_data = self.request.get_orders(status.to_string(), symbol_format.clone()).await;
  311. // if res_data.code == 200 {
  312. // let res_data_json = res_data.data;
  313. // let order_list = res_data_json["items"].as_array().unwrap().clone();
  314. // let order_info: Vec<_> = order_list.iter().filter(|item| item["symbol"].as_str().unwrap_or("") == symbol_format.clone()).collect();
  315. // let result = order_info.iter().map(|&item| format_order_item(item.clone(), ct_val)).collect();
  316. // Ok(result)
  317. // } else {
  318. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  319. // }
  320. // }
  321. //
  322. // async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
  323. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  324. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  325. // let ct_val = self.market.ct_val;
  326. // let mut params = json!({
  327. // "clientOid": custom_id,
  328. // "symbol": symbol_format,
  329. // "leverage": "10",
  330. // "reduceOnly":false,
  331. // "price": price.to_string(),
  332. // });
  333. // params["type"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
  334. // let size = (amount / ct_val).floor();
  335. // params["size"] = json!(size);
  336. // match origin_side {
  337. // "kd" => {
  338. // params["side"] = json!("buy");
  339. // }
  340. // "pd" => {
  341. // params["side"] = json!("sell");
  342. // }
  343. // "kk" => {
  344. // params["side"] = json!("sell");
  345. // }
  346. // "pk" => {
  347. // params["side"] = json!("buy");
  348. // }
  349. // _ => { error!("下单参数错误"); }
  350. // };
  351. //
  352. // let res_data = self.request.swap_order(params).await;
  353. // if res_data.code == 200 {
  354. // let res_data_json = res_data.data;
  355. // let id = res_data_json["orderId"].as_str().unwrap().to_string();
  356. // let result = Order {
  357. // id,
  358. // custom_id: custom_id.to_string(),
  359. // price,
  360. // amount,
  361. // deal_amount: Decimal::ZERO,
  362. // avg_price: Decimal::ZERO,
  363. // status: "NEW".to_string(),
  364. // order_type: "".to_string(),
  365. // trace_stack: TraceStack::new(0, Instant::now()).on_special("359 kucoin_swap".to_string()),
  366. // };
  367. // Ok(result)
  368. // } else {
  369. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  370. // }
  371. // }
  372. //
  373. // async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
  374. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
  375. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  376. // let mut params = json!({
  377. // "clientOid": custom_id,
  378. // "symbol": symbol_format,
  379. // "leverage": "10",
  380. // "reduceOnly":false,
  381. // "price": price.to_string(),
  382. // });
  383. // let size = (amount / ct_val).floor();
  384. // params["size"] = json!(size);
  385. // if price.eq(&Decimal::ZERO){
  386. // params["type"] = json!("market");
  387. // }
  388. // match origin_side {
  389. // "kd" => {
  390. // params["side"] = json!("buy");
  391. // }
  392. // "pd" => {
  393. // params["side"] = json!("sell");
  394. // }
  395. // "kk" => {
  396. // params["side"] = json!("sell");
  397. // }
  398. // "pk" => {
  399. // params["side"] = json!("buy");
  400. // }
  401. // _ => { error!("下单参数错误"); }
  402. // };
  403. //
  404. // let res_data = self.request.swap_order(params).await;
  405. // if res_data.code == 200 {
  406. // let res_data_json = res_data.data;
  407. // let id = res_data_json["orderId"].as_str().unwrap().to_string();
  408. // let result = Order {
  409. // id,
  410. // custom_id: custom_id.to_string(),
  411. // price,
  412. // amount,
  413. // deal_amount: Decimal::ZERO,
  414. // avg_price: Decimal::ZERO,
  415. // status: "NEW".to_string(),
  416. // order_type: "".to_string(),
  417. // trace_stack: TraceStack::new(0, Instant::now()).on_special("408 kucoin_swap".to_string()),
  418. // };
  419. // Ok(result)
  420. // } else {
  421. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  422. // }
  423. // }
  424. //
  425. // async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
  426. // let res_data = self.request.cancel_order(order_id.to_string(), custom_id.to_string()).await;
  427. // if order_id == "" {
  428. // error!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id);
  429. // panic!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id)
  430. // }
  431. // if res_data.code == 200 {
  432. // let res_data_json = res_data.data;
  433. // let cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
  434. // let id = cancel_ids[0].as_str().unwrap().to_string();
  435. // let result = Order {
  436. // id,
  437. // custom_id: custom_id.to_string(),
  438. // price: Decimal::ZERO,
  439. // amount: Decimal::ZERO,
  440. // deal_amount: Decimal::ZERO,
  441. // avg_price: Decimal::ZERO,
  442. // status: "REMOVE".to_string(),
  443. // order_type: "".to_string(),
  444. // trace_stack: TraceStack::new(0, Instant::now()).on_special("436 kucoin_swap".to_string()),
  445. // };
  446. // Ok(result)
  447. // } else {
  448. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  449. // }
  450. // }
  451. //
  452. // async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
  453. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  454. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  455. // let res_data = self.request.cancel_orders(symbol_format).await;
  456. // if res_data.code == 200 {
  457. // info!("{}", res_data.data.to_string());
  458. // let res_data_json = res_data.data;
  459. // let cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
  460. // let result = cancel_ids.iter().map(|item|
  461. // Order {
  462. // id: item.as_str().unwrap().to_string(),
  463. // custom_id: "".to_string(),
  464. // price: Decimal::ZERO,
  465. // amount: Decimal::ZERO,
  466. // deal_amount: Decimal::ZERO,
  467. // avg_price: Decimal::ZERO,
  468. // status: "REMOVE".to_string(),
  469. // order_type: "".to_string(),
  470. // trace_stack: TraceStack::new(0, Instant::now()).on_special("461 kucoin_swap".to_string()),
  471. // }
  472. // ).collect();
  473. // Ok(result)
  474. // } else {
  475. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  476. // }
  477. // }
  478. //
  479. // async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
  480. // let res_data = self.request.cancel_order_all().await;
  481. // if res_data.code == 200 {
  482. // info!("{}", res_data.data.to_string());
  483. // let res_data_json = res_data.data;
  484. // let cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
  485. // let result = cancel_ids.iter().map(|item|
  486. // Order {
  487. // id: item.as_str().unwrap().to_string(),
  488. // custom_id: "".to_string(),
  489. // price: Decimal::ZERO,
  490. // amount: Decimal::ZERO,
  491. // deal_amount: Decimal::ZERO,
  492. // avg_price: Decimal::ZERO,
  493. // status: "REMOVE".to_string(),
  494. // order_type: "".to_string(),
  495. // trace_stack: TraceStack::new(0, Instant::now()).on_special("486 kucoin_swap".to_string()),
  496. // }
  497. // ).collect();
  498. // Ok(result)
  499. // } else {
  500. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  501. // }
  502. // }
  503. //
  504. // async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
  505. // Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
  506. // }
  507. //
  508. // async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
  509. // Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
  510. // }
  511. //
  512. // async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
  513. // Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
  514. // }
  515. //
  516. // async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
  517. // Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
  518. // }
  519. //
  520. // async fn set_auto_deposit_status(&mut self, status: bool) -> Result<String, Error> {
  521. // let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
  522. // let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
  523. // let res_data = self.request.auto_deposit_status(symbol_format, status).await;
  524. // if res_data.code == 200 {
  525. // Ok(res_data.data.to_string())
  526. // } else {
  527. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  528. // }
  529. // }
  530. //
  531. // async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
  532. // Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
  533. // }
  534. //
  535. // // 指令下单
  536. // async fn command_order(&mut self, order_command: &mut OrderCommand, trace_stack: &TraceStack) {
  537. // let mut handles = vec![];
  538. // // 下单指令,limits_open里已经包含了limits_close,在core里面处理过了
  539. // for item in order_command.limits_open.keys() {
  540. // let mut ts = trace_stack.clone();
  541. //
  542. // let amount = Decimal::from_str(&*order_command.limits_open[item].get(0).unwrap().clone()).unwrap();
  543. // let side = order_command.limits_open[item].get(1).unwrap().clone();
  544. // let price = Decimal::from_str(&*order_command.limits_open[item].get(2).unwrap().clone()).unwrap();
  545. // let cid = order_command.limits_open[item].get(3).unwrap().clone();
  546. //
  547. // let mut self_clone = self.clone();
  548. // let handle = tokio::spawn(async move {
  549. // ts.on_before_send();
  550. // let result = self_clone.take_order(&cid, &side, price, amount).await;
  551. // ts.on_after_send();
  552. //
  553. // match result {
  554. // Ok(mut result) => {
  555. // // ts.on_after_send();
  556. // result.trace_stack = ts.clone();
  557. //
  558. // self_clone.order_sender.send(result).await.unwrap();
  559. // }
  560. // Err(error) => {
  561. // let mut err_order = Order::new();
  562. // err_order.custom_id = cid.clone();
  563. // err_order.status = "REMOVE".to_string();
  564. //
  565. // self_clone.order_sender.send(err_order).await.unwrap();
  566. // self_clone.error_sender.send(error).await.unwrap();
  567. // }
  568. // }
  569. // });
  570. // handles.push(handle)
  571. // }
  572. // let futures = FuturesUnordered::from_iter(handles);
  573. // // 等待所有任务完成
  574. // let _: Result<Vec<_>, _> = futures.try_collect().await;
  575. //
  576. // // 撤销订单
  577. // let mut cancel_handlers = vec![];
  578. // for item in order_command.cancel.keys() {
  579. // let order_id = order_command.cancel[item].get(1).unwrap().clone();
  580. // let custom_id = order_command.cancel[item].get(0).unwrap().clone();
  581. //
  582. // let mut self_clone = self.clone();
  583. //
  584. // let handle = tokio::spawn(async move {
  585. // if order_id != "" {
  586. // let result = self_clone.cancel_order(&order_id, &custom_id).await;
  587. // match result {
  588. // Ok(_) => {
  589. // // result_sd.send(result).await.unwrap();
  590. // }
  591. // Err(error) => {
  592. // // 取消失败去查订单。
  593. // let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
  594. // match query_rst {
  595. // Ok(order) => {
  596. // self_clone.order_sender.send(order).await.unwrap();
  597. // }
  598. // Err(_query_err) => {
  599. // // error!(?_query_err);
  600. // // error!("撤单失败,而且查单也失败了,kucoin_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
  601. // }
  602. // }
  603. // self_clone.error_sender.send(error).await.unwrap();
  604. // }
  605. // }
  606. // }
  607. // });
  608. // cancel_handlers.push(handle)
  609. // }
  610. // let futures = FuturesUnordered::from_iter(cancel_handlers);
  611. // // 等待所有任务完成
  612. // let _: Result<Vec<_>, _> = futures.try_collect().await;
  613. //
  614. // // 检查订单指令
  615. // let mut check_handlers = vec![];
  616. // for item in order_command.check.keys() {
  617. // let order_id = order_command.check[item].get(1).unwrap().clone();
  618. // let custom_id = order_command.check[item].get(0).unwrap().clone();
  619. //
  620. // let mut self_clone = self.clone();
  621. //
  622. // let handle = tokio::spawn(async move {
  623. // let result = self_clone.get_order_detail(&order_id, &custom_id).await;
  624. // match result {
  625. // Ok(result) => {
  626. // self_clone.order_sender.send(result).await.unwrap();
  627. // }
  628. // Err(error) => {
  629. // self_clone.error_sender.send(error).await.unwrap();
  630. // }
  631. // }
  632. // });
  633. // check_handlers.push(handle)
  634. // }
  635. //
  636. // let futures = FuturesUnordered::from_iter(check_handlers);
  637. // // 等待所有任务完成
  638. // let _: Result<Vec<_>, _> = futures.try_collect().await;
  639. // }
  640. // }
  641. //
  642. // pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
  643. // let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
  644. // let size = Decimal::from_f64(order["size"].as_f64().unwrap()).unwrap();
  645. // let status = order["status"].as_str().unwrap_or("");
  646. // let filled_size = Decimal::from_f64(order["filledSize"].as_f64().unwrap()).unwrap();
  647. // let filled_value = Decimal::from_str(order["filledValue"].as_str().unwrap()).unwrap();
  648. //
  649. // let amount = size * ct_val;
  650. // let deal_amount = filled_size * ct_val;
  651. // let avg_price = if deal_amount.is_zero() { Decimal::ZERO } else { filled_value / deal_amount };
  652. // let custom_status;
  653. // if ["cancelled", "closed", "finished"].contains(&status) {
  654. // custom_status = "REMOVE".to_string();
  655. // } else if status == "open" {
  656. // custom_status = "NEW".to_string();
  657. // } else {
  658. // custom_status = "NULL".to_string();
  659. // };
  660. // Order {
  661. // id: order["id"].as_str().unwrap().to_string(),
  662. // custom_id: order["clientOid"].as_str().unwrap_or("").to_string(),
  663. // price,
  664. // amount,
  665. // deal_amount,
  666. // avg_price,
  667. // status: custom_status,
  668. // order_type: order["type"].as_str().unwrap().to_string(),
  669. // trace_stack: TraceStack::new(0, Instant::now()).on_special("655 kucoin_swap".to_string()),
  670. // }
  671. // }