bybit_swap.rs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. use std::collections::{BTreeMap, HashMap};
  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 rust_decimal::Decimal;
  7. use serde_json::{from_str, from_value, json, Value};
  8. use futures::stream::FuturesUnordered;
  9. use futures::{TryStreamExt};
  10. use rust_decimal::prelude::FromPrimitive;
  11. use serde::{Deserialize, Serialize};
  12. use tracing::{error, debug, trace};
  13. use exchanges::bybit_swap_rest::BybitSwapRest;
  14. use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand, PositionModeEnum};
  15. use global::trace_stack::TraceStack;
  16. #[derive(Debug, Clone, Deserialize, Serialize)]
  17. #[serde(rename_all = "camelCase")]
  18. struct SwapTicker{
  19. symbol: String,
  20. high_price24h: Decimal,
  21. low_price24h: Decimal,
  22. bid1_price: Decimal,
  23. ask1_price: Decimal,
  24. last_price: Decimal,
  25. volume24h: Decimal
  26. }
  27. #[allow(dead_code)]
  28. #[derive(Clone)]
  29. pub struct BybitSwap {
  30. exchange: ExchangeEnum,
  31. symbol: String,
  32. symbol_uppercase: String,
  33. is_colo: bool,
  34. params: BTreeMap<String, String>,
  35. request: BybitSwapRest,
  36. market: Market,
  37. order_sender: Option<Sender<Order>>,
  38. error_sender: Option<Sender<Error>>,
  39. }
  40. impl BybitSwap {
  41. pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Option<Sender<Order>>, error_sender: Option<Sender<Error>>) -> BybitSwap {
  42. let market = Market::new();
  43. let mut bybit_swap = BybitSwap {
  44. exchange: ExchangeEnum::BybitSwap,
  45. symbol: symbol.to_uppercase(),
  46. symbol_uppercase: symbol.replace("_", "").to_uppercase(),
  47. is_colo,
  48. params: params.clone(),
  49. request: BybitSwapRest::new(is_colo, params.clone()),
  50. market,
  51. order_sender,
  52. error_sender,
  53. };
  54. // 修改持仓模式
  55. let symbol_array: Vec<&str> = symbol.split("_").collect();
  56. let mode_result = bybit_swap.set_dual_mode(symbol_array[1], true).await;
  57. match mode_result {
  58. Ok(_) => {
  59. trace!("Bybit:设置持仓模式成功!")
  60. }
  61. Err(error) => {
  62. error!("Bybit:设置持仓模式失败!mode_result={}", error)
  63. }
  64. }
  65. // 获取市场信息
  66. bybit_swap.market = BybitSwap::get_market(&mut bybit_swap).await.unwrap_or(bybit_swap.market);
  67. return bybit_swap;
  68. }
  69. }
  70. #[async_trait]
  71. impl Platform for BybitSwap {
  72. // 克隆方法
  73. fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
  74. // 获取交易所模式
  75. fn get_self_exchange(&self) -> ExchangeEnum {
  76. ExchangeEnum::BybitSwap
  77. }
  78. // 获取交易对
  79. fn get_self_symbol(&self) -> String { self.symbol.clone() }
  80. // 获取是否使用高速通道
  81. fn get_self_is_colo(&self) -> bool {
  82. self.is_colo
  83. }
  84. // 获取params信息
  85. fn get_self_params(&self) -> BTreeMap<String, String> {
  86. self.params.clone()
  87. }
  88. // 获取market信息
  89. fn get_self_market(&self) -> Market { self.market.clone() }
  90. // 获取请求时间
  91. fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
  92. // 获取请求平均时间
  93. fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
  94. // 获取请求最大时间
  95. fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
  96. // 获取服务器时间
  97. async fn get_server_time(&mut self) -> Result<String, Error> {
  98. let res_data = self.request.get_server_time().await;
  99. if res_data.code == "200" {
  100. let res_data_str = &res_data.data;
  101. let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
  102. let result = res_data_json["server_time"].to_string();
  103. Ok(result)
  104. } else {
  105. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  106. }
  107. }
  108. // 获取账号信息
  109. async fn get_account(&mut self) -> Result<Account, Error> {
  110. let symbol_array: Vec<&str> = self.symbol.split("_").collect();
  111. let res_data = self.request.get_account_balance(symbol_array[1].parse().unwrap()).await;
  112. if res_data.code == "200" {
  113. let res_data_str = &res_data.data;
  114. let res_data_json: Value = from_str(res_data_str).unwrap();
  115. let arr_infos: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
  116. if arr_infos.len() < 1usize{
  117. return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
  118. }
  119. let coin_infos: Vec<Value> = from_value(arr_infos[0]["coin"].clone()).unwrap();
  120. if coin_infos.len() < 1usize{
  121. return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
  122. }
  123. let balance = Decimal::from_str(coin_infos[0]["equity"].as_str().unwrap()).unwrap();
  124. let available_balance = Decimal::from_str(coin_infos[0]["walletBalance"].as_str().unwrap()).unwrap();
  125. let frozen_balance = balance - available_balance;
  126. let result = Account {
  127. coin: symbol_array[1].to_string(),
  128. balance,
  129. available_balance,
  130. frozen_balance,
  131. stocks: Decimal::ZERO,
  132. available_stocks: Decimal::ZERO,
  133. frozen_stocks: Decimal::ZERO,
  134. };
  135. Ok(result)
  136. } else {
  137. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  138. }
  139. }
  140. async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
  141. Err(Error::new(ErrorKind::NotFound, "bybit_swap:该交易所方法未实现".to_string()))
  142. }
  143. // 获取持仓信息
  144. async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
  145. let symbol = self.symbol_uppercase.clone();
  146. let ct_val = self.market.ct_val;
  147. let res_data = self.request.get_positions(symbol, "".to_string()).await;
  148. if res_data.code == "200" {
  149. let res_data_str: Value = from_str(&res_data.data).unwrap();
  150. let res_data_json: Vec<Value> = from_value(res_data_str["list"].clone()).unwrap();
  151. let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
  152. Ok(result)
  153. } else {
  154. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  155. }
  156. }
  157. // 获取所有持仓
  158. async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
  159. let symbol_array: Vec<&str> = self.symbol.split("_").collect();
  160. let ct_val = self.market.ct_val;
  161. let res_data = self.request.get_positions("".to_string(), symbol_array[1].to_string().to_uppercase()).await;
  162. if res_data.code == "200" {
  163. let res_data_str: Value = from_str(&res_data.data).unwrap();
  164. let res_data_json: Vec<Value> = from_value(res_data_str["list"].clone()).unwrap();
  165. let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
  166. Ok(result)
  167. } else {
  168. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  169. }
  170. }
  171. // 获取市场行情
  172. async fn get_ticker(&mut self) -> Result<Ticker, Error> {
  173. let symbol = self.symbol_uppercase.clone();
  174. let res_data = self.request.get_tickers(symbol).await;
  175. if res_data.code == "200" {
  176. let res_data_str = &res_data.data;
  177. let res_data_json: Value = from_str(res_data_str).unwrap();
  178. let list :Vec<SwapTicker>= from_value(res_data_json["list"].clone()).unwrap_or(Vec::new());
  179. if list.len() < 1usize {
  180. error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
  181. return Err(Error::new(ErrorKind::Other, res_data.to_string()));
  182. }
  183. let value = list[0].clone();
  184. Ok(Ticker{
  185. time: chrono::Utc::now().timestamp_millis(),
  186. high: value.high_price24h,
  187. low: value.low_price24h,
  188. sell: value.ask1_price,
  189. buy: value.bid1_price,
  190. last: value.last_price,
  191. volume: value.volume24h
  192. })
  193. } else {
  194. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  195. }
  196. }
  197. async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
  198. let symbol_upper = symbol.replace("_", "").to_uppercase();
  199. let res_data = self.request.get_tickers(symbol_upper.clone()).await;
  200. if res_data.code == "200" {
  201. let res_data_str = &res_data.data;
  202. let arr: Value = from_str(res_data_str).unwrap();
  203. let list :Vec<SwapTicker> = from_value(arr["list"].clone()).unwrap();
  204. let ticker_info = list.iter().find(|&item| item.symbol == symbol_upper);
  205. match ticker_info {
  206. None => {
  207. error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
  208. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  209. }
  210. Some(value) => {
  211. let result = Ticker {
  212. time: chrono::Utc::now().timestamp_millis(),
  213. high: value.high_price24h,
  214. low: value.low_price24h,
  215. sell: value.ask1_price,
  216. buy: value.bid1_price,
  217. last: value.last_price,
  218. volume: value.volume24h
  219. };
  220. Ok(result)
  221. }
  222. }
  223. } else {
  224. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  225. }
  226. }
  227. async fn get_market(&mut self) -> Result<Market, Error> {
  228. let symbol = self.symbol_uppercase.clone();
  229. let res_data = self.request.get_instruments_info(symbol.clone()).await;
  230. if res_data.code == "200" {
  231. let res_data_str = res_data.data.clone();
  232. let res_data_json: Value = from_str(res_data_str.as_str()).unwrap();
  233. let arr_data: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
  234. let market_info = arr_data.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol);
  235. match market_info {
  236. None => {
  237. error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
  238. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  239. }
  240. Some(value) => {
  241. let base_coin = value["baseCoin"].as_str().unwrap();
  242. let quote_coin = value["quoteCoin"].as_str().unwrap();
  243. let name = format!("{}_{}",base_coin, quote_coin);
  244. let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
  245. let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
  246. let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
  247. let ct_val = Decimal::ONE;
  248. let amount_size = min_qty * ct_val;
  249. let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
  250. let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
  251. let min_notional = min_qty * ct_val;
  252. let max_notional = max_qty * ct_val;
  253. let result = Market {
  254. symbol: name,
  255. base_asset: base_coin.to_string(),
  256. quote_asset: quote_coin.to_string(),
  257. tick_size,
  258. amount_size,
  259. price_precision,
  260. amount_precision,
  261. min_qty,
  262. max_qty,
  263. min_notional,
  264. max_notional,
  265. ct_val,
  266. };
  267. Ok(result)
  268. }
  269. }
  270. } else {
  271. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  272. }
  273. }
  274. async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
  275. let symbol = symbol.replace("_", "").to_uppercase();
  276. let res_data = self.request.get_instruments_info(symbol.clone()).await;
  277. if res_data.code == "200" {
  278. let res_data_str = &res_data.data;
  279. let res_data_json: Value = from_str(res_data_str.as_str()).unwrap();
  280. let arr_data: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
  281. let market_info = arr_data.iter().find(|item| item["symbol"].as_str().unwrap() == symbol);
  282. match market_info {
  283. None => {
  284. error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
  285. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  286. }
  287. Some(value) => {
  288. let base_coin = value["baseCoin"].as_str().unwrap();
  289. let quote_coin = value["quoteCoin"].as_str().unwrap();
  290. let name = format!("{}_{}",base_coin, quote_coin);
  291. let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
  292. let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
  293. let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
  294. let ct_val = Decimal::ONE;
  295. let amount_size = min_qty * ct_val;
  296. let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
  297. let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
  298. let min_notional = min_qty * ct_val;
  299. let max_notional = max_qty * ct_val;
  300. let result = Market {
  301. symbol: name,
  302. base_asset: base_coin.to_string(),
  303. quote_asset: quote_coin.to_string(),
  304. tick_size,
  305. amount_size,
  306. price_precision,
  307. amount_precision,
  308. min_qty,
  309. max_qty,
  310. min_notional,
  311. max_notional,
  312. ct_val,
  313. };
  314. Ok(result)
  315. }
  316. }
  317. } else {
  318. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  319. }
  320. }
  321. // 获取订单详情
  322. async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
  323. let symbol = self.symbol_uppercase.clone();
  324. let ct_val = self.market.ct_val;
  325. let id = if !custom_id.trim().eq("") { format!("t-{}", custom_id) } else { String::new() };
  326. let res_data = self.request.get_order(symbol, order_id.parse().unwrap(), id).await;
  327. if res_data.code == "200" {
  328. let res_data_str = &res_data.data;
  329. let res_data_json: Value = from_str::<Value>(res_data_str).unwrap()["list"].clone();
  330. if res_data_json.is_array() && res_data_json.as_array().unwrap().len() == 0 {
  331. return Err(Error::new(ErrorKind::Other, "没有该订单!"));
  332. }
  333. let result = format_order_item(res_data_json.as_array().unwrap()[0].clone(), ct_val);
  334. Ok(result)
  335. } else {
  336. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  337. }
  338. }
  339. // 获取订单列表
  340. async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
  341. Err(Error::new(ErrorKind::Other, "bybit获取订单列表暂未实现".to_string()))
  342. }
  343. // 下单接口
  344. async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
  345. let symbol = self.symbol_uppercase.clone();
  346. let ct_val = self.market.ct_val;
  347. let size = (amount / ct_val).floor();
  348. let mut params = json!({
  349. "orderLinkId": format!("t-{}", custom_id),
  350. "symbol": symbol.to_string(),
  351. "price": price.to_string(),
  352. "category": "linear",
  353. "orderType":"Limit",
  354. "qty": json!(size),
  355. // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
  356. "positionIdx": json!(1),
  357. "reduceOnly": json!(false)
  358. });
  359. if price.eq(&Decimal::ZERO) {
  360. params["timeInForce"] = json!("IOC".to_string());
  361. }
  362. match origin_side {
  363. "kd" => {
  364. params["side"] = json!("Buy");
  365. }
  366. "pd" => {
  367. params["side"] = json!("Sell");
  368. // 减仓
  369. params["reduceOnly"] = json!(true);
  370. }
  371. "kk" => {
  372. params["side"] = json!("Sell");
  373. params["positionIdx"] = json!(2);
  374. }
  375. "pk" => {
  376. params["side"] = json!("Buy");
  377. // 减仓
  378. params["reduceOnly"] = json!(true);
  379. params["positionIdx"] = json!(2);
  380. }
  381. _ => { error!("下单参数错误"); }
  382. };
  383. let res_data = self.request.swap_order(params).await;
  384. if res_data.code == "200" {
  385. let res_data_str = &res_data.data;
  386. let res_data_json: Value = from_str(res_data_str).unwrap();
  387. let result = format_new_order_item(res_data_json, price, size);
  388. Ok(result)
  389. } else {
  390. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  391. }
  392. }
  393. 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> {
  394. let symbol_upper = symbol.replace("_", "").trim().to_uppercase();
  395. let size = (amount / ct_val).floor();
  396. let mut params = json!({
  397. "orderLinkId": format!("t-{}", custom_id),
  398. "symbol": symbol_upper,
  399. "price": price.to_string(),
  400. "category": "linear",
  401. "orderType":"Limit",
  402. "qty": json!(size),
  403. // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
  404. "positionIdx": json!(1),
  405. "reduceOnly": json!(false)
  406. });
  407. if price.eq(&Decimal::ZERO) {
  408. params["timeInForce"] = json!("IOC".to_string());
  409. }
  410. match origin_side {
  411. "kd" => {
  412. params["side"] = json!("Buy");
  413. }
  414. "pd" => {
  415. params["side"] = json!("Sell");
  416. params["positionIdx"] = json!(1);
  417. // 减仓
  418. params["reduceOnly"] = json!(true);
  419. }
  420. "kk" => {
  421. params["side"] = json!("Sell");
  422. params["positionIdx"] = json!(2);
  423. }
  424. "pk" => {
  425. params["side"] = json!("Buy");
  426. params["positionIdx"] = json!(2);
  427. // 减仓
  428. params["reduceOnly"] = json!(true);
  429. }
  430. _ => { error!("下单参数错误"); }
  431. };
  432. let res_data = self.request.swap_order(params.clone()).await;
  433. if res_data.code == "200" {
  434. let res_data_str = &res_data.data;
  435. let res_data_json: Value = from_str(res_data_str).unwrap();
  436. let result = format_new_order_item(res_data_json, price, size);
  437. Ok(result)
  438. } else {
  439. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  440. }
  441. }
  442. // 撤销订单
  443. async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
  444. let symbol = self.symbol_uppercase.clone();
  445. let id = format!("t-{}", custom_id);
  446. let res_data = self.request.cancel_order(symbol, String::from(order_id), id.clone()).await;
  447. if res_data.code == "200" {
  448. let res_data_str = &res_data.data;
  449. let res_data_json: Value = from_str(res_data_str).unwrap();
  450. let result = format_cancel_order_item(res_data_json);
  451. Ok(result)
  452. } else {
  453. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  454. }
  455. }
  456. // 批量撤销订单
  457. async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
  458. let symbol = self.symbol_uppercase.clone();
  459. let res_data = self.request.cancel_orders(symbol).await;
  460. if res_data.code == "200" {
  461. let res_data_str = &res_data.data;
  462. let res_data_json: Value = from_str(res_data_str).unwrap();
  463. let res_arr: Vec<Value> = from_value(res_data_json).unwrap();
  464. let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
  465. Ok(result)
  466. } else {
  467. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  468. }
  469. }
  470. async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
  471. let symbol = self.symbol_uppercase.clone();
  472. let res_data = self.request.cancel_orders(symbol).await;
  473. if res_data.code == "200" {
  474. let res_data_str = &res_data.data;
  475. let res_data_json: Value = from_str(res_data_str).unwrap();
  476. let res_arr: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
  477. let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
  478. Ok(result)
  479. } else {
  480. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  481. }
  482. }
  483. // 设置持仓模式
  484. async fn set_dual_mode(&mut self, _coin: &str, is_dual_mode: bool) -> Result<String, Error> {
  485. let coin_format = self.symbol_uppercase.clone();
  486. let mut mod_num = 0;
  487. if is_dual_mode {
  488. mod_num = 3;
  489. }
  490. let res_data = self.request.set_position_mode(coin_format, mod_num).await;
  491. if res_data.code == "200" {
  492. let res_data_str = &res_data.data;
  493. let result = res_data_str.clone();
  494. Ok(result)
  495. } else {
  496. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  497. }
  498. }
  499. // 更新双持仓模式下杠杆
  500. async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
  501. let symbol = self.symbol_uppercase.clone();
  502. let res_data = self.request.set_leverage(symbol, leverage.to_string()).await;
  503. if res_data.code == "200" {
  504. let res_data_str = &res_data.data;
  505. let result = res_data_str.clone();
  506. Ok(result)
  507. } else {
  508. Err(Error::new(ErrorKind::Other, res_data.to_string()))
  509. }
  510. }
  511. async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate:该交易所方法未实现".to_string())) }
  512. // 交易账户互转
  513. async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
  514. // let coin_format = coin.to_string().to_lowercase();
  515. // let res_data = self.request.wallet_transfers(coin_format.clone(), from.to_string(), to.to_string(), amount.to_string(), coin_format.clone()).await;
  516. // if res_data.code == "200" {
  517. // let res_data_str = &res_data.data;
  518. // let result = res_data_str.clone();
  519. // Ok(result)
  520. // } else {
  521. // Err(Error::new(ErrorKind::Other, res_data.to_string()))
  522. // }
  523. Err(Error::new(ErrorKind::Other, "暂未实现!"))
  524. }
  525. // 指令下单
  526. async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
  527. let mut handles = vec![];
  528. // 撤销订单
  529. let cancel = order_command.cancel;
  530. for item in cancel.keys() {
  531. let mut self_clone = self.clone();
  532. let cancel_clone = cancel.clone();
  533. let item_clone = item.clone();
  534. let order_id = cancel_clone.get(&item_clone).unwrap().get(1).unwrap_or(&"".to_string()).clone();
  535. let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
  536. let result_sd = self.order_sender.clone();
  537. let err_sd = self.error_sender.clone();
  538. let handle = tokio::spawn(async move {
  539. let result = self_clone.cancel_order(&order_id, &custom_id).await;
  540. match result {
  541. Ok(_) => {
  542. // result_sd.send(result).await.unwrap();
  543. }
  544. Err(error) => {
  545. // 取消失败去查订单。
  546. let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
  547. match query_rst {
  548. Ok(order) => {
  549. result_sd.unwrap().send(order).await.unwrap();
  550. }
  551. Err(_err) => {
  552. // error!("撤单失败,而且查单也失败了,bybit_io_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
  553. // panic!("撤单失败,而且查单也失败了,bybit_io_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
  554. }
  555. }
  556. err_sd.unwrap().send(error).await.unwrap();
  557. }
  558. }
  559. });
  560. handles.push(handle)
  561. }
  562. // 下单指令
  563. let mut limits = HashMap::new();
  564. limits.extend(order_command.limits_open);
  565. limits.extend(order_command.limits_close);
  566. for item in limits.keys() {
  567. let mut self_clone = self.clone();
  568. let limits_clone = limits.clone();
  569. let item_clone = item.clone();
  570. let result_sd = self.order_sender.clone();
  571. let err_sd = self.error_sender.clone();
  572. let mut ts = trace_stack.clone();
  573. let handle = tokio::spawn(async move {
  574. let value = limits_clone[&item_clone].clone();
  575. let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
  576. let side = value.get(1).unwrap();
  577. let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
  578. let cid = value.get(3).unwrap();
  579. // order_name: [数量,方向,价格,c_id]
  580. let result = self_clone.take_order(cid, side, price, amount).await;
  581. match result {
  582. Ok(mut result) => {
  583. // 记录此订单完成时间
  584. ts.on_after_send();
  585. result.trace_stack = ts;
  586. result_sd.unwrap().send(result).await.unwrap();
  587. }
  588. Err(error) => {
  589. let mut err_order = Order::new();
  590. err_order.custom_id = cid.clone();
  591. err_order.status = "REMOVE".to_string();
  592. result_sd.unwrap().send(err_order).await.unwrap();
  593. err_sd.unwrap().send(error).await.unwrap();
  594. }
  595. }
  596. });
  597. handles.push(handle)
  598. }
  599. // 检查订单指令
  600. let check = order_command.check;
  601. for item in check.keys() {
  602. let mut self_clone = self.clone();
  603. let check_clone = check.clone();
  604. let item_clone = item.clone();
  605. let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
  606. let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
  607. let result_sd = self.order_sender.clone();
  608. let err_sd = self.error_sender.clone();
  609. let handle = tokio::spawn(async move {
  610. let result = self_clone.get_order_detail(&order_id, &custom_id).await;
  611. match result {
  612. Ok(result) => {
  613. result_sd.unwrap().send(result).await.unwrap();
  614. }
  615. Err(error) => {
  616. err_sd.unwrap().send(error).await.unwrap();
  617. }
  618. }
  619. });
  620. handles.push(handle)
  621. }
  622. let futures = FuturesUnordered::from_iter(handles);
  623. let _: Result<Vec<_>, _> = futures.try_collect().await;
  624. }
  625. }
  626. pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
  627. let position_idx = position["positionIdx"].to_string();
  628. let mut position_mode = match position_idx.as_str() {
  629. "0" => PositionModeEnum::Both,
  630. "1" => PositionModeEnum::Long,
  631. "2" => PositionModeEnum::Short,
  632. _ => {
  633. error!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
  634. panic!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
  635. }
  636. };
  637. let size_str: String = from_value(position["size"].clone()).unwrap();
  638. let size = Decimal::from_str(size_str.as_str()).unwrap();
  639. let amount = size * ct_val;
  640. let mut profit = Decimal::ZERO;
  641. let profit_str = position["unrealisedPnl"].as_str().unwrap_or("0");
  642. if profit_str != "" {
  643. profit = Decimal::from_str(profit_str).unwrap();
  644. }
  645. match position_mode {
  646. PositionModeEnum::Both => {
  647. position_mode = match amount {
  648. amount if amount > Decimal::ZERO => PositionModeEnum::Long,
  649. amount if amount < Decimal::ZERO => PositionModeEnum::Short,
  650. _ => { PositionModeEnum::Both }
  651. }
  652. }
  653. _ => {}
  654. }
  655. Position {
  656. symbol: position["symbol"].as_str().unwrap_or("").parse().unwrap(),
  657. margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
  658. amount,
  659. frozen_amount: Decimal::ZERO,
  660. price: Decimal::from_str(position["avgPrice"].as_str().unwrap()).unwrap(),
  661. profit,
  662. position_mode,
  663. margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
  664. }
  665. }
  666. fn format_cancel_order_item(order: Value) -> Order {
  667. Order {
  668. id: format!("{}", order["orderId"].as_str().unwrap()),
  669. custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
  670. price: Decimal::ZERO,
  671. amount: Decimal::ZERO,
  672. deal_amount: Decimal::ZERO,
  673. avg_price: Decimal::ZERO,
  674. status: "REMOVE".to_string(),
  675. order_type: "limit".to_string(),
  676. trace_stack: TraceStack::default().on_special("688 trace_stack".to_string())
  677. }
  678. }
  679. fn format_new_order_item(order: Value, price: Decimal, amount: Decimal) -> Order {
  680. Order {
  681. id: format!("{}", order["orderId"].as_str().unwrap()),
  682. custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
  683. price,
  684. amount,
  685. deal_amount: Decimal::ZERO,
  686. avg_price: price,
  687. status: "NEW".to_string(),
  688. order_type: "limit".to_string(),
  689. trace_stack: TraceStack::default().on_special("688 trace_stack".to_string())
  690. }
  691. }
  692. pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
  693. debug!("format-order-start, bybit_swap");
  694. debug!(?order);
  695. let status = order["orderStatus"].as_str().unwrap_or("");
  696. let text = order["orderLinkId"].as_str().unwrap_or("");
  697. let mut size = Decimal::ZERO;
  698. let mut deal_amount = Decimal::ZERO;
  699. let mut avg_price = Decimal::ZERO;
  700. let right_str = order["cumExecQty"].to_string();
  701. let size_str = order["qty"].to_string();
  702. if !order.get("qty").is_some() {
  703. size = Decimal::from_str(size_str.as_str()).unwrap();
  704. let right_val = Decimal::from_str(order["cumExecValue"].as_str().unwrap()).unwrap();
  705. let right = Decimal::from_str(right_str.as_str()).unwrap();
  706. if right != Decimal::ZERO {
  707. avg_price = right_val / right;
  708. }
  709. deal_amount = right * ct_val;
  710. }
  711. let amount = size * ct_val;
  712. let custom_status = if status == "Filled" || status == "Cancelled" { "REMOVE".to_string() } else if status == "New" { "NEW".to_string() } else {
  713. "NULL".to_string()
  714. };
  715. let rst_order = Order {
  716. id: format!("{}", order["orderId"].as_str().unwrap()),
  717. custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
  718. price: Decimal::from_str(order["price"].as_str().unwrap()).unwrap(),
  719. amount,
  720. deal_amount,
  721. avg_price,
  722. status: custom_status,
  723. order_type: "limit".to_string(),
  724. trace_stack: TraceStack::default().on_special("688 trace_stack".to_string()),
  725. };
  726. debug!(?rst_order);
  727. debug!("format-order-end, bybit_swap");
  728. return rst_order;
  729. }