gate_swap.rs 34 KB

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