handle_info.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. use std::cmp::Ordering;
  2. use std::str::FromStr;
  3. use rust_decimal::{Decimal};
  4. use rust_decimal::prelude::FromPrimitive;
  5. use rust_decimal_macros::dec;
  6. use tracing::{error, info};
  7. use exchanges::response_base::ResponseData;
  8. use global::public_params;
  9. use crate::exchange::ExchangeEnum;
  10. use crate::{binance_swap_handle, gate_swap_handle, bybit_swap_handle, bitget_swap_handle, kucoin_handle, coinex_swap_handle, htx_swap_handle};
  11. use crate::{Account, MarketOrder, Position, SpecialDepth, SpecialOrder, SpecialTicker};
  12. #[allow(dead_code)]
  13. pub struct HandleSwapInfo;
  14. #[derive(Debug, Clone, PartialEq, Eq)]
  15. pub struct DepthParam {
  16. pub depth_asks: Vec<MarketOrder>,
  17. pub depth_bids: Vec<MarketOrder>,
  18. pub t: Decimal,
  19. pub create_at: i64
  20. }
  21. #[allow(dead_code)]
  22. impl HandleSwapInfo {
  23. // 处理账号信息
  24. pub fn handle_account_info(exchange: ExchangeEnum, res_data: &ResponseData, symbol: &String) -> Account {
  25. match exchange {
  26. // ExchangeEnum::BinanceSwap => {
  27. // error!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
  28. // panic!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
  29. // }
  30. ExchangeEnum::GateSwap => {
  31. gate_swap_handle::handle_account_info(res_data, symbol)
  32. }
  33. // ExchangeEnum::KucoinSwap => {
  34. // kucoin_handle::handle_account_info(res_data, symbol)
  35. // }
  36. // ExchangeEnum::KucoinSpot => {
  37. // kucoin_spot_handle::handle_account_info(res_data, symbol)
  38. // }
  39. // ExchangeEnum::OkxSwap => {
  40. // okx_handle::handle_account_info(res_data, symbol)
  41. // }
  42. // ExchangeEnum::BitgetSpot => {
  43. // bitget_spot_handle::handle_account_info(res_data, symbol)
  44. // },
  45. ExchangeEnum::BitgetSwap => {
  46. bitget_swap_handle::handle_account_info(res_data, symbol)
  47. },
  48. ExchangeEnum::BybitSwap => {
  49. bybit_swap_handle::handle_account_info(res_data, symbol)
  50. }
  51. ExchangeEnum::CoinexSwap => {
  52. coinex_swap_handle::handle_account_info(res_data, symbol)
  53. }
  54. ExchangeEnum::HtxSwap => {
  55. htx_swap_handle::handle_account_info(res_data, symbol)
  56. }
  57. _ => {
  58. error!("未找到该交易所!handle_account_info: {:?}",exchange);
  59. panic!("未找到该交易所!handle_account_info: {:?}", exchange);
  60. }
  61. }
  62. }
  63. // 处理特殊Ticket信息
  64. pub fn handle_book_ticker(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
  65. match exchange {
  66. // ExchangeEnum::BinanceSpot => {
  67. // binance_spot_handle::handle_special_ticker(res_data)
  68. // }
  69. ExchangeEnum::BinanceSwap => {
  70. binance_swap_handle::handle_book_ticker(res_data)
  71. }
  72. ExchangeEnum::GateSwap => {
  73. gate_swap_handle::handle_book_ticker(res_data)
  74. }
  75. ExchangeEnum::KucoinSwap => {
  76. kucoin_handle::handle_book_ticker(res_data)
  77. }
  78. // ExchangeEnum::KucoinSpot => {
  79. // kucoin_spot_handle::handle_special_ticker(res_data)
  80. // }
  81. // ExchangeEnum::KucoinSpot => {
  82. // kucoin_spot_handle::handle_special_ticker(res_data)
  83. // }
  84. // ExchangeEnum::OkxSwap => {
  85. // okx_handle::handle_special_ticker(res_data)
  86. // }
  87. // ExchangeEnum::BitgetSpot => {
  88. // bitget_spot_handle::handle_special_ticker(res_data)
  89. // },
  90. ExchangeEnum::BitgetSwap => {
  91. info!(?res_data);
  92. panic!("BitgetSwap 85 未实现格式化");
  93. // bitget_swap_handle::handle_special_ticker(res_data)
  94. },
  95. ExchangeEnum::BybitSwap => {
  96. bybit_swap_handle::handle_ticker(res_data)
  97. }
  98. ExchangeEnum::CoinexSwap => {
  99. coinex_swap_handle::handle_ticker(res_data)
  100. }
  101. ExchangeEnum::HtxSwap => {
  102. SpecialDepth::new()
  103. // htx_swap_handle::handle_ticker(res_data)
  104. }
  105. }
  106. }
  107. // 处理position信息
  108. pub fn handle_position(exchange: ExchangeEnum, res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
  109. match exchange {
  110. ExchangeEnum::BinanceSwap => {
  111. error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
  112. panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
  113. }
  114. ExchangeEnum::GateSwap => {
  115. gate_swap_handle::handle_position(res_data, ct_val)
  116. }
  117. ExchangeEnum::KucoinSwap => {
  118. kucoin_handle::handle_position(res_data, ct_val)
  119. }
  120. // ExchangeEnum::KucoinSpot => {
  121. // error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
  122. // panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
  123. // }
  124. // ExchangeEnum::OkxSwap => {
  125. // okx_handle::handle_position(res_data, ct_val)
  126. // }
  127. // ExchangeEnum::BitgetSpot => {
  128. // error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
  129. // panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
  130. // },
  131. ExchangeEnum::BitgetSwap => {
  132. bitget_swap_handle::handle_position(res_data, ct_val)
  133. },
  134. ExchangeEnum::BybitSwap => {
  135. bybit_swap_handle::handle_position(res_data, ct_val)
  136. }
  137. ExchangeEnum::CoinexSwap => {
  138. coinex_swap_handle::handle_position(res_data, ct_val)
  139. }
  140. ExchangeEnum::HtxSwap => {
  141. htx_swap_handle::handle_position(res_data, ct_val)
  142. }
  143. }
  144. }
  145. // 处理订单信息
  146. pub fn handle_order(exchange: ExchangeEnum, res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
  147. match exchange {
  148. ExchangeEnum::BinanceSwap => {
  149. error!("暂未提供此交易所方法!handle_order:{:?}", exchange);
  150. panic!("暂未提供此交易所方法!handle_order:{:?}", exchange);
  151. }
  152. ExchangeEnum::GateSwap => {
  153. gate_swap_handle::handle_order(res_data, ct_val)
  154. }
  155. ExchangeEnum::KucoinSwap => {
  156. kucoin_handle::handle_order(res_data, ct_val)
  157. }
  158. // ExchangeEnum::KucoinSpot => {
  159. // kucoin_spot_handle::handle_order(res_data, ct_val)
  160. // }
  161. // ExchangeEnum::OkxSwap => {
  162. // okx_handle::handle_order(res_data, ct_val)
  163. // }
  164. // ExchangeEnum::BitgetSpot => {
  165. // bitget_spot_handle::handle_order(res_data, ct_val)
  166. // },
  167. ExchangeEnum::BitgetSwap => {
  168. bitget_swap_handle::handle_order(res_data, ct_val)
  169. },
  170. ExchangeEnum::BybitSwap => {
  171. bybit_swap_handle::handle_order(res_data, ct_val)
  172. }
  173. ExchangeEnum::CoinexSwap => {
  174. coinex_swap_handle::handle_order(res_data, ct_val)
  175. }
  176. ExchangeEnum::HtxSwap => {
  177. htx_swap_handle::handle_order(res_data, ct_val)
  178. }
  179. }
  180. }
  181. // 处理深度信息
  182. pub fn handle_special_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
  183. let label = res_data.label.clone();
  184. // 格式化
  185. let mut format_depth = format_depth(exchange, res_data);
  186. // 运算、组装
  187. make_special_depth(label, &mut format_depth.depth_asks, &mut format_depth.depth_bids, format_depth.t, format_depth.create_at)
  188. }
  189. }
  190. pub fn make_special_depth(label: String, depth_asks: &mut Vec<MarketOrder>, depth_bids: &mut Vec<MarketOrder>, t: Decimal, create_at: i64) -> SpecialDepth {
  191. depth_asks.sort_by(|a, b| a.price.partial_cmp(&b.price).unwrap_or(Ordering::Equal));
  192. depth_bids.sort_by(|a, b| b.price.partial_cmp(&a.price).unwrap_or(Ordering::Equal));
  193. // TODO 不排序的话,有4us可以省下来。
  194. let mp = (depth_asks[0].price + depth_bids[0].price) * dec!(0.5);
  195. let step = (public_params::EFF_RANGE * mp / Decimal::from_usize(public_params::LEVEL).unwrap()).round_dp(mp.scale());
  196. let mut ap = Vec::new();
  197. let mut bp = Vec::new();
  198. let mut av: Vec<Decimal> = Vec::new();
  199. let mut bv: Vec<Decimal> = Vec::new();
  200. for i in 0..public_params::LEVEL {
  201. let price = (depth_asks[0].price + step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_asks[0].price.scale());
  202. ap.push(price);
  203. }
  204. for i in 0..public_params::LEVEL {
  205. let price = (depth_bids[0].price - step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_bids[0].price.scale());
  206. bp.push(price);
  207. }
  208. let mut ap_price_tag = depth_asks[0].price + step;
  209. let mut ap_index = 0;
  210. for item in depth_asks.iter() {
  211. let price = item.price;
  212. let amount = item.amount;
  213. if av.get(ap_index).is_none() { av.push(Decimal::ZERO) };
  214. if price < ap_price_tag {
  215. av[ap_index] += amount;
  216. } else {
  217. ap_price_tag += step;
  218. ap_index += 1;
  219. if ap_index == public_params::LEVEL {
  220. break;
  221. }
  222. av[ap_index] += amount
  223. }
  224. }
  225. let mut bp_price_tag = depth_bids[0].price - step;
  226. let mut bp_index = 0;
  227. for item in depth_bids.iter() {
  228. let price = item.price;
  229. let amount = item.amount;
  230. if bv.get(bp_index).is_none() { bv.push(Decimal::ZERO) };
  231. if price > bp_price_tag {
  232. bv[bp_index] += amount;
  233. } else {
  234. bp_price_tag -= step;
  235. bp_index += 1;
  236. if bp_index == public_params::LEVEL {
  237. break;
  238. }
  239. bv[bp_index] += amount
  240. }
  241. }
  242. let ticker_info = SpecialTicker { sell: depth_asks[0].price, buy: depth_bids[0].price, mid_price: mp, t, create_at };
  243. let depth_info = bp.iter().cloned().chain(bv.iter().cloned()).chain(ap.iter().cloned()).chain(av.iter().cloned()).collect();
  244. SpecialDepth {
  245. name: label,
  246. depth: depth_info,
  247. ticker: ticker_info,
  248. t,
  249. create_at,
  250. }
  251. }
  252. pub fn format_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> DepthParam {
  253. let depth_asks: Vec<MarketOrder>;
  254. let depth_bids: Vec<MarketOrder>;
  255. let t: Decimal;
  256. let create_at: i64;
  257. match exchange {
  258. // ExchangeEnum::BinanceSpot => {
  259. // depth_asks = binance_swap_handle::format_depth_items(res_data_json["asks"].clone());
  260. // depth_bids = binance_swap_handle::format_depth_items(res_data_json["bids"].clone());
  261. // t = Decimal::from_str(&res_data_json["lastUpdateId"].to_string()).unwrap();
  262. // create_at = 0;
  263. // }
  264. ExchangeEnum::BinanceSwap => {
  265. depth_asks = binance_swap_handle::format_depth_items(res_data.data["a"].clone());
  266. depth_bids = binance_swap_handle::format_depth_items(res_data.data["b"].clone());
  267. t = Decimal::from_str(&res_data.data["u"].to_string()).unwrap();
  268. create_at = res_data.data["E"].as_i64().unwrap() * 1000;
  269. }
  270. ExchangeEnum::GateSwap => {
  271. depth_asks = gate_swap_handle::format_depth_items(&res_data.data["asks"]);
  272. depth_bids = gate_swap_handle::format_depth_items(&res_data.data["bids"]);
  273. // todo! 有id可以取 保证与py一致
  274. t = Decimal::from_str(&res_data.data["t"].to_string()).unwrap();
  275. create_at = res_data.data["t"].as_i64().unwrap() * 1000;
  276. }
  277. ExchangeEnum::KucoinSwap => {
  278. depth_asks = kucoin_handle::format_depth_items(res_data.data["asks"].clone());
  279. depth_bids = kucoin_handle::format_depth_items(res_data.data["bids"].clone());
  280. t = Decimal::from_str(&res_data.data["sequence"].to_string()).unwrap();
  281. create_at = res_data.data["ts"].as_i64().unwrap() * 1000;
  282. }
  283. // ExchangeEnum::KucoinSpot => {
  284. // depth_asks = kucoin_spot_handle::format_depth_items(res_data_json["asks"].clone());
  285. // depth_bids = kucoin_spot_handle::format_depth_items(res_data_json["bids"].clone());
  286. // t = Decimal::from_str(&res_data_json["timestamp"].to_string()).unwrap();
  287. // create_at = res_data_json["timestamp"].as_i64().unwrap() * 1000;
  288. // }
  289. // ExchangeEnum::OkxSwap => {
  290. // depth_asks = okx_handle::format_depth_items(res_data_json[0]["asks"].clone());
  291. // depth_bids = okx_handle::format_depth_items(res_data_json[0]["bids"].clone());
  292. // t = Decimal::from_str(&res_data_json[0]["seqId"].to_string()).unwrap();
  293. // create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
  294. // }
  295. // ExchangeEnum::BitgetSpot => {
  296. // depth_asks = bitget_spot_handle::format_depth_items(res_data_json[0]["asks"].clone());
  297. // depth_bids = bitget_spot_handle::format_depth_items(res_data_json[0]["bids"].clone());
  298. // t = Decimal::from_str(res_data_json[0]["ts"].as_str().unwrap()).unwrap();
  299. // create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
  300. // }
  301. ExchangeEnum::BitgetSwap => {
  302. depth_asks = bitget_swap_handle::format_depth_items(res_data.data[0]["asks"].clone());
  303. depth_bids = bitget_swap_handle::format_depth_items(res_data.data[0]["bids"].clone());
  304. t = Decimal::from_str(res_data.data[0]["ts"].as_str().unwrap()).unwrap();
  305. create_at = res_data.data[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
  306. }
  307. ExchangeEnum::BybitSwap => {
  308. depth_asks = bybit_swap_handle::format_depth_items(res_data.data["a"].clone());
  309. depth_bids = bybit_swap_handle::format_depth_items(res_data.data["b"].clone());
  310. t = Decimal::from_i64(res_data.reach_time).unwrap();
  311. create_at = res_data.reach_time * 1000;
  312. },
  313. ExchangeEnum::CoinexSwap => {
  314. let depth = &res_data.data["depth"];
  315. depth_asks = coinex_swap_handle::format_depth_items(&depth["asks"].clone());
  316. depth_bids = coinex_swap_handle::format_depth_items(&depth["bids"].clone());
  317. let time = depth.get("updated_at").unwrap().as_i64().unwrap_or(0i64);
  318. t = Decimal::from_i64(time).unwrap();
  319. create_at = time * 1000;
  320. }
  321. ExchangeEnum::HtxSwap => {
  322. let depth = &res_data.data;
  323. depth_asks = htx_swap_handle::format_depth_items(depth["asks"].clone());
  324. depth_bids = htx_swap_handle::format_depth_items(depth["bids"].clone());
  325. let time = depth["ts"].to_string().parse::<i64>().unwrap();
  326. t = Decimal::from_i64(time).unwrap();
  327. create_at = time * 1000;
  328. }
  329. }
  330. DepthParam {
  331. depth_asks,
  332. depth_bids,
  333. t,
  334. create_at
  335. }
  336. }