gate_swap.rs 33 KB

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