Răsfoiți Sursa

kucoin单元测试

gepangpang 2 ani în urmă
părinte
comite
c4ca4211fe

+ 27 - 1
standard/src/binance_swap.rs

@@ -228,7 +228,33 @@ impl Platform for BinanceSwap {
         }
     }
 
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> { todo!() }
+    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
+        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
+        let res_data = self.request.get_open_orders(symbol_format).await;
+        if res_data.code == "200" {
+            let res_data_str = &res_data.data;
+            let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
+            let order_info: Vec<_> = res_data_json.iter().filter(|item| item["contract"].as_str().unwrap_or("") == self.symbol).collect();
+            let result = order_info.iter().map(|&item| {
+                let status = item["status"].as_str().unwrap();
+                let custom_status = if ["CANCELED", "EXPIRED", "FILLED"].contains(&status) { "REMOVE".to_string() } else if status == "NEW" { "NEW".to_string() } else { panic!("Binance:格式化订单状态错误!\nget_order_detail:status={:?}", status) };
+                Order {
+                    id: item["orderId"].to_string(),
+                    custom_id: item["clientOrderId"].as_str().unwrap().parse().unwrap(),
+                    price: Decimal::from_str(item["price"].as_str().unwrap()).unwrap(),
+                    amount: Decimal::from_str(item["origQty"].as_str().unwrap()).unwrap(),
+                    deal_amount: Decimal::from_str(item["executedQty"].as_str().unwrap()).unwrap(),
+                    avg_price: Decimal::from_str(item["avgPrice"].as_str().unwrap()).unwrap(),
+                    status: custom_status,
+                    order_type: item["type"].as_str().unwrap().parse().unwrap(),
+                }
+            }
+            ).collect();
+            Ok(result)
+        } else {
+            Err(Error::new(ErrorKind::Other, res_data.message))
+        }
+    }
 
     async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { todo!() }
 

+ 2 - 2
standard/src/kucoin_handle.rs

@@ -41,9 +41,9 @@ pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
 }
 
 pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let bp = Decimal::from_str(&data["bestBidPrice"].to_string()).unwrap();
+    let bp = Decimal::from_str(&data["bestBidPrice"].as_str().unwrap()).unwrap();
     let bq = Decimal::from_str(&data["bestBidSize"].to_string()).unwrap();
-    let ap = Decimal::from_str(&data["bestAskPrice"].to_string()).unwrap();
+    let ap = Decimal::from_str(&data["bestAskPrice"].as_str().unwrap()).unwrap();
     let aq = Decimal::from_str(&data["bestAskSize"].to_string()).unwrap();
     let mp = (bp + ap) * dec!(0.5);
 

+ 10 - 0
standard/tests/binance_swap_test.rs

@@ -159,4 +159,14 @@ async fn test_get_order_detail() {
     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
     let binance_get_order_detail = binance_swap_exchange.get_order_detail("", "9999").await;
     trace!(?binance_get_order_detail);
+}
+// 测试获取订单详情信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_orders_list() {
+    global::log_utils::init_log_with_trace();
+
+    let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
+    let binance_get_orders_list = binance_swap_exchange.get_orders_list("open").await;
+    trace!(?binance_get_orders_list);
 }

+ 95 - 6
standard/tests/exchange_test.rs

@@ -1,15 +1,23 @@
-use std::collections::BTreeMap;
-use std::env;
+use std::collections::{BTreeMap};
+use std::{env};
 use std::io::Error;
-use tokio::sync::mpsc;
+use std::sync::Arc;
+use std::sync::atomic::AtomicBool;
+use std::time::Duration;
+use rust_decimal_macros::dec;
+use tokio::sync::mpsc::{channel, Receiver, Sender};
+use tokio::try_join;
+use tracing::trace;
+use exchanges::kucoin_swap_ws::{KucoinSubscribeType, KucoinSwapWs, KucoinWsType};
+use exchanges::response_base::ResponseData;
 use standard::exchange::{Exchange, ExchangeEnum};
-use standard::{Order, Platform, utils};
+use standard::{kucoin_handle, Order, Platform, utils};
 
 // 创建实体
 pub async fn test_new_exchange(exchange: ExchangeEnum, symbol: &str) -> Box<dyn Platform> {
     utils::proxy_handle();
-    let (order_sender, _order_receiver): (mpsc::Sender<Order>, mpsc::Receiver<Order>) = mpsc::channel(1024);
-    let (error_sender, _error_receiver): (mpsc::Sender<Error>, mpsc::Receiver<Error>) = mpsc::channel(1024);
+    let (order_sender, _order_receiver): (Sender<Order>, Receiver<Order>) = channel(1024);
+    let (error_sender, _error_receiver): (Sender<Error>, Receiver<Error>) = channel(1024);
     match exchange {
         ExchangeEnum::BinanceSwap => {
             let mut params: BTreeMap<String, String> = BTreeMap::new();
@@ -54,4 +62,85 @@ pub async fn test_new_exchange(exchange: ExchangeEnum, symbol: &str) -> Box<dyn
             Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
         }
     }
+}
+
+#[allow(dead_code)]
+pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subscriber_type: T, mold: &str) where Vec<KucoinSubscribeType>: From<T> {
+    utils::proxy_handle();
+
+    match exchange {
+        ExchangeEnum::BinanceSwap => {
+            panic!("该交易所不支持!")
+        }
+        ExchangeEnum::GateSwap => {
+            panic!("该交易所不支持!")
+        }
+        ExchangeEnum::KucoinSwap => {
+            let symbol_format = format!("{}M", utils::format_symbol(symbol.to_string(), ""));
+            let symbol_back = utils::format_symbol(symbol.to_string(), "_");
+            let name = format!("kucoin_usdt_swap@{}", symbol.to_string().to_lowercase());
+            let bool_v1 = Arc::new(AtomicBool::new(true));
+
+            let (res_sender, mut res_receiver): (Sender<ResponseData>, Receiver<ResponseData>) = channel(1024);
+            let mut params: BTreeMap<String, String> = BTreeMap::new();
+            let access_key = env::var("kucoin_access_key").unwrap_or("".to_string());
+            let secret_key = env::var("kucoin_secret_key").unwrap_or("".to_string());
+            let pass_key = env::var("kucoin_pass_key").unwrap_or("".to_string());
+            params.insert("access_key".to_string(), access_key);
+            params.insert("secret_key".to_string(), secret_key);
+            params.insert("pass_key".to_string(), pass_key);
+            let mut exchange_wss;
+            if ["depth", "ticker"].contains(&mold) {
+                exchange_wss = KucoinSwapWs::new_label(name, false, params, KucoinWsType::Public, res_sender).await
+            } else {
+                exchange_wss = KucoinSwapWs::new_label(name, false, params, KucoinWsType::Private, res_sender).await
+            }
+            exchange_wss.set_subscribe(subscriber_type.into());
+
+            let t1 = tokio::spawn(async move {
+                exchange_wss.custom_subscribe(bool_v1, vec![symbol_format]).await;
+            });
+            let mold_arc = Arc::new(mold.to_string());
+            let t2 = tokio::spawn(async move {
+                let mold_clone = Arc::clone(&mold_arc);
+                loop {
+                    tokio::time::sleep(Duration::from_millis(1)).await;
+                    if let Ok(received) = res_receiver.try_recv() {
+                        match mold_clone.as_str() {
+                            "depth" => {
+                                let result = kucoin_handle::handle_special_depth(received);
+                                trace!(?result)
+                            }
+                            "ticker" => {
+                                let result = kucoin_handle::handle_special_ticker(received);
+                                trace!(?result)
+                            }
+                            "account" => {
+                                trace!(?received);
+                                let result = kucoin_handle::handle_account_info(received, symbol_back.clone());
+                                trace!(?result)
+                            }
+                            "position" => {
+                                trace!(?received);
+                                let result = kucoin_handle::handle_position(received, dec!(1));
+                                trace!(?result)
+                            }
+                            "orders" => {
+                                trace!(?received);
+                                let result = kucoin_handle::handle_order(received, dec!(0.001));
+                                trace!(?result)
+                            }
+                            _ => {
+                                panic!("没有该命令!mode={}", mold_clone)
+                            }
+                        }
+                    }
+                }
+            });
+            try_join!(t1, t2).unwrap();
+        }
+        _ => {
+            panic!("该交易所不支持!")
+        }
+    }
 }

+ 1 - 1
standard/tests/kucoin_swap_test.rs

@@ -206,7 +206,7 @@ async fn test_cancel_order() {
     global::log_utils::init_log_with_trace();
 
     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-    let kucoin_cancel_order = kucoin_swap_exchange.cancel_order("94627978104856576", "").await;
+    let kucoin_cancel_order = kucoin_swap_exchange.cancel_order("96039854680322048", "").await;
     trace!(?kucoin_cancel_order);
 }