gate_swap_handle.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. use std::str::FromStr;
  2. use rust_decimal::{Decimal};
  3. use rust_decimal::prelude::FromPrimitive;
  4. use rust_decimal_macros::dec;
  5. use serde_json::Value;
  6. use tokio::time::Instant;
  7. use tracing::{error};
  8. use exchanges::response_base::ResponseData;
  9. use global::trace_stack::TraceStack;
  10. use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
  11. // 处理账号信息
  12. pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account {
  13. let res_data_json = res_data.data.as_array().unwrap();
  14. format_account_info(res_data_json, symbol)
  15. }
  16. pub fn format_account_info(data: &Vec<Value>, symbol: &String) -> Account {
  17. let symbol_upper = symbol.to_uppercase();
  18. let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
  19. let balance_info = data.iter().find(|&item| item["text"].as_str().unwrap().contains(&symbol_upper));
  20. match balance_info {
  21. None => {
  22. error!("Gate:格式化账号信息错误!\nformat_account_info: data={:?}", data);
  23. panic!("Gate:格式化账号信息错误!\nformat_account_info: data={:?}", data)
  24. }
  25. Some(value) => {
  26. let balance = Decimal::from_str(&value["balance"].as_f64().unwrap().to_string()).unwrap();
  27. Account {
  28. coin: symbol_array[1].to_string(),
  29. balance,
  30. available_balance: Decimal::ZERO,
  31. frozen_balance: Decimal::ZERO,
  32. stocks: Decimal::ZERO,
  33. available_stocks: Decimal::ZERO,
  34. frozen_stocks: Decimal::ZERO,
  35. }
  36. }
  37. }
  38. }
  39. // 处理position信息
  40. pub fn handle_position(res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
  41. let res_data_json = res_data.data.as_array().unwrap();
  42. res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect()
  43. }
  44. pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
  45. let mut position_mode = match position["mode"].as_str().unwrap_or("") {
  46. "single" => PositionModeEnum::Both,
  47. "dual_long" => PositionModeEnum::Long,
  48. "dual_short" => PositionModeEnum::Short,
  49. _ => {
  50. error!("Gate:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
  51. panic!("Gate:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
  52. }
  53. };
  54. let size = Decimal::from_str(&position["size"].as_f64().unwrap().to_string()).unwrap();
  55. let amount = size * ct_val;
  56. match position_mode {
  57. PositionModeEnum::Both => {
  58. position_mode = match amount {
  59. amount if amount > Decimal::ZERO => PositionModeEnum::Long,
  60. amount if amount < Decimal::ZERO => PositionModeEnum::Short,
  61. _ => { PositionModeEnum::Both }
  62. }
  63. }
  64. _ => {}
  65. }
  66. Position {
  67. symbol: position["contract"].as_str().unwrap().to_string(),
  68. margin_level: Decimal::from_str(&position["leverage"].as_f64().unwrap().to_string()).unwrap(),
  69. amount,
  70. frozen_amount: Decimal::ZERO,
  71. price: Decimal::from_str(&position["entry_price"].as_f64().unwrap().to_string()).unwrap(),
  72. profit: Decimal::from_str(&position["realised_pnl"].as_f64().unwrap().to_string()).unwrap(),
  73. position_mode,
  74. margin: Decimal::from_str(&position["margin"].as_f64().unwrap().to_string()).unwrap(),
  75. }
  76. }
  77. // 处理order信息
  78. pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
  79. let res_data_json = res_data.data.as_array().unwrap();
  80. let mut order_info = Vec::new();
  81. for item in res_data_json.iter() {
  82. order_info.push(format_order_item(item.clone(), ct_val));
  83. };
  84. SpecialOrder {
  85. name: res_data.label,
  86. order: order_info,
  87. }
  88. }
  89. pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
  90. let status = order["status"].as_str().unwrap_or("");
  91. let text = order["text"].as_str().unwrap_or("");
  92. let size = Decimal::from_f64(order["size"].as_f64().unwrap()).unwrap();
  93. let left = Decimal::from_f64(order["left"].as_f64().unwrap()).unwrap();
  94. let amount = size * ct_val;
  95. let deal_amount = (size - left) * ct_val;
  96. let custom_status = if status == "finished" { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else {
  97. error!("Gate:格式化订单状态错误!\nformat_order_item:order={:?}", order);
  98. panic!("Gate:格式化订单状态错误!\nformat_order_item:order={:?}", order)
  99. };
  100. let rst_order = Order {
  101. id: order["id"].to_string(),
  102. custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
  103. price: Decimal::from_f64(order["price"].as_f64().unwrap()).unwrap(),
  104. amount,
  105. deal_amount,
  106. avg_price: Decimal::from_f64(order["fill_price"].as_f64().unwrap()).unwrap(),
  107. status: custom_status,
  108. order_type: "limit".to_string(),
  109. trace_stack: TraceStack::new(0, Instant::now()).on_special("120 gate_handle".to_string()),
  110. };
  111. return rst_order;
  112. }
  113. // 处理特殊Ticket信息
  114. pub fn handle_book_ticker(res_data: &ResponseData) -> SpecialDepth {
  115. let bp = Decimal::from_str((*res_data).data["b"].as_str().unwrap_or("0")).unwrap_or(Decimal::ZERO);
  116. let bq = Decimal::from_f64((*res_data).data["B"].as_f64().unwrap()).unwrap();
  117. let ap = Decimal::from_str((*res_data).data["a"].as_str().unwrap_or("0")).unwrap_or(Decimal::ZERO);
  118. let aq = Decimal::from_f64((*res_data).data["A"].as_f64().unwrap()).unwrap();
  119. let mp = (bp + ap) * dec!(0.5);
  120. let t = Decimal::from_u64((*res_data).data["u"].as_u64().unwrap()).unwrap();
  121. let create_at = (*res_data).data["t"].as_i64().unwrap() * 1000;
  122. let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
  123. let depth_info = vec![bp, bq, ap, aq];
  124. SpecialDepth {
  125. name: (*res_data).label.clone(),
  126. depth: depth_info,
  127. ticker: ticker_info,
  128. t,
  129. create_at,
  130. }
  131. }
  132. pub fn format_depth_items(value: &Value) -> Vec<MarketOrder> {
  133. let mut depth_items: Vec<MarketOrder> = vec![];
  134. for value in value.as_array().unwrap() {
  135. depth_items.push(MarketOrder {
  136. price: Decimal::from_str(value["p"].as_str().unwrap()).unwrap(),
  137. amount: Decimal::from_f64(value["s"].as_f64().unwrap()).unwrap(),
  138. })
  139. }
  140. return depth_items;
  141. }