فهرست منبع

币安wss 测试完成

skyfffire 1 سال پیش
والد
کامیت
820fbf59e3
3فایلهای تغییر یافته به همراه138 افزوده شده و 32 حذف شده
  1. 29 28
      standard/src/binance_swap_handle.rs
  2. 60 0
      standard/tests/binance_handle_test.rs
  3. 49 4
      standard/tests/exchange_test.rs

+ 29 - 28
standard/src/binance_swap_handle.rs

@@ -1,6 +1,7 @@
 use std::str::FromStr;
 use rust_decimal::Decimal;
 use rust_decimal::prelude::FromPrimitive;
+use rust_decimal_macros::dec;
 use serde_json::Value;
 use tokio::time::Instant;
 use tracing::error;
@@ -12,22 +13,24 @@ use crate::{Account, Depth, Order, OrderBook, Position, PositionModeEnum, Record
 // 处理账号信息
 pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account {
     let symbol_format = utils::format_symbol(symbol.clone(), "");
-    let res_data_json = res_data.data.as_array().unwrap();
+    let res_data_json = res_data.data["a"]["B"].as_array().unwrap();
 
-
-    let balance_info = res_data_json.iter().find(|&item| item["result"].as_str().unwrap().contains(&symbol_format));
+    let balance_info = res_data_json.iter().find(|&item| symbol_format.ends_with(item["a"].as_str().unwrap()));
     match balance_info {
         None => {
             error!("Gate:格式化账号信息错误!\nformat_account_info: data={:?}", res_data_json);
             panic!("Gate:格式化账号信息错误!\nformat_account_info: data={:?}", res_data_json)
         }
         Some(value) => {
-            let balance = Decimal::from_str(&value["balance"].as_f64().unwrap().to_string()).unwrap();
+            let coin = value["a"].as_str().unwrap().to_string();
+            let balance = Decimal::from_str(&value["wb"].as_str().unwrap()).unwrap();
+            let available_balance = Decimal::from_str(&value["cw"].as_str().unwrap()).unwrap();
+            let frozen_balance = balance - available_balance;
             Account {
-                coin: symbol_format,
+                coin,
                 balance,
-                available_balance: Decimal::ZERO,
-                frozen_balance: Decimal::ZERO,
+                available_balance,
+                frozen_balance,
                 stocks: Decimal::ZERO,
                 available_stocks: Decimal::ZERO,
                 frozen_stocks: Decimal::ZERO,
@@ -38,20 +41,20 @@ pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account
 
 // 处理position信息
 pub fn handle_position(res_data: &ResponseData, mul: &Decimal) -> Vec<Position> {
-    let res_data_json = res_data.data.as_array().unwrap();
+    let res_data_json = res_data.data["a"]["P"].as_array().unwrap();
     res_data_json.iter().map(|item| { format_position_item(item, mul) }).collect()
 }
 pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
-    let mut position_mode = match position["mode"].as_str().unwrap_or("") {
-        "single" => PositionModeEnum::Both,
-        "dual_long" => PositionModeEnum::Long,
-        "dual_short" => PositionModeEnum::Short,
+    let mut position_mode = match position["ps"].as_str().unwrap_or("") {
+        "BOTH" => PositionModeEnum::Both,
+        "LONG" => PositionModeEnum::Long,
+        "SHORT" => PositionModeEnum::Short,
         _ => {
             error!("Gate:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
             panic!("Gate:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
         }
     };
-    let size = Decimal::from_str(&position["size"].as_f64().unwrap().to_string()).unwrap();
+    let size = Decimal::from_str(&position["pa"].as_str().unwrap()).unwrap();
     let amount = size * ct_val;
     match position_mode {
         PositionModeEnum::Both => {
@@ -64,24 +67,22 @@ pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
         _ => {}
     }
     Position {
-        symbol: position["contract"].as_str().unwrap().to_string(),
-        margin_level: Decimal::from_str(&position["leverage"].as_f64().unwrap().to_string()).unwrap(),
+        symbol: position["s"].as_str().unwrap().to_string(),
+        margin_level: dec!(-1),
         amount,
         frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(&position["entry_price"].as_f64().unwrap().to_string()).unwrap(),
-        profit: Decimal::from_str(&position["realised_pnl"].as_f64().unwrap().to_string()).unwrap(),
+        price: Decimal::from_str(&position["ep"].as_str().unwrap()).unwrap(),
+        profit: Decimal::from_str(&position["up"].as_str().unwrap()).unwrap(),
         position_mode,
-        margin: Decimal::from_str(&position["margin"].as_f64().unwrap().to_string()).unwrap(),
+        margin: Decimal::from_str(&position["iw"].as_str().unwrap()).unwrap(),
     }
 }
 
 // 处理order信息
 pub fn handle_order(res_data: &ResponseData, ct_val: &Decimal) -> SpecialOrder {
-    let res_data_json = res_data.data.as_array().unwrap();
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    };
+    let res_data_json = res_data.data["o"].clone();
+    let order_info = vec![format_order_item(res_data_json.clone(), ct_val)];
+
 
     SpecialOrder {
         name: res_data.label.clone(),
@@ -99,7 +100,7 @@ pub fn format_order_item(order: Value, ct_val: &Decimal) -> Order {
 
     let status = order["X"].as_str().unwrap();
 
-    let custom_status = if vec!["FILLED", "CANCELED", "REJECTED", "EXPIRED"].contains(&status) { "REMOVE".to_string() } else if ["NEW", "PARTIALLY_FILLED "].contains(&status) { "NEW".to_string() } else {
+    let custom_status = if vec!["FILLED", "CANCELED", "REJECTED", "EXPIRED"].contains(&status) { "REMOVE".to_string() } else if ["NEW", "PARTIALLY_FILLED"].contains(&status) { "NEW".to_string() } else {
         error!("Gate:格式化订单状态错误!\nformat_order_item:order={:?}", order);
         panic!("Gate:格式化订单状态错误!\nformat_order_item:order={:?}", order)
     };
@@ -112,7 +113,7 @@ pub fn format_order_item(order: Value, ct_val: &Decimal) -> Order {
         avg_price,
         status: custom_status,
         order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("120 binance_handle".to_string()),
+        trace_stack: TraceStack::new(0, Instant::now()).on_special("115 binance_handle".to_string()),
     };
 
     return rst_order;
@@ -121,11 +122,11 @@ pub fn format_order_item(order: Value, ct_val: &Decimal) -> Order {
 // 处理特殊Ticket信息
 pub fn handle_book_ticker(res_data: &ResponseData, mul: &Decimal) -> Depth {
     let bid_price = Decimal::from_str(res_data.data["b"].as_str().unwrap()).unwrap();
-    let bid_amount = Decimal::from_f64(res_data.data["B"].as_f64().unwrap()).unwrap();
+    let bid_amount = Decimal::from_str(res_data.data["B"].as_str().unwrap()).unwrap();
     let ask_price = Decimal::from_str(res_data.data["a"].as_str().unwrap()).unwrap();
-    let ask_amount = Decimal::from_f64(res_data.data["A"].as_f64().unwrap()).unwrap();
+    let ask_amount = Decimal::from_str(res_data.data["A"].as_str().unwrap()).unwrap();
     // let u = Decimal::from_u64((*res_data).data["u"].as_u64().unwrap()).unwrap();
-    let t = Decimal::from_i64(res_data.data["t"].as_i64().unwrap()).unwrap();
+    let t = Decimal::from_i64(res_data.data["T"].as_i64().unwrap()).unwrap();
     let s = res_data.data["s"].as_str().unwrap().replace("USDT", "_USDT");
 
     let asks = vec![

+ 60 - 0
standard/tests/binance_handle_test.rs

@@ -29,3 +29,63 @@ async fn test_get_wss_ticker() {
     ];
     test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "ticker").await;
 }
+
+// 测试订阅Trade信息
+#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
+#[instrument(level = "TRACE")]
+async fn test_get_wss_trade() {
+    global::log_utils::init_log_with_trace();
+
+    let binance_subscribe_type = vec![
+        BinanceSwapSubscribeType::PuAggTrade,
+    ];
+    test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "trade").await;
+}
+
+// // 测试订阅Record信息
+// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
+// #[instrument(level = "TRACE")]
+// async fn test_get_wss_record() {
+//     global::log_utils::init_log_with_trace();
+//
+//     let binance_subscribe_type = vec![
+//         BinanceSwapSubscribeType::PuDepth20levels100ms,
+//     ];
+//     test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "record").await;
+// }
+
+// 测试订阅Account信息
+#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
+#[instrument(level = "TRACE")]
+async fn test_get_wss_account() {
+    global::log_utils::init_log_with_trace();
+
+    let binance_subscribe_type = vec![
+        BinanceSwapSubscribeType::PrBalance,
+    ];
+    test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "account").await;
+}
+
+// 测试订阅Order信息
+#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
+#[instrument(level = "TRACE")]
+async fn test_get_wss_order() {
+    global::log_utils::init_log_with_trace();
+
+    let binance_subscribe_type = vec![
+        BinanceSwapSubscribeType::PrAccount,
+    ];
+    test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "order").await;
+}
+
+// 测试订阅Position信息
+#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
+#[instrument(level = "TRACE")]
+async fn test_get_wss_position() {
+    global::log_utils::init_log_with_trace();
+
+    let binance_subscribe_type = vec![
+        BinanceSwapSubscribeType::PrPosition,
+    ];
+    test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "position").await;
+}

+ 49 - 4
standard/tests/exchange_test.rs

@@ -208,7 +208,7 @@ where
         // try_join!(t1).unwrap();
         // }
         ExchangeEnum::BinanceSwap => {
-            let symbol_format = utils::format_symbol(symbol.to_string(), "-").to_uppercase();
+            let symbol_format = utils::format_symbol(symbol.to_string(), "").to_uppercase();
             trace!(symbol_format);
             let name = format!("binance_swap@{}", symbol.to_string().to_lowercase());
             let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
@@ -216,12 +216,12 @@ where
             let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
             let params = BinanceSwapLogin {
-                api_key: "".to_string(),
-                api_secret: "".to_string(),
+                api_key: account_info.binance_access_key,
+                api_secret: account_info.binance_secret_key
             };
 
 
-            let mut exchange_wss = if ["depth", "ticker"].contains(&mold) {
+            let mut exchange_wss = if ["depth", "ticker","trade","record"].contains(&mold) {
                 BinanceSwapWs::new_label(name, false, Option::from(params), BinanceSwapWsType::Public).await
             } else {
                 BinanceSwapWs::new_label(name, false, Option::from(params), BinanceSwapWsType::Private).await
@@ -244,6 +244,51 @@ where
                                 trace!(?result)
                             }
                         }
+                        "ticker" => {
+                            if data.data != "" {
+                                let result = ExchangeStructHandler::book_ticker_handle(ExchangeEnum::BinanceSwap, &data, &Decimal::ONE);
+                                trace!("-------------------------------");
+                                trace!(?result)
+                            }
+                        }
+                        "trade" => {
+                            if data.data != "" {
+                                let result = ExchangeStructHandler::trades_handle(ExchangeEnum::BinanceSwap, &data, &Decimal::ONE);
+                                trace!("-------------------------------");
+                                trace!(?result)
+                            }
+                        }
+                        "record" => {
+                            if data.data != "" {
+                                let result = ExchangeStructHandler::records_handle(ExchangeEnum::BinanceSwap, &data);
+                                trace!("-------------------------------");
+                                trace!(?result)
+                            }
+                        }
+                        "account" => {
+                            if data.data != "" {
+                                if data.channel != "ACCOUNT_UPDATE" { return; };
+                                let result = ExchangeStructHandler::account_info_handle(ExchangeEnum::BinanceSwap, &data, &symbol_format_c);
+                                trace!("-------------------------------");
+                                trace!(?result)
+                            }
+                        }
+                        "order" => {
+                            if data.data != "" {
+                                if data.channel != "ORDER_TRADE_UPDATE" { return; };
+                                let result = ExchangeStructHandler::order_handle(ExchangeEnum::BinanceSwap, &data, &Decimal::ONE);
+                                trace!("-------------------------------");
+                                trace!(?result)
+                            }
+                        }
+                        "position" => {
+                            if data.data != "" {
+                                if data.channel != "ACCOUNT_UPDATE" { return; };
+                                let result = ExchangeStructHandler::position_handle(ExchangeEnum::BinanceSwap, &data, &Decimal::ONE);
+                                trace!("-------------------------------");
+                                trace!(?result)
+                            }
+                        }
                         _ => {
                             error!("没有该命令!mode={}", mold_cc);
                             panic!("没有该命令!mode={}", mold_cc)