htx_swap.rs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. // use std::collections::{BTreeMap};
  2. // use exchanges::htx_swap_rest::HtxSwapRest;
  3. // use std::io::{Error, ErrorKind};
  4. // use tokio::sync::mpsc::Sender;
  5. // use std::str::FromStr;
  6. // use async_trait::async_trait;
  7. // use futures::stream::FuturesUnordered;
  8. // use futures::TryStreamExt;
  9. // use rust_decimal::Decimal;
  10. // use rust_decimal::prelude::{FromPrimitive};
  11. // use serde_json::json;
  12. // use serde_json::Value::Null;
  13. // use tokio::spawn;
  14. // use tokio::time::Instant;
  15. // use tracing::{error, info};
  16. // use global::trace_stack::TraceStack;
  17. // use crate::exchange::ExchangeEnum;
  18. // use crate::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, Ticker, utils};
  19. //
  20. // #[allow(dead_code)]
  21. // #[derive(Clone)]
  22. // pub struct HtxSwap {
  23. // exchange: ExchangeEnum,
  24. // symbol: String,
  25. // is_colo: bool,
  26. // params: BTreeMap<String, String>,
  27. // request: HtxSwapRest,
  28. // market: Market,
  29. // order_sender: Sender<Order>,
  30. // error_sender: Sender<Error>,
  31. // }
  32. //
  33. // impl HtxSwap {
  34. // pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> HtxSwap {
  35. // let market = Market::new();
  36. // let mut htx_swap = HtxSwap {
  37. // exchange: ExchangeEnum::HtxSwap,
  38. // symbol: symbol.to_uppercase(),
  39. // is_colo,
  40. // params: params.clone(),
  41. // request: HtxSwapRest::new(is_colo, params.clone()),
  42. // market,
  43. // order_sender,
  44. // error_sender,
  45. // };
  46. // htx_swap.market = HtxSwap::get_market(&mut htx_swap).await.unwrap();
  47. // // 修改持仓模式
  48. // let mode_result = htx_swap.set_dual_mode("", true).await;
  49. // match mode_result {
  50. // Ok(ok) => {
  51. // info!("HtxSwap:设置持仓模式成功!{:?}", ok);
  52. // }
  53. // Err(error) => {
  54. // error!("HtxSwap:设置持仓模式失败!{:?}", error)
  55. // }
  56. // }
  57. // // 设置持仓杠杆
  58. // let lever_rate_result = htx_swap.set_dual_leverage("10").await;
  59. // match lever_rate_result {
  60. // Ok(ok) => {
  61. // info!("HtxSwap:设置持仓杠杆成功!{:?}", ok);
  62. // }
  63. // Err(error) => {
  64. // error!("HtxSwap:设置持仓杠杆失败!{:?}", error)
  65. // }
  66. // }
  67. //
  68. // return htx_swap;
  69. // }
  70. // }
  71. //
  72. // #[async_trait]
  73. // impl Platform for HtxSwap {
  74. // fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
  75. //
  76. // fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::HtxSwap }
  77. //
  78. // fn get_self_symbol(&self) -> String { self.symbol.clone() }
  79. //
  80. // fn get_self_is_colo(&self) -> bool { self.is_colo }
  81. //
  82. // fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
  83. //
  84. // fn get_self_market(&self) -> Market { self.market.clone() }
  85. //
  86. // fn get_request_delays(&self) -> Vec<i64> {
  87. // // self.request.get_delays()
  88. // vec![]
  89. // }
  90. //
  91. // fn get_request_avg_delay(&self) -> Decimal {
  92. // // self.request.get_avg_delay()
  93. // Decimal::ZERO
  94. // }
  95. //
  96. // fn get_request_max_delay(&self) -> i64 { 0 }
  97. //
  98. // async fn get_server_time(&mut self) -> Result<String, Error> {
  99. // let response = self.request.get_server_time().await;
  100. // if response.code != 200 {
  101. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取服务器时间异常{:?}", response).to_string()));
  102. // }
  103. //
  104. // let res_data_json = response.data;
  105. // let result = res_data_json["ts"].to_string();
  106. // Ok(result)
  107. // }
  108. //
  109. // async fn get_account(&mut self) -> Result<Account, Error> {
  110. // let params = json!({
  111. // "margin_account": "USDT"
  112. // });
  113. // let response = self.request.get_account(params).await;
  114. // if response.code != 200 {
  115. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取账户信息异常{:?}", response).to_string()));
  116. // }
  117. //
  118. // let res_data_json = response.data;
  119. // let mut account = Account::new();
  120. // for data in res_data_json.as_array().unwrap() {
  121. // let margin_position = Decimal::from_f64(data["margin_position"].as_f64().unwrap()).unwrap();
  122. //
  123. // let balance = Decimal::from_f64(data["margin_static"].as_f64().unwrap()).unwrap();
  124. // let frozen_balance = Decimal::from_f64(data["margin_frozen"].as_f64().unwrap()).unwrap();
  125. // let available_balance = balance - margin_position - frozen_balance;
  126. // // 格式化account信息
  127. // account = Account {
  128. // coin: data["margin_asset"].as_str().unwrap().to_string(),
  129. // balance,
  130. // available_balance,
  131. // frozen_balance,
  132. // stocks: Default::default(),
  133. // available_stocks: Default::default(),
  134. // frozen_stocks: Default::default(),
  135. // };
  136. // }
  137. // return Ok(account);
  138. // }
  139. //
  140. // async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
  141. // Err(Error::new(ErrorKind::NotFound, "htx_swap get_spot_account:该交易所方法未实现".to_string()))
  142. // }
  143. //
  144. // async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
  145. // let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
  146. // let ct_val = self.market.ct_val;
  147. // let params = json!({
  148. // "contract_type": "swap",
  149. // "contract_code": symbol_format
  150. // });
  151. // let response = self.request.get_user_position(params).await;
  152. // if response.code != 200 {
  153. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取仓位异常{:?}", response).to_string()));
  154. // }
  155. //
  156. // let res_data_json = response.data;
  157. // let positions_info = res_data_json.as_array().unwrap();
  158. // let result = positions_info.iter().map(|item| { format_position_item(item, &ct_val) }).collect();
  159. // Ok(result)
  160. // }
  161. //
  162. // async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
  163. // let params = json!({
  164. // "contract_type": "swap"
  165. // });
  166. // let response = self.request.get_user_position(params).await;
  167. //
  168. // if response.code != 200 {
  169. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取仓位异常{:?}", response).to_string()));
  170. // }
  171. //
  172. // let res_data_json = response.data;
  173. // let positions_info = res_data_json.as_array().unwrap();
  174. // let result = positions_info.iter().map(|item| { format_position_item(item, &Decimal::ONE) }).collect();
  175. // Ok(result)
  176. // }
  177. //
  178. // async fn get_ticker(&mut self) -> Result<Ticker, Error> {
  179. // return self.get_ticker_symbol(self.symbol.clone()).await;
  180. // }
  181. //
  182. // async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
  183. // let symbol_format = utils::format_symbol(symbol.clone(), "-");
  184. // let params = json!({
  185. // "contract_code": symbol_format,
  186. // });
  187. // let response = self.request.get_ticker(params).await;
  188. // if response.code != 200 {
  189. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取行情信息异常{:?}", response).to_string()));
  190. // }
  191. //
  192. // let res_data_json = response.data;
  193. // let ticker_info = res_data_json["tick"].clone();
  194. // let time = ticker_info["ts"].as_i64().unwrap();
  195. // let result = Ticker {
  196. // time,
  197. // high: Decimal::from_str(ticker_info["high"].as_str().unwrap()).unwrap(),
  198. // low: Decimal::from_str(ticker_info["low"].as_str().unwrap()).unwrap(),
  199. // sell: Decimal::from_f64(ticker_info["bid"][0].as_f64().unwrap()).unwrap(),
  200. // buy: Decimal::from_f64(ticker_info["ask"][0].as_f64().unwrap()).unwrap(),
  201. // last: Decimal::from_str(ticker_info["close"].as_str().unwrap()).unwrap(),
  202. // volume: Decimal::from_str(ticker_info["amount"].as_str().unwrap()).unwrap(),
  203. // };
  204. // Ok(result)
  205. // }
  206. //
  207. // async fn get_market(&mut self) -> Result<Market, Error> {
  208. // self.get_market_symbol(self.symbol.clone()).await
  209. // }
  210. //
  211. // async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
  212. // let symbol_format = utils::format_symbol(symbol.clone(), "-");
  213. // let symbol_array: Vec<&str> = self.symbol.split("_").collect();
  214. //
  215. // let params = json!({
  216. // "pair": symbol_format,
  217. // "contract_type":"swap"
  218. // });
  219. // let response = self.request.get_market(params).await;
  220. // if response.code != 200 {
  221. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取市场信息异常{:?}", response).to_string()));
  222. // }
  223. // let res_data_json = response.data.as_array().unwrap();
  224. // let market_info = res_data_json[0].clone();
  225. //
  226. // if !market_info["pair"].as_str().unwrap().to_string().eq(&symbol_format) {
  227. // return Err(Error::new(ErrorKind::NotFound, format!("符号未找到:symbol={}, response={:?}", symbol_format, response))).unwrap();
  228. // }
  229. //
  230. // let base_asset = market_info["symbol"].as_str().unwrap().to_string();
  231. // let quote_asset = symbol_array[1].to_string();
  232. //
  233. // let tick_size = Decimal::from_f64(market_info["price_tick"].as_f64().unwrap()).unwrap();
  234. // let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
  235. // let amount_size = Decimal::from_f64(market_info["contract_size"].as_f64().unwrap()).unwrap();
  236. // let amount_precision = Decimal::ZERO;
  237. // let min_qty = Decimal::NEGATIVE_ONE;
  238. // let max_qty = Decimal::NEGATIVE_ONE;
  239. // let ct_val = Decimal::from_f64(market_info["contract_size"].as_f64().unwrap()).unwrap();
  240. //
  241. // let result = Market {
  242. // symbol: format!("{}_{}", base_asset, quote_asset),
  243. // base_asset,
  244. // quote_asset,
  245. // tick_size,
  246. // amount_size,
  247. // price_precision,
  248. // amount_precision,
  249. // min_qty,
  250. // max_qty,
  251. // min_notional: min_qty,
  252. // max_notional: max_qty,
  253. // ct_val,
  254. // };
  255. // Ok(result)
  256. // }
  257. //
  258. // async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
  259. // let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
  260. // let ct_val = self.market.ct_val;
  261. //
  262. // let mut params = json!({
  263. // "pair": symbol_format
  264. // });
  265. // if order_id.eq("") { params["client_order_id"] = json!(custom_id) } else { params["order_id"] = json!(order_id) };
  266. // let response = self.request.get_order_details(params).await;
  267. // if response.code != 200 || response.data == Null {
  268. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取订单详情异常{:?}", response).to_string()));
  269. // }
  270. //
  271. // let res_data_json = response.data;
  272. // let orders = res_data_json.as_array().unwrap();
  273. // let result = format_order_item(orders[0].clone(), ct_val);
  274. // Ok(result)
  275. // }
  276. //
  277. // async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
  278. // Err(Error::new(ErrorKind::NotFound, "htx_swap get_orders_list:该交易所方法未实现".to_string()))
  279. // }
  280. //
  281. // async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
  282. // let ct_val = self.market.ct_val;
  283. //
  284. // return self.take_order_symbol(self.symbol.clone(), ct_val, custom_id, origin_side, price, amount).await;
  285. // }
  286. //
  287. // 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> {
  288. // let symbol_format = utils::format_symbol(symbol, "-");
  289. // let final_size = (amount / ct_val).floor();
  290. // let mut params = json!({
  291. // "pair": symbol_format,
  292. // "client_order_id": custom_id,
  293. // "contract_type": "swap",
  294. // "volume": final_size.to_string(),
  295. // "lever_rate": 10
  296. // });
  297. // if price.eq(&Decimal::ZERO) {
  298. // params["order_price_type"] = json!("market");
  299. // } else {
  300. // params["price"] = json!(price.to_string());
  301. // params["order_price_type"] = json!("limit");
  302. // };
  303. // match origin_side {
  304. // "kd" => {
  305. // params["direction"] = json!("buy");
  306. // params["offset"] = json!("open");
  307. // }
  308. // "pd" => {
  309. // params["direction"] = json!("sell");
  310. // params["offset"] = json!("close");
  311. // }
  312. // "kk" => {
  313. // params["direction"] = json!("sell");
  314. // params["offset"] = json!("open");
  315. // }
  316. // "pk" => {
  317. // params["direction"] = json!("buy");
  318. // params["offset"] = json!("close");
  319. // }
  320. // _ => { panic!("htx_usdt_swap 下单参数错误"); }
  321. // };
  322. // let response = self.request.swap_order(params).await;
  323. // if response.code != 200 {
  324. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 下单异常{:?}", response).to_string()));
  325. // }
  326. //
  327. // let res_data_json = response.data;
  328. // let result = Order {
  329. // id: res_data_json["order_id"].to_string(),
  330. // custom_id: res_data_json["client_order_id"].to_string(),
  331. // price: Decimal::ZERO,
  332. // amount: Decimal::ZERO,
  333. // deal_amount: Decimal::ZERO,
  334. // avg_price: Decimal::ZERO,
  335. // status: "NEW".to_string(),
  336. // order_type: "".to_string(),
  337. // trace_stack: TraceStack::new(0, Instant::now()).on_special("339 htx_swap".to_string()),
  338. // };
  339. // return Ok(result);
  340. // }
  341. //
  342. // async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
  343. // let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
  344. // let mut params = json!({
  345. // "pair": symbol_format,
  346. // "contract_type": "swap"
  347. // });
  348. // if order_id.eq("") { params["client_order_id"] = json!(custom_id) } else { params["order_id"] = json!(order_id) };
  349. // let response = self.request.cancel_order(params).await;
  350. //
  351. // // 取消失败,进行报错
  352. // if response.code != 200 || response.data["errors"].as_array().unwrap_or(&vec![]).len() > 0 {
  353. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 取消订单异常{:?}", response).to_string()));
  354. // }
  355. // let res_data_json = response.data;
  356. // let mut id = order_id.to_string();
  357. // let mut custom_id = custom_id.to_string();
  358. // if order_id.eq("") {
  359. // custom_id = res_data_json["successes"].as_str().unwrap().to_string()
  360. // } else {
  361. // id = res_data_json["successes"].as_str().unwrap().to_string()
  362. // };
  363. // let result = Order {
  364. // id,
  365. // custom_id,
  366. // price: Decimal::ZERO,
  367. // amount: Decimal::ZERO,
  368. // deal_amount: Decimal::ZERO,
  369. // avg_price: Decimal::ZERO,
  370. // status: "REMOVE".to_string(),
  371. // order_type: "".to_string(),
  372. // trace_stack: TraceStack::new(0, Instant::now()).on_special("374 htx_swap".to_string()),
  373. // };
  374. // Ok(result)
  375. // }
  376. //
  377. // async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
  378. // Err(Error::new(ErrorKind::NotFound, "htx_swap cancel_orders:该交易所方法未实现".to_string()))
  379. // }
  380. //
  381. // async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
  382. // let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
  383. // let params = json!({
  384. // "pair": symbol_format,
  385. // "contract_type": "swap"
  386. // });
  387. // let response = self.request.cancel_price_order(params).await;
  388. // if response.code != 200 {
  389. // if response.data.to_string().contains("No cancellable orders") { return Ok(vec![]); }
  390. // return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 撤销所有订单异常{:?}", response).to_string()));
  391. // }
  392. //
  393. // Ok(vec![])
  394. // }
  395. //
  396. // async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<serde_json::Value, Error> {
  397. // Err(Error::new(ErrorKind::NotFound, "htx_swap take_stop_loss_order:该交易所方法未实现".to_string()))
  398. // }
  399. //
  400. // async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<serde_json::Value, Error> {
  401. // Err(Error::new(ErrorKind::NotFound, "htx_swap cancel_stop_loss_order:该交易所方法未实现".to_string()))
  402. // }
  403. //
  404. // async fn set_dual_mode(&mut self, _coin: &str, is_dual_mode: bool) -> Result<String, Error> {
  405. // let pos_mode = if is_dual_mode { "dual_side" } else { "single_side" };
  406. // let params = json!({
  407. // "margin_account": "USDT",
  408. // "position_mode": pos_mode,
  409. // });
  410. // let response = self.request.setting_dual_mode(params).await;
  411. // if response.code != 200 {
  412. // return Err(Error::new(ErrorKind::Other, format!("设置持仓模式失败:{:?}", response).to_string()));
  413. // }
  414. //
  415. // return Ok(response.data.to_string());
  416. // }
  417. //
  418. // async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
  419. // let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
  420. // let params = json!({
  421. // "pair": symbol_format,
  422. // "contract_type": "swap",
  423. // "lever_rate": leverage
  424. // });
  425. // let response = self.request.setting_dual_leverage(params).await;
  426. //
  427. // if response.code != 200 {
  428. // return Err(Error::new(ErrorKind::Other, format!("设置杠杆失败:{:?}", response).to_string()));
  429. // }
  430. //
  431. // return Ok(response.data.to_string());
  432. // }
  433. //
  434. // async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
  435. // Err(Error::new(ErrorKind::NotFound, "htx_swap set_auto_deposit_status:该交易所方法未实现".to_string()))
  436. // }
  437. //
  438. // async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
  439. // Err(Error::new(ErrorKind::NotFound, "htx_swap wallet_transfers:该交易所方法未实现".to_string()))
  440. // }
  441. //
  442. // async fn command_order(&mut self, order_command: &mut OrderCommand, trace_stack: &TraceStack) {
  443. // let mut handles = vec![];
  444. //
  445. // // 下单指令
  446. // for item in order_command.limits_open.keys() {
  447. // let mut ts = trace_stack.clone();
  448. //
  449. // let amount = Decimal::from_str(&*order_command.limits_open[item].get(0).unwrap().clone()).unwrap();
  450. // let side = order_command.limits_open[item].get(1).unwrap().clone();
  451. // let price = Decimal::from_str(&*order_command.limits_open[item].get(2).unwrap().clone()).unwrap();
  452. // let cid = order_command.limits_open[item].get(3).unwrap().clone();
  453. //
  454. // // order_name: [数量,方向,价格,c_id]
  455. // let mut self_clone = self.clone();
  456. // let handle = spawn(async move {
  457. // // TraceStack::show_delay(&ts.ins);
  458. // ts.on_before_send();
  459. // let result = self_clone.take_order(cid.as_str(), side.as_str(), price, amount).await;
  460. // ts.on_after_send();
  461. // // info!("下单 custom_id {}", cid);
  462. // match result {
  463. // Ok(mut result) => {
  464. // result.trace_stack = ts;
  465. // // info!("下单完成 order_id {}", result.id);
  466. // self_clone.order_sender.send(result).await.unwrap();
  467. // }
  468. // Err(error) => {
  469. // info!(?error);
  470. // let mut err_order = Order::new();
  471. // err_order.custom_id = cid.clone();
  472. // err_order.status = "REMOVE".to_string();
  473. // ts.source = "htx_swap 474".to_string();
  474. // err_order.trace_stack = ts;
  475. //
  476. // self_clone.order_sender.send(err_order).await.unwrap();
  477. // self_clone.error_sender.send(error).await.unwrap();
  478. // }
  479. // }
  480. // });
  481. // handles.push(handle)
  482. // }
  483. // let futures = FuturesUnordered::from_iter(handles);
  484. // // 等待所有任务完成
  485. // let _: Result<Vec<_>, _> = futures.try_collect().await;
  486. //
  487. // // 撤销订单
  488. // let mut cancel_handlers = vec![];
  489. // for item in order_command.cancel.keys() {
  490. // let order_id = order_command.cancel[item].get(1).unwrap().clone();
  491. // let custom_id = order_command.cancel[item].get(0).unwrap().clone();
  492. // // info!("取消订单 order_id {}, custom_id {}", order_id, custom_id);
  493. // let mut self_clone = self.clone();
  494. // let handle = spawn(async move {
  495. // let result = self_clone.cancel_order(&order_id, &custom_id).await;
  496. // match result {
  497. // Ok(_) => {
  498. // // result_sd.send(result).await.unwrap();
  499. // }
  500. // Err(error) => {
  501. // // 已经取消的订单不去撤单了
  502. // if !error.to_string().contains("Your order has been canceled") {
  503. // // 取消失败去查订单。
  504. // let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
  505. // match query_rst {
  506. // Ok(order) => {
  507. // self_clone.order_sender.send(order).await.unwrap();
  508. // }
  509. // Err(err) => {
  510. // error!("撤单失败,而且查单也失败了,htx_swap,oid={}, cid={}, err={:?}。", order_id.clone(), custom_id.clone(), err);
  511. // }
  512. // }
  513. // error!("撤单失败,异常:{}", error);
  514. // self_clone.error_sender.send(error).await.unwrap();
  515. // }
  516. // }
  517. // }
  518. // });
  519. // cancel_handlers.push(handle)
  520. // }
  521. // let futures = FuturesUnordered::from_iter(cancel_handlers);
  522. // // 等待所有任务完成
  523. // let _: Result<Vec<_>, _> = futures.try_collect().await;
  524. //
  525. // // 检查订单指令
  526. // let mut check_handlers = vec![];
  527. // for item in order_command.check.keys() {
  528. // let order_id = order_command.check[item].get(1).unwrap().clone();
  529. // let custom_id = order_command.check[item].get(0).unwrap().clone();
  530. //
  531. // let mut self_clone = self.clone();
  532. // let handle = spawn(async move {
  533. // let result = self_clone.get_order_detail(order_id.as_str(), custom_id.as_str()).await;
  534. // match result {
  535. // Ok(result) => {
  536. // self_clone.order_sender.send(result).await.unwrap();
  537. // }
  538. // Err(error) => {
  539. // self_clone.error_sender.send(error).await.unwrap();
  540. // }
  541. // }
  542. // });
  543. // check_handlers.push(handle)
  544. // }
  545. //
  546. // let futures = FuturesUnordered::from_iter(check_handlers);
  547. // // 等待所有任务完成
  548. // let _: Result<Vec<_>, _> = futures.try_collect().await;
  549. // }
  550. // }
  551. //
  552. // // pub fn format_account_info(balance_data: Value) -> Account {
  553. // // let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
  554. // // let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
  555. // // let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
  556. // // let balance = available_balance + frozen_balance;
  557. // //
  558. // // Account {
  559. // // coin: balance_coin,
  560. // // balance,
  561. // // available_balance,
  562. // // frozen_balance,
  563. // // stocks: Decimal::ZERO,
  564. // // available_stocks: Decimal::ZERO,
  565. // // frozen_stocks: Decimal::ZERO,
  566. // // }
  567. // // }
  568. //
  569. // pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
  570. // let id = order["order_id"].to_string();
  571. // let custom_id = order["client_order_id"].to_string();
  572. // let price = Decimal::from_f64(order["price"].as_f64().unwrap()).unwrap();
  573. // let amount = Decimal::from_f64(order["volume"].as_f64().unwrap()).unwrap() * ct_val;
  574. // let deal_amount = Decimal::from_f64(order["trade_volume"].as_f64().unwrap()).unwrap() * ct_val;
  575. // let avg_price = Decimal::from_f64(order["trade_avg_price"].as_f64().unwrap_or(0.0)).unwrap();
  576. //
  577. // let status = order["status"].to_string();
  578. //
  579. // let custom_status = if ["5", "6", "7"].contains(&&**&status) {
  580. // "REMOVE".to_string()
  581. // } else if ["1", "2", "3", "4"].contains(&&**&status) {
  582. // "NEW".to_string()
  583. // } else {
  584. // "NULL".to_string()
  585. // };
  586. // Order {
  587. // id,
  588. // custom_id,
  589. // price,
  590. // amount,
  591. // deal_amount,
  592. // avg_price,
  593. // status: custom_status,
  594. // order_type: order["order_price_type"].as_str().unwrap().to_string(),
  595. // trace_stack: TraceStack::new(0, Instant::now()).on_special("630 htx_swap".to_string()),
  596. // }
  597. // }
  598. //
  599. // pub fn format_position_item(position: &serde_json::Value, ct_val: &Decimal) -> Position {
  600. // let symbol = position["pair"].as_str().unwrap().to_string();
  601. // let margin_level = Decimal::from_str(&position["lever_rate"].to_string()).unwrap();
  602. // let amount = Decimal::from_f64(position["volume"].as_f64().unwrap()).unwrap() * ct_val;
  603. //
  604. // let frozen_amount = Decimal::from_f64(position["frozen"].as_f64().unwrap()).unwrap();
  605. // let price = Decimal::from_f64(position["cost_hold"].as_f64().unwrap()).unwrap();
  606. // let profit = Decimal::from_f64(position["profit_unreal"].as_f64().unwrap()).unwrap();
  607. // let position_mode = match position["position_mode"].as_str().unwrap() {
  608. // "dual_side" => {
  609. // match position["direction"].as_str().unwrap() {
  610. // "sell" => {
  611. // PositionModeEnum::Short
  612. // }
  613. // "buy" => {
  614. // PositionModeEnum::Long
  615. // }
  616. // _ => {
  617. // panic!("htx_usdt_swap: 未知的持仓模式与持仓方向: {}, {}",
  618. // position["direction"].as_str().unwrap(), position["direction"].as_str().unwrap())
  619. // }
  620. // }
  621. // }
  622. // "single_side" => {
  623. // PositionModeEnum::Both
  624. // }
  625. // _ => {
  626. // panic!("htx_usdt_swap: 未知的持仓模式: {}", position["position_mode"].as_str().unwrap())
  627. // }
  628. // };
  629. // let margin = Decimal::from_f64(position["position_margin"].as_f64().unwrap()).unwrap();
  630. //
  631. // Position {
  632. // symbol,
  633. // margin_level,
  634. // amount,
  635. // frozen_amount,
  636. // price,
  637. // profit,
  638. // position_mode,
  639. // margin,
  640. // }
  641. // }