gate_swap.rs 32 KB

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