bybit_swap.rs 33 KB

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