binance_swap.rs 32 KB

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