handle_info.rs 13 KB

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