Browse Source

修改格式化数据方式

gepangpang 2 years ago
parent
commit
cc8542c40e

+ 6 - 8
standard/src/binance_spot.rs

@@ -86,14 +86,6 @@ impl Platform for BinanceSpot {
         todo!()
     }
 
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        todo!()
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
-
     async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { todo!() }
 
     async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { todo!() }
@@ -102,5 +94,11 @@ impl Platform for BinanceSpot {
         todo!()
     }
 
+    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
+
+    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { todo!() }
+
+    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
+
     async fn command_order(&mut self, _order_command: OrderCommand) { todo!() }
 }

+ 6 - 8
standard/src/binance_swap.rs

@@ -116,14 +116,6 @@ impl Platform for BinanceSwap {
         todo!()
     }
 
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        todo!()
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
-
     async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { todo!() }
 
     async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { todo!() }
@@ -132,5 +124,11 @@ impl Platform for BinanceSwap {
         todo!()
     }
 
+    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
+
+    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { todo!() }
+
+    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
+
     async fn command_order(&mut self, _order_command: OrderCommand) { todo!() }
 }

+ 5 - 5
standard/src/gate_handle.rs

@@ -19,8 +19,8 @@ pub fn format_account_info(data: Vec<serde_json::Value>, symbol: String) -> Acco
     let balance_info = data.iter().find(|&item| item["text"].as_str().unwrap().contains(&symbol));
     match balance_info {
         None => {
-            error!("格式化Gate账号信息错误!");
-            panic!("格式化Gate账号信息错误!\nformat_account_info: balance_info={:?}", balance_info)
+            error!("Gate:格式化账号信息错误!");
+            panic!("Gate:格式化账号信息错误!\nformat_account_info: balance_info={:?}", balance_info)
         }
         Some(value) => {
             let balance = Decimal::from_str(&value["balance"].to_string()).unwrap();
@@ -48,12 +48,12 @@ pub fn format_position_item(position: &serde_json::Value, amount_size: Decimal)
         "single" => PositionModeEnum::Both,
         "dual_long" => PositionModeEnum::Long,
         "dual_short" => PositionModeEnum::Short,
-        _ => panic!("格式化Gate持仓模式错误!\nformat_position_item:position_mode={}", position["mode"])
+        _ => panic!("Gate:格式化持仓模式错误!\nformat_position_item:position_mode={}", position["mode"])
     };
     let size = Decimal::from_str(&position["size"].to_string()).unwrap();
     let amount = size * amount_size;
     Position {
-        symbol: position["contract"].as_str().unwrap_or("").parse().unwrap(),
+        symbol: position["contract"].as_str().unwrap().to_string(),
         margin_level: Decimal::from_str(&position["leverage"].to_string()).unwrap(),
         amount,
         frozen_amount: dec!(0),
@@ -87,7 +87,7 @@ pub fn format_order_item(order: serde_json::Value, amount_size: Decimal) -> Orde
 
     let amount = size * amount_size;
     let deal_amount = (size - left) * amount_size;
-    let custom_status = if status == "finished" { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { panic!("格式化Gate订单状态错误!\nformat_order_item:status={}", status) };
+    let custom_status = if status == "finished" { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { panic!("Gate:格式化订单状态错误!\nformat_order_item:status={}", status) };
     Order {
         id: order["id"].to_string(),
         custom_id: text.replace("t-my-custom-id_", ""),

+ 6 - 10
standard/src/gate_spot.rs

@@ -86,21 +86,17 @@ impl Platform for GateSpot {
         todo!()
     }
 
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
+    async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { todo!() }
 
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        todo!()
-    }
+    async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { todo!() }
 
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
+    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { todo!() }
 
-    async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { todo!() }
+    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
 
-    async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { todo!() }
+    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { todo!() }
 
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        todo!()
-    }
+    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
 
     async fn command_order(&mut self, _order_command: OrderCommand) { todo!() }
 }

+ 42 - 41
standard/src/gate_swap.rs

@@ -76,7 +76,8 @@ impl Platform for GateSwap {
         let res_data = self.request.get_server_time().await;
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
-            let result = res_data_str.clone();
+            let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
+            let result = res_data_json["server_time"].to_string();
             Ok(result)
         } else {
             Err(Error::new(ErrorKind::Other, res_data.message))
@@ -143,7 +144,7 @@ impl Platform for GateSwap {
             let ticker_info = res_data_json.iter().find(|item| item["contract"].as_str().unwrap() == self.symbol);
             match ticker_info {
                 None => {
-                    panic!("获取Ticker信息错误!\nget_ticker:res_data={}", res_data_str)
+                    panic!("Gate:获取Ticker信息错误!\nget_ticker:res_data={}", res_data_str)
                 }
                 Some(value) => {
                     let result = Ticker {
@@ -172,7 +173,7 @@ impl Platform for GateSwap {
             let market_info = res_data_json.iter().find(|item| item["name"].as_str().unwrap() == self.symbol);
             match market_info {
                 None => {
-                    panic!("获取Market信息错误!\nget_market:res_data={}", res_data_str)
+                    panic!("Gate:获取Market信息错误!\nget_market:res_data={}", res_data_str)
                 }
                 Some(value) => {
                     let name = value["name"].as_str().unwrap();
@@ -233,42 +234,6 @@ impl Platform for GateSwap {
             Err(Error::new(ErrorKind::Other, res_data.message))
         }
     }
-    // 设置持仓模式
-    async fn set_dual_mode(&mut self, coin: &str, is_dual_mode: bool) -> Result<String, Error> {
-        let coin_format = coin.to_string().to_lowercase();
-        let res_data = self.request.setting_dual_mode(coin_format, is_dual_mode).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let result = res_data_str.clone();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.message))
-        }
-    }
-    // 更新双持仓模式下杠杆
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let res_data = self.request.setting_dual_leverage(symbol_array[1].to_string().to_lowercase(), self.symbol.to_string(), leverage.to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let result = res_data_str.clone();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.message))
-        }
-    }
-    // 交易账户互转
-    async fn wallet_transfers(&mut self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error> {
-        let coin_format = coin.to_string().to_lowercase();
-        let res_data = self.request.wallet_transfers(coin_format.clone(), from.to_string(), to.to_string(), amount.to_string(), coin_format.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let result = res_data_str.clone();
-            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> {
         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
@@ -341,6 +306,42 @@ impl Platform for GateSwap {
             Err(Error::new(ErrorKind::Other, res_data.message))
         }
     }
+    // 设置持仓模式
+    async fn set_dual_mode(&mut self, coin: &str, is_dual_mode: bool) -> Result<String, Error> {
+        let coin_format = coin.to_string().to_lowercase();
+        let res_data = self.request.setting_dual_mode(coin_format, is_dual_mode).await;
+        if res_data.code == "200" {
+            let res_data_str = &res_data.data;
+            let result = res_data_str.clone();
+            Ok(result)
+        } else {
+            Err(Error::new(ErrorKind::Other, res_data.message))
+        }
+    }
+    // 更新双持仓模式下杠杆
+    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
+        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
+        let res_data = self.request.setting_dual_leverage(symbol_array[1].to_string().to_lowercase(), self.symbol.to_string(), leverage.to_string()).await;
+        if res_data.code == "200" {
+            let res_data_str = &res_data.data;
+            let result = res_data_str.clone();
+            Ok(result)
+        } else {
+            Err(Error::new(ErrorKind::Other, res_data.message))
+        }
+    }
+    // 交易账户互转
+    async fn wallet_transfers(&mut self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error> {
+        let coin_format = coin.to_string().to_lowercase();
+        let res_data = self.request.wallet_transfers(coin_format.clone(), from.to_string(), to.to_string(), amount.to_string(), coin_format.clone()).await;
+        if res_data.code == "200" {
+            let res_data_str = &res_data.data;
+            let result = res_data_str.clone();
+            Ok(result)
+        } else {
+            Err(Error::new(ErrorKind::Other, res_data.message))
+        }
+    }
     // 指令下单
     async fn command_order(&mut self, order_command: OrderCommand) {
         let mut handles = vec![];
@@ -431,7 +432,7 @@ pub fn format_position_item(position: &serde_json::Value, amount_size: Decimal)
         "single" => PositionModeEnum::Both,
         "dual_long" => PositionModeEnum::Long,
         "dual_short" => PositionModeEnum::Short,
-        _ => panic!("格式化Gate持仓模式错误!\nformat_position_item:position_mode={}", position["mode"])
+        _ => panic!("Gate:格式化持仓模式错误!\nformat_position_item:position_mode={}", position["mode"])
     };
     let size = Decimal::from_str(&position["size"].to_string()).unwrap();
     let amount = size * amount_size;
@@ -455,7 +456,7 @@ pub fn format_order_item(order: serde_json::Value, amount_size: Decimal) -> Orde
 
     let amount = size * amount_size;
     let deal_amount = (size - left) * amount_size;
-    let custom_status = if status == "finished" { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { panic!("格式化Gate订单状态错误!\nformat_order_item:status={}", status) };
+    let custom_status = if status == "finished" { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { panic!("Gate:格式化订单状态错误!\nformat_order_item:status={}", status) };
     Order {
         id: order["id"].to_string(),
         custom_id: text.replace("t-my-custom-id_", ""),

+ 35 - 34
standard/src/kucoin_handle.rs

@@ -1,3 +1,4 @@
+use std::str::FromStr;
 use rust_decimal::Decimal;
 use rust_decimal_macros::dec;
 use exchanges::response_base::ResponseData;
@@ -7,28 +8,28 @@ use crate::handle_info::HandleSwapInfo;
 
 // 处理账号信息
 pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
+    let symbol_format = symbol.to_uppercase();
     let res_data_str = res_data.data;
     let res_data_json: serde_json::Value = serde_json::from_str(&res_data_str).unwrap();
-    format_account_info(res_data_json, symbol)
+    format_account_info(res_data_json, symbol_format)
 }
 
 pub fn format_account_info(data: serde_json::Value, symbol: String) -> Account {
     let symbol_array: Vec<&str> = symbol.split("_").collect();
-    let mut available_balance = dec!(0);
-    let mut frozen_balance = dec!(0);
-    let mut balance = dec!(0);
     if data["data"]["currency"].as_str().unwrap() == symbol_array[1].to_string() && data["subject"].as_str().unwrap() == "availableBalance.change" {
-        available_balance = data["data"]["availableBalance"].to_string().parse().unwrap_or(dec!(0));
-        frozen_balance = data["data"]["holdBalance"].to_string().parse().unwrap_or(dec!(0));
-        balance = available_balance + frozen_balance;
-    }
-    Account {
-        balance,
-        available_balance,
-        frozen_balance,
-        stocks: dec!(0),
-        available_stocks: dec!(0),
-        frozen_stocks: dec!(0),
+        let available_balance = Decimal::from_str(&data["data"]["availableBalance"].to_string()).unwrap();
+        let frozen_balance = Decimal::from_str(&data["data"]["holdBalance"].to_string()).unwrap();
+        let balance = available_balance + frozen_balance;
+        Account {
+            balance,
+            available_balance,
+            frozen_balance,
+            stocks: dec!(0),
+            available_stocks: dec!(0),
+            frozen_stocks: dec!(0),
+        }
+    } else {
+        panic!("Kucoin:格式化账号信息错误!\nformat_account_info:data={}", data);
     }
 }
 
@@ -40,10 +41,10 @@ pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
 }
 
 pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let bp = data["bestBidPrice"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0));
-    let bq = data["bestBidSize"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0));
-    let ap = data["bestAskPrice"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0));
-    let aq = data["bestAskSize"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0));
+    let bp = Decimal::from_str(&data["bestBidPrice"].to_string()).unwrap();
+    let bq = Decimal::from_str(&data["bestBidSize"].to_string()).unwrap();
+    let ap = Decimal::from_str(&data["bestAskPrice"].to_string()).unwrap();
+    let aq = Decimal::from_str(&data["bestAskSize"].to_string()).unwrap();
     let mp = (bp + ap) * dec!(0.5);
 
     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp };
@@ -68,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 = position["currentQty"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0));
+    let current_qty = Decimal::from_str(position["currentQty"].as_str().unwrap()).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: position["realLeverage"].as_str().unwrap_or("1").parse().unwrap_or(dec!(1)),
+        margin_level: Decimal::from_str(position["realLeverage"].as_str().unwrap()).unwrap(),
         amount: amount.abs(),
         frozen_amount: dec!(0),
-        price: position["avgEntryPrice"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0)),
-        profit: position["unrealisedPnl"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0)),
+        price: Decimal::from_str(position["avgEntryPrice"].as_str().unwrap()).unwrap(),
+        profit: Decimal::from_str(position["unrealisedPnl"].as_str().unwrap()).unwrap(),
         position_mode,
-        margin: position["posMargin"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0)),
+        margin: Decimal::from_str(position["posMargin"].as_str().unwrap()).unwrap(),
     }
 }
 
@@ -98,25 +99,25 @@ pub fn handle_order(res_data: ResponseData, amount_size: Decimal) -> SpecialOrde
 }
 
 pub fn format_order_item(order: serde_json::Value, amount_size: Decimal) -> Order {
-    let price = order["price"].as_str().unwrap_or("0").parse().unwrap_or(dec!(0));
-    let size = order["size"].to_string().parse().unwrap_or(dec!(0));
+    let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
+    let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
     let status = order["status"].as_str().unwrap_or("");
-    let filled_size = order["filledSize"].to_string().parse().unwrap_or(dec!(0));
-    let match_price = order["matchPrice"].to_string().parse().unwrap_or(dec!(0));
+    let filled_size = Decimal::from_str(order["filledSize"].as_str().unwrap()).unwrap();
+    let match_price = Decimal::from_str(order["matchPrice"].as_str().unwrap()).unwrap();
 
     let amount = size * amount_size;
     let deal_amount = filled_size * amount_size;
     let avg_price = if status == "match" { match_price } else { price };
-    let custom_status = if ["done", "match"].contains(&status) { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { "OTHER".to_string() };
+    let custom_status = if ["done", "match"].contains(&status) { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { panic!("Kucoin:格式化订单状态错误!\nformat_order_item:status={}", status); };
     Order {
-        id: order["id"].as_str().unwrap_or("").parse().unwrap(),
-        custom_id: order["clientOid"].as_str().unwrap_or("").parse().unwrap(),
+        id: order["id"].as_str().unwrap().to_string(),
+        custom_id: order["clientOid"].as_str().unwrap().to_string(),
         price,
         amount,
         deal_amount,
         avg_price,
         status: custom_status,
-        order_type: order["type"].as_str().unwrap_or("").parse().unwrap(),
+        order_type: order["type"].as_str().unwrap().to_string(),
     }
 }
 
@@ -129,8 +130,8 @@ pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
     let mut depth_items: Vec<MarketOrder> = vec![];
     for value in value.as_array().unwrap() {
         depth_items.push(MarketOrder {
-            price: value[0].as_str().unwrap_or("0").parse().unwrap_or(dec!(0)),
-            amount: value[1].to_string().parse().unwrap_or(dec!(0)),
+            price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
+            amount: Decimal::from_str(&value[1].to_string()).unwrap(),
         })
     }
     return depth_items;

+ 71 - 48
standard/src/kucoin_swap.rs

@@ -88,8 +88,8 @@ impl Platform for KucoinSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-            let balance = res_data_json["accountEquity"].to_string().parse().unwrap_or(dec!(0));
-            let available_balance = res_data_json["availableBalance"].to_string().parse().unwrap_or(dec!(0));
+            let balance = Decimal::from_str(&res_data_json["accountEquity"].to_string()).unwrap();
+            let available_balance = Decimal::from_str(&res_data_json["availableBalance"].to_string()).unwrap();
             let frozen_balance = balance - available_balance;
             let result = Account {
                 balance,
@@ -143,12 +143,12 @@ 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: ticker_info["bestAskPrice"].to_string().parse().unwrap_or(dec!(0)),
-                low: ticker_info["bestBidPrice"].to_string().parse().unwrap_or(dec!(0)),
-                sell: ticker_info["bestAskPrice"].to_string().parse().unwrap_or(dec!(0)),
-                buy: ticker_info["bestBidPrice"].to_string().parse().unwrap_or(dec!(0)),
-                last: ticker_info["price"].to_string().parse().unwrap_or(dec!(0)),
-                volume: ticker_info["size"].to_string().parse().unwrap_or(dec!(0)),
+                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(),
+                volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
             };
             Ok(result)
         } else {
@@ -162,28 +162,36 @@ impl Platform for KucoinSwap {
         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 default_info = json!({});
-            let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format).unwrap_or(&default_info);
-            let tick_size = market_info["tickSize"].to_string().parse().unwrap_or(dec!(0));
-            let amount_size = market_info["multiplier"].to_string().parse().unwrap_or(dec!(0));
-            let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-            let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
+            let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
+            match market_info {
+                None => {
+                    panic!("Kucoin:获取Market信息错误!\nget_market:res_data={}", res_data_str)
+                }
+                Some(value) => {
+                    let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
+                    let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
+                    let tick_size = Decimal::from_str(&value["tickSize"].to_string()).unwrap();
+                    let amount_size = Decimal::from_str(&value["multiplier"].to_string()).unwrap();
+                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
+                    let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
 
-            let result = Market {
-                symbol: self.symbol.clone(),
-                base_asset: market_info["baseCurrency"].as_str().unwrap_or("").to_string(),
-                quote_asset: market_info["quoteCurrency"].as_str().unwrap_or("").to_string(),
-                tick_size: market_info["tickSize"].to_string().parse().unwrap_or(dec!(0)),
-                amount_size: market_info["multiplier"].to_string().parse().unwrap_or(dec!(0)),
-                price_precision,
-                amount_precision,
-                min_qty: market_info["lotSize"].to_string().parse().unwrap_or(dec!(0)),
-                max_qty: market_info["maxOrderQty"].to_string().parse().unwrap_or(dec!(0)),
-                min_notional: Default::default(),
-                max_notional: market_info["maxPrice"].to_string().parse().unwrap_or(dec!(0)),
-                ct_val: Default::default(),
-            };
-            Ok(result)
+                    let result = Market {
+                        symbol: format!("{}_{}", base_asset, quote_asset),
+                        base_asset,
+                        quote_asset,
+                        tick_size,
+                        amount_size,
+                        price_precision,
+                        amount_precision,
+                        min_qty: Decimal::from_str(&value["lotSize"].to_string()).unwrap(),
+                        max_qty: Decimal::from_str(&value["maxOrderQty"].to_string()).unwrap(),
+                        min_notional: Default::default(),
+                        max_notional: Decimal::from_str(&value["maxPrice"].to_string()).unwrap(),
+                        ct_val: Default::default(),
+                    };
+                    Ok(result)
+                }
+            }
         } else {
             Err(Error::new(ErrorKind::Other, res_data.message))
         }
@@ -195,7 +203,7 @@ impl Platform for KucoinSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-            let result = kucoin_handle::format_order_item(res_data_json, amount_size);
+            let result = format_order_item(res_data_json, amount_size);
             Ok(result)
         } else {
             Err(Error::new(ErrorKind::Other, res_data.message))
@@ -210,25 +218,13 @@ impl Platform for KucoinSwap {
             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 result = order_info.iter().map(|&item| kucoin_handle::format_order_item(item.clone(), amount_size)).collect();
+            let result = order_info.iter().map(|&item| format_order_item(item.clone(), amount_size)).collect();
             Ok(result)
         } else {
             Err(Error::new(ErrorKind::Other, res_data.message))
         }
     }
 
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-        todo!()
-    }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        todo!()
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        todo!()
-    }
-
     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
         let symbol_format = format!("{}M", utils::format_symbol(self.symbol.clone(), ""));
         let amount_size = self.market.amount_size;
@@ -260,7 +256,7 @@ impl Platform for KucoinSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-            let result = kucoin_handle::format_order_item(res_data_json, amount_size);
+            let result = format_order_item(res_data_json, amount_size);
             Ok(result)
         } else {
             Err(Error::new(ErrorKind::Other, res_data.message))
@@ -273,16 +269,20 @@ impl Platform for KucoinSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-            let result = kucoin_handle::format_order_item(res_data_json, amount_size);
+            let result = format_order_item(res_data_json, amount_size);
             Ok(result)
         } else {
             Err(Error::new(ErrorKind::Other, res_data.message))
         }
     }
 
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        todo!()
-    }
+    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { todo!() }
+
+    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
+
+    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { todo!() }
+
+    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
 
     // 指令下单
     async fn command_order(&mut self, order_command: OrderCommand) {
@@ -368,3 +368,26 @@ impl Platform for KucoinSwap {
         let _: Result<Vec<_>, _> = futures.try_collect().await;
     }
 }
+
+pub fn format_order_item(order: serde_json::Value, amount_size: Decimal) -> 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 amount = size * amount_size;
+    let deal_amount = filled_size * amount_size;
+    let avg_price = if deal_amount.is_zero() { dec!(0) } else { filled_value / deal_amount };
+    let custom_status = if ["done", "match"].contains(&status) { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { panic!("Kucoin:格式化订单状态错误!\nformat_order_item:status={}", status); };
+    Order {
+        id: order["id"].as_str().unwrap().to_string(),
+        custom_id: order["clientOid"].as_str().unwrap().to_string(),
+        price,
+        amount,
+        deal_amount,
+        avg_price,
+        status: custom_status,
+        order_type: order["type"].as_str().unwrap().to_string(),
+    }
+}

+ 6 - 6
standard/src/lib.rs

@@ -494,18 +494,18 @@ pub trait Platform {
     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error>;
     // 获取订单列表
     async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error>;
-    // 设置持仓模式
-    async fn set_dual_mode(&mut self, coin: &str, is_dual_mode: bool) -> Result<String, Error>;
-    // 更新双持仓模式下杠杆
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error>;
-    // 交易账户互转
-    async fn wallet_transfers(&mut self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error>;
     // 下单接口
     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error>;
     // 撤销订单
     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error>;
     // 批量撤销订单
     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error>;
+    // 设置持仓模式
+    async fn set_dual_mode(&mut self, coin: &str, is_dual_mode: bool) -> Result<String, Error>;
+    // 更新双持仓模式下杠杆
+    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error>;
+    // 交易账户互转
+    async fn wallet_transfers(&mut self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error>;
     // 指令下单
     async fn command_order(&mut self, order_command: OrderCommand);
 }

+ 61 - 0
standard/tests/exchange_test.rs

@@ -0,0 +1,61 @@
+use std::collections::BTreeMap;
+use std::env;
+use std::io::Error;
+use tokio::sync::mpsc;
+use tracing::trace;
+use exchanges::proxy;
+use standard::exchange::{Exchange, ExchangeEnum};
+use standard::{Order, Platform};
+
+// 创建实体
+pub async fn test_new_exchange(exchange: ExchangeEnum) -> Box<dyn Platform> {
+    if proxy::ParsingDetail::http_enable_proxy() {
+        trace!("检测有代理配置,配置走代理");
+    }
+    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);
+    match exchange {
+        ExchangeEnum::BinanceSwap => {
+            let mut params: BTreeMap<String, String> = BTreeMap::new();
+            let access_key = env::var("binance_access_key").unwrap_or("".to_string());
+            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
+        }
+        ExchangeEnum::BinanceSpot => {
+            let mut params: BTreeMap<String, String> = BTreeMap::new();
+            let access_key = env::var("binance_access_key").unwrap_or("".to_string());
+            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
+        }
+        ExchangeEnum::GateSwap => {
+            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);
+            Exchange::new(exchange, "BLZ_USDT".to_string(), false, params, order_sender, error_sender).await
+        }
+        ExchangeEnum::GateSpot => {
+            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);
+            Exchange::new(exchange, "ROSE_USDT".to_string(), false, params, order_sender, error_sender).await
+        }
+        ExchangeEnum::KucoinSwap => {
+            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);
+            Exchange::new(exchange, "ROSE_USDT".to_string(), false, params, order_sender, error_sender).await
+        }
+    }
+}

+ 2 - 111
standard/tests/libs_test.rs

@@ -1,7 +1,6 @@
 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 exchanges::proxy;
@@ -39,7 +38,7 @@ 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, "BTC_USDT".to_string(), false, params, order_sender, error_sender).await
+            Exchange::new(exchange, "BLZ_USDT".to_string(), false, params, order_sender, error_sender).await
         }
         ExchangeEnum::GateSpot => {
             let mut params: BTreeMap<String, String> = BTreeMap::new();
@@ -147,7 +146,7 @@ async fn test_replace_symbol() {
     trace!(?format_symbol);
 }
 
-// 测试Binance期货K线推送
+// 测试Binance获取账号信息
 #[tokio::test]
 #[instrument(level = "TRACE")]
 async fn test_get_account() {
@@ -164,115 +163,7 @@ async fn test_get_account() {
     trace!(?kucoin_account);
 }
 
-// 测试Gate 获取持仓信息
-#[tokio::test]
-#[instrument(level = "TRACE")]
-async fn test_gate_swap_get_position() {
-    global::log_utils::init_log_with_trace();
-
-    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap).await;
-    let gate_get_position = gate_swap_exchange.get_position().await;
-    trace!(?gate_get_position);
-}
-
-// 测试Gate 获取所有持仓信息
-#[tokio::test]
-#[instrument(level = "TRACE")]
-async fn test_gate_swap_get_positions() {
-    global::log_utils::init_log_with_trace();
-
-    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap).await;
-    let gate_get_positions = gate_swap_exchange.get_positions().await;
-    trace!(?gate_get_positions);
-}
-
-// 测试Gate获取Ticker信息
-#[tokio::test]
-#[instrument(level = "TRACE")]
-async fn test_gate_swap_get_ticker() {
-    global::log_utils::init_log_with_trace();
-
-    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap).await;
-    let gate_get_ticker = gate_swap_exchange.get_ticker().await;
-    trace!(?gate_get_ticker);
-}
-
-// 测试Gate获取Market信息
-#[tokio::test]
-#[instrument(level = "TRACE")]
-async fn test_gate_swap_get_market() {
-    global::log_utils::init_log_with_trace();
-
-    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap).await;
-    let gate_get_market = gate_swap_exchange.get_market().await;
-    trace!(?gate_get_market);
-}
-
-// 测试Gate获取Order详情信息
-#[tokio::test]
-#[instrument(level = "TRACE")]
-async fn test_gate_swap_get_order_detail() {
-    global::log_utils::init_log_with_trace();
-
-    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap).await;
-    let gate_get_order_detail = gate_swap_exchange.get_order_detail("336321097375", "").await;
-    trace!(?gate_get_order_detail);
-}
 
-// 测试Gate获取Order列表信息
-#[tokio::test]
-#[instrument(level = "TRACE")]
-async fn test_gate_swap_get_orders_list() {
-    global::log_utils::init_log_with_trace();
-
-    let mut gate_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::GateSwap).await;
-    let gate_get_orders_list = gate_swap_exchange.get_orders_list("finished").await;
-    trace!(?gate_get_orders_list);
-}
-
-// 测试Gate 设置持仓模式
-#[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).await;
-    let gate_set_dual_mode = gate_swap_exchange.set_dual_mode("usdt", true).await;
-    trace!(?gate_set_dual_mode);
-}
-
-// 测试Gate 设置持仓模式
-#[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).await;
-    let gate_set_dual_leverage = gate_swap_exchange.set_dual_leverage("10").await;
-    trace!(?gate_set_dual_leverage);
-}
-
-// 测试Gate 测试下单
-#[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).await;
-    let gate_take_order = gate_swap_exchange.take_order("123", "kd", dec!(25000), dec!(0.0001)).await;
-    trace!(?gate_take_order);
-}
-
-// 测试Gate 撤销订单
-#[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).await;
-    let gate_cancel_order = gate_swap_exchange.cancel_order("", "123").await;
-    trace!(?gate_cancel_order);
-}
 
 // 测试kucoin 获取持仓信息
 #[tokio::test]