Просмотр исходного кода

添加gate单元测试代码
添加kucoin的单元测试代码

gepangpang 2 лет назад
Родитель
Сommit
a879f5c274

+ 5 - 5
standard/src/kucoin_handle.rs

@@ -69,18 +69,18 @@ pub fn format_position_item(position: &serde_json::Value, amount_size: Decimal)
     let currency = position["settleCurrency"].as_str().unwrap_or("");
     let coin = &symbol[..symbol.find(currency).unwrap_or(0)];
 
-    let current_qty = Decimal::from_str(position["currentQty"].as_str().unwrap()).unwrap();
+    let current_qty = Decimal::from_str(&position["currentQty"].to_string()).unwrap();
     let amount = current_qty * amount_size;
     let position_mode = if amount > dec!(0) { PositionModeEnum::Long } else { PositionModeEnum::Short };
     Position {
         symbol: format!("{}_{}", coin, currency),
-        margin_level: Decimal::from_str(position["realLeverage"].as_str().unwrap()).unwrap(),
+        margin_level: Decimal::from_str(&position["realLeverage"].to_string()).unwrap(),
         amount: amount.abs(),
         frozen_amount: dec!(0),
-        price: Decimal::from_str(position["avgEntryPrice"].as_str().unwrap()).unwrap(),
-        profit: Decimal::from_str(position["unrealisedPnl"].as_str().unwrap()).unwrap(),
+        price: Decimal::from_str(&position["avgEntryPrice"].to_string()).unwrap(),
+        profit: Decimal::from_str(&position["unrealisedPnl"].to_string()).unwrap(),
         position_mode,
-        margin: Decimal::from_str(position["posMargin"].as_str().unwrap()).unwrap(),
+        margin: Decimal::from_str(&position["posMargin"].to_string()).unwrap(),
     }
 }
 

+ 16 - 11
standard/src/kucoin_swap.rs

@@ -76,6 +76,7 @@ impl Platform for KucoinSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let result = res_data_str.clone();
+            println!("{}", res_data.data);
             Ok(result)
         } else {
             Err(Error::new(ErrorKind::Other, res_data.message))
@@ -122,7 +123,8 @@ impl Platform for KucoinSwap {
     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
         let amount_size = self.market.amount_size;
-        let res_data = self.request.get_positions(symbol_array[1].to_string().to_uppercase()).await;
+        let res_data = self.request.get_positions(symbol_array[1].to_string()).await;
+        println!("{:?}", res_data);
         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();
@@ -143,11 +145,11 @@ impl Platform for KucoinSwap {
             let time = (Decimal::from_str(&*ticker_info["ts"].to_string()).unwrap() / dec!(1000000)).floor().to_i64().unwrap();
             let result = Ticker {
                 time,
-                high: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
-                buy: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
-                last: Decimal::from_str(ticker_info["price"].as_str().unwrap()).unwrap(),
+                high: Decimal::from_str(&ticker_info["bestAskPrice"].to_string()).unwrap(),
+                low: Decimal::from_str(&ticker_info["bestBidPrice"].to_string()).unwrap(),
+                sell: Decimal::from_str(&ticker_info["bestAskPrice"].to_string()).unwrap(),
+                buy: Decimal::from_str(&ticker_info["bestBidPrice"].to_string()).unwrap(),
+                last: Decimal::from_str(&ticker_info["price"].to_string()).unwrap(),
                 volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
             };
             Ok(result)
@@ -213,11 +215,12 @@ impl Platform for KucoinSwap {
     async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error> {
         let symbol_format = format!("{}M", utils::format_symbol(self.symbol.clone(), ""));
         let amount_size = self.market.amount_size;
-        let res_data = self.request.get_orders(status.to_string(), symbol_format).await;
+        let res_data = self.request.get_orders(status.to_string(), symbol_format.clone()).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<&serde_json::Value> = res_data_json.iter().filter(|item| item["contract"].as_str().unwrap_or("") == self.symbol.clone()).collect();
+            let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
+            let order_list: Vec<serde_json::Value> = res_data_json["items"].as_array().unwrap().clone();
+            let order_info: Vec<&serde_json::Value> = order_list.iter().filter(|item| item["symbol"].as_str().unwrap_or("") == symbol_format.clone()).collect();
             let result = order_info.iter().map(|&item| format_order_item(item.clone(), amount_size)).collect();
             Ok(result)
         } else {
@@ -252,8 +255,9 @@ impl Platform for KucoinSwap {
             _ => { error!("下单参数错误"); }
         };
 
-        let res_data = self.request.swap_order(Default::default()).await;
+        let res_data = self.request.swap_order(params).await;
         if res_data.code == "200" {
+            println!("{:?}",res_data);
             let res_data_str = &res_data.data;
             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
             let result = format_order_item(res_data_json, amount_size);
@@ -370,11 +374,12 @@ impl Platform for KucoinSwap {
 }
 
 pub fn format_order_item(order: serde_json::Value, amount_size: Decimal) -> Order {
+    println!("{}", order);
     let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
     let size = Decimal::from_str(&order["size"].to_string()).unwrap();
     let status = order["status"].as_str().unwrap_or("");
     let filled_size = Decimal::from_str(&order["filledSize"].to_string()).unwrap();
-    let filled_value = Decimal::from_str(&order["filledValue"].to_string()).unwrap();
+    let filled_value = Decimal::from_str(order["filledValue"].as_str().unwrap()).unwrap();
 
     let amount = size * amount_size;
     let deal_amount = filled_size * amount_size;

+ 6 - 6
standard/tests/exchange_test.rs

@@ -8,7 +8,7 @@ use standard::exchange::{Exchange, ExchangeEnum};
 use standard::{Order, Platform};
 
 // 创建实体
-pub async fn test_new_exchange(exchange: ExchangeEnum) -> Box<dyn Platform> {
+pub async fn test_new_exchange(exchange: ExchangeEnum, symbol: &str) -> Box<dyn Platform> {
     if proxy::ParsingDetail::http_enable_proxy() {
         trace!("检测有代理配置,配置走代理");
     }
@@ -21,7 +21,7 @@ pub async fn test_new_exchange(exchange: ExchangeEnum) -> Box<dyn Platform> {
             let secret_key = env::var("binance_secret_key").unwrap_or("".to_string());
             params.insert("access_key".to_string(), access_key);
             params.insert("secret_key".to_string(), secret_key);
-            Exchange::new(exchange, "ROSE_USDT".to_string(), false, params, order_sender, error_sender).await
+            Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
         }
         ExchangeEnum::BinanceSpot => {
             let mut params: BTreeMap<String, String> = BTreeMap::new();
@@ -29,7 +29,7 @@ pub async fn test_new_exchange(exchange: ExchangeEnum) -> Box<dyn Platform> {
             let secret_key = env::var("binance_secret_key").unwrap_or("".to_string());
             params.insert("access_key".to_string(), access_key);
             params.insert("secret_key".to_string(), secret_key);
-            Exchange::new(exchange, "ROSE_USDT".to_string(), false, params, order_sender, error_sender).await
+            Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
         }
         ExchangeEnum::GateSwap => {
             let mut params: BTreeMap<String, String> = BTreeMap::new();
@@ -37,7 +37,7 @@ pub async fn test_new_exchange(exchange: ExchangeEnum) -> Box<dyn Platform> {
             let secret_key = env::var("gate_secret_key").unwrap_or("".to_string());
             params.insert("access_key".to_string(), access_key);
             params.insert("secret_key".to_string(), secret_key);
-            Exchange::new(exchange, "BLZ_USDT".to_string(), false, params, order_sender, error_sender).await
+            Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
         }
         ExchangeEnum::GateSpot => {
             let mut params: BTreeMap<String, String> = BTreeMap::new();
@@ -45,7 +45,7 @@ pub async fn test_new_exchange(exchange: ExchangeEnum) -> Box<dyn Platform> {
             let secret_key = env::var("gate_secret_key").unwrap_or("".to_string());
             params.insert("access_key".to_string(), access_key);
             params.insert("secret_key".to_string(), secret_key);
-            Exchange::new(exchange, "ROSE_USDT".to_string(), false, params, order_sender, error_sender).await
+            Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
         }
         ExchangeEnum::KucoinSwap => {
             let mut params: BTreeMap<String, String> = BTreeMap::new();
@@ -55,7 +55,7 @@ pub async fn test_new_exchange(exchange: ExchangeEnum) -> Box<dyn Platform> {
             params.insert("access_key".to_string(), access_key);
             params.insert("secret_key".to_string(), secret_key);
             params.insert("pass_key".to_string(), pass_key);
-            Exchange::new(exchange, "ROSE_USDT".to_string(), false, params, order_sender, error_sender).await
+            Exchange::new(exchange, symbol.to_string(), false, params, order_sender, error_sender).await
         }
     }
 }

+ 276 - 0
standard/tests/gate_swap_test.rs

@@ -0,0 +1,276 @@
+mod exchange_test;
+
+use std::collections::BTreeMap;
+use std::env;
+use std::io::Error;
+use rust_decimal_macros::dec;
+use tokio::sync::mpsc;
+use tracing::{instrument, trace};
+use standard::exchange::{Exchange, ExchangeEnum};
+use standard::{Order, OrderCommand, Platform};
+use crate::exchange_test::test_new_exchange;
+
+const SYMBOL: &str = "BLZ_USDT";
+
+// 测试获取Exchange实体
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_self_exchange() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_self_exchange = gate_swap_exchange.get_self_exchange();
+    trace!(?gate_get_self_exchange);
+}
+
+// 测试获取交易对信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_self_symbol() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_self_symbol = gate_swap_exchange.get_self_symbol();
+    trace!(?gate_get_self_symbol);
+}
+
+// 测试获取是否使用高速通道
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_self_is_colo() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_self_is_colo = gate_swap_exchange.get_self_is_colo();
+    trace!(?gate_get_self_is_colo);
+}
+
+// 测试获取登录params信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_self_params() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_self_params = gate_swap_exchange.get_self_params();
+    trace!("gate_get_self_params={:?}",gate_get_self_params);
+}
+
+// 测试获取Market信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_self_market() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_self_market = gate_swap_exchange.get_self_market();
+    trace!(?gate_get_self_market);
+}
+
+// 测试获取请求时间信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_request_delays() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_request_delays = gate_swap_exchange.get_request_delays();
+    trace!(?gate_get_request_delays);
+}
+
+// 测试获取请求平均时间信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_request_avg_delay() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_request_avg_delay = gate_swap_exchange.get_request_avg_delay();
+    trace!(?gate_get_request_avg_delay);
+}
+
+// 测试获取最大请求时间信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_request_max_delay() {
+    global::log_utils::init_log_with_trace();
+
+    let gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_request_max_delay = gate_swap_exchange.get_request_max_delay();
+    trace!(?gate_get_request_max_delay);
+}
+
+// 测试获取服务器时间
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_server_time() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_server_time = gate_swap_exchange.get_server_time().await;
+    trace!(?gate_get_server_time);
+}
+
+// 测试获取账号信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_account() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_account = gate_swap_exchange.get_account().await;
+    trace!(?gate_get_account);
+}
+
+// 测试获取持仓信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_position() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_position = gate_swap_exchange.get_position().await;
+    trace!(?gate_get_position);
+}
+
+// 测试获取所有持仓信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_positions() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_positions = gate_swap_exchange.get_positions().await;
+    trace!(?gate_get_positions);
+}
+
+// 测试获取Ticker信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_ticker() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_ticker = gate_swap_exchange.get_ticker().await;
+    trace!(?gate_get_ticker);
+}
+
+// 测试获取Market信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_market() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_market = gate_swap_exchange.get_market().await;
+    trace!(?gate_get_market);
+}
+
+// 测试获取Order详情信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_order_detail() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_order_detail = gate_swap_exchange.get_order_detail("", "999999").await;
+    trace!(?gate_get_order_detail);
+}
+
+// 测试获取Order列表信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_orders_list() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_get_orders_list = gate_swap_exchange.get_orders_list("finished").await;
+    trace!(?gate_get_orders_list);
+}
+
+// 测试下单
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_take_order() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_take_order = gate_swap_exchange.take_order("999999", "kk", dec!(0.27), dec!(100)).await;
+    trace!(?gate_take_order);
+}
+
+// 测试撤销订单
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_cancel_order() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_cancel_order = gate_swap_exchange.cancel_order("", "999999").await;
+    trace!(?gate_cancel_order);
+}
+
+// 测试批量撤销订单
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_cancel_orders() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_cancel_orders = gate_swap_exchange.cancel_orders().await;
+    trace!(?gate_cancel_orders);
+}
+
+// 测试设置持仓模式
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_set_dual_mode() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_set_dual_mode = gate_swap_exchange.set_dual_mode("usdt", true).await;
+    trace!(?gate_set_dual_mode);
+}
+
+// 测试设置杠杆
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_set_dual_leverage() {
+    global::log_utils::init_log_with_trace();
+
+    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap, SYMBOL).await;
+    let gate_set_dual_leverage = gate_swap_exchange.set_dual_leverage("10").await;
+    trace!(?gate_set_dual_leverage);
+}
+
+// 测试指令下单
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_command_order() {
+    global::log_utils::init_log_with_trace();
+    let (order_sender, mut order_receiver): (mpsc::Sender<Order>, mpsc::Receiver<Order>) = mpsc::channel(1024);
+    let (error_sender, mut error_receiver): (mpsc::Sender<Error>, mpsc::Receiver<Error>) = mpsc::channel(1024);
+
+    let mut params: BTreeMap<String, String> = BTreeMap::new();
+    let access_key = env::var("gate_access_key").unwrap_or("".to_string());
+    let secret_key = env::var("gate_secret_key").unwrap_or("".to_string());
+    params.insert("access_key".to_string(), access_key);
+    params.insert("secret_key".to_string(), secret_key);
+
+    let mut gate_swap_exchange: Box<dyn Platform> = Exchange::new(ExchangeEnum::GateSwap, SYMBOL.to_string(), false, params, order_sender, error_sender).await;
+
+    let mut command = OrderCommand::new();
+    command.cancel.insert("888888".to_string(), vec!["888888".to_string(), "".to_string()]);
+    command.limits_open.insert("888888".to_string(), vec!["100".to_string(), "kd".to_string(), "0.18".to_string(), "888888".to_string()]);
+    command.limits_close.insert("999999".to_string(), vec!["100".to_string(), "kk".to_string(), "0.25".to_string(), "999999".to_string()]);
+    command.check.insert("888888".to_string(), vec!["999999".to_string(), "".to_string()]);
+    gate_swap_exchange.command_order(command).await;
+
+
+    if let Ok(order) = order_receiver.try_recv() {
+        trace!(?order);
+    }
+    if let Ok(error) = error_receiver.try_recv() {
+        trace!(?error);
+    }
+}