Browse Source

改造完成,能测试通过了,等会睡了起来测试。

skyffire 1 year ago
parent
commit
ad60ac92b7

+ 36 - 36
exchanges/src/binance_swap_rest.rs

@@ -7,9 +7,9 @@ use rust_decimal::prelude::FromPrimitive;
 use rust_decimal_macros::dec;
 use crate::http_tool::RestTool;
 use crate::response_base::ResponseData;
-use tracing::{info, trace};
+use tracing::{error, info, trace};
 use ring::hmac;
-use serde_json::json;
+use serde_json::{json, Value};
 
 #[derive(Clone)]
 pub struct BinanceSwapRest {
@@ -360,17 +360,18 @@ impl BinanceSwapRest {
 
         trace!("headers:{:?}", headers);
         let start_time = chrono::Utc::now().timestamp_millis();
-        let get_response = self.http_toll(
+        let response = self.http_toll(
             format!("{}{}", prefix_url.clone(), request_url.clone()),
             request_type.to_string(),
             params_json.to_string(),
             headers,
         ).await;
+
         let time_array = chrono::Utc::now().timestamp_millis() - start_time;
         self.delays.push(time_array);
         self.get_delay_info();
-        let res_data = Self::res_data_analysis(get_response, params_json.to_string());
-        res_data
+
+        response
     }
 
     pub fn headers(access_key: String) -> HeaderMap {
@@ -393,8 +394,7 @@ impl BinanceSwapRest {
     }
 
 
-    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        let res_data: ResponseData;
+    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> ResponseData {
         /****请求接口与 地址*/
         let url = format!("{}{}", self.base_url.to_string(), request_path);
         let request_type = request_type.clone().to_uppercase();
@@ -409,47 +409,47 @@ impl BinanceSwapRest {
         trace!("body:{:?}",params);
 
 
-        let req = match request_type.as_str() {
+        let request_builder = match request_type.as_str() {
             "GET" => self.client.get(url.clone()).query(&params_json).headers(headers),
             "POST" => self.client.post(url.clone()).query(&params_json).headers(headers),
             "DELETE" => self.client.delete(url.clone()).query(&params_json).headers(headers),
             // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
+            _ => {
+                panic!("{}", format!("错误的请求类型:{}", request_type.clone()))
+            }
         };
 
-        let response = req.send().await?;
-        if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await?;
-            // trace!("ok-----{}", body);
-            res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
+        let response = request_builder.send().await.unwrap();
+        let is_success = response.status().is_success(); // 先检查状态码
+        let text = response.text().await.unwrap();
+        return if is_success {
+            self.on_success_data(text)
         } else {
-            let body = response.text().await?;
-            // trace!("error-----{}", body);
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
+            self.on_error_data(text, addrs_url, params)
         }
+    }
 
-        Ok(res_data)
+    pub fn on_success_data(&mut self, text: String) -> ResponseData {
+        let data = serde_json::from_str(text.as_str()).unwrap();
+
+        ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), data)
     }
 
-    //res_data 解析
-    pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, params: String) -> ResponseData {
-        match result {
-            Ok(res_data) => {
-                if res_data.code != "200" {
-                    let message = res_data.message;
-                    let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
-                    let msg = json_value["msg"].as_str().unwrap();
-                    let mut error = ResponseData::error(res_data.label, msg.parse().unwrap());
-                    error.code = format!("{}", json_value["code"]);
-                    error.data = format!("参数:{}", params);
-                    error
-                } else {
-                    res_data
-                }
+    pub fn on_error_data(&mut self, text: String, base_url: String, params: String) -> ResponseData {
+        let json_value = serde_json::from_str::<Value>(&text);
+
+        match json_value {
+            Ok(data) => {
+                let message = data["msg"].as_str().unwrap();
+
+                let mut error = ResponseData::error(self.label.clone(), message.to_string());
+                error.code = data["code"].to_string();
+                error.message = format!("请求地址:{}, 请求参数:{}", base_url, params);
+                error
             }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", err, params));
+            Err(e) => {
+                error!("解析错误:{:?}", e);
+                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", e, text));
                 error
             }
         }

+ 825 - 825
exchanges/src/bitget_spot_rest.rs

@@ -1,825 +1,825 @@
-use std::collections::BTreeMap;
-use reqwest::header::HeaderMap;
-use reqwest::{Client};
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use tracing::{info, trace};
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-use ring::hmac;
-use serde_json::Value;
-
-#[derive(Clone, Debug)]
-pub struct BitgetSpotRest {
-    pub label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //是否需要登陆
-    //登陆所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-
-}
-
-impl BitgetSpotRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSpotRest
-    {
-        return BitgetSpotRest::new_label("default-BitgetSpotRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSpotRest {
-        let base_url = if is_colo {
-            "https://api.bitget.com".to_string()
-        } else {
-            "https://api.bitget.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",base_url);
-        } else {
-            info!("走普通通道:{}",base_url);
-        }
-        /*****返回结构体*******/
-        BitgetSpotRest {
-            label,
-            base_url,
-            client: Client::new(),
-            login_param,
-            delays: vec![],
-            max_delay: 0,
-            avg_delay: dec!(0.0),
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************rest请求函数********************************************************/
-    /*******************************************************************************************************/
-    //获取系统时间
-    pub async fn get_server_time(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/public/time".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //账户信息
-    pub async fn get_account_info(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/account/info".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取账户币种资产
-    pub async fn get_account_assets(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/account/assets".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取币种信息
-    pub async fn get_coins(&mut self, coin: String) -> ResponseData {
-        let params = serde_json::json!({
-            "coin":coin
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/public/coins".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取交易对信息
-    pub async fn get_symbols(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/public/symbols".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取现货VIP费率
-    pub async fn get_vip_fee_rate(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/market/vip-fee-rate".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取行情信息
-    pub async fn get_tickers(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/market/tickers".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取合并交易深度
-    pub async fn get_merge_depth(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/market/merge-depth".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取K线数据
-    //参数:granularity: K线的时间颗粒度
-    //                   分钟:1min,5min,15min,30min
-    //                   小时:1h,4h,6h,12h
-    //                   天:1day,3day
-    //                   周:1week
-    //                   月:1M
-    //                   零时区小时线:6Hutc,12Hutc
-    //                   零时区日线:1Dutc ,3Dutc
-    //                   零时区周线:1Wutc
-    //                   零时区月线:1Mutc
-    //                   1m、3m、5m可以查一个月 ;15m可以查52天; 30m查62天; 1H可以查83天; 2H可以查120天; 4H可以查240天; 6H可以查360天
-    //start_time :K线数据的时间起始点,即获取该时间戳以后的K线数据 Unix毫秒时间戳,例如1690196141868
-    //end_time :K线数据的时间终止点,即获取该时间戳以前的K线数据 Unix毫秒时间戳,例如1690196141868
-    //limit :查询条数  默认100,最大1000
-    pub async fn get_candles(&mut self, symbol: String, granularity: String, start_time: String, end_time: String, limit: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "granularity":granularity,
-            "startTime":start_time,
-            "endTime":end_time,
-            "limit":limit,
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/market/candles".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取历史K线数据
-    pub async fn get_history_candles(&mut self, symbol: String, granularity: String, end_time: String, limit: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "granularity":granularity,
-            "endTime":end_time,
-            "limit":limit,
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/market/history-candles".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取最近成交数据
-    pub async fn get_market_fills(&mut self, symbol: String, limit: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "limit":limit,
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/market/fills".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取历史成交数据
-    pub async fn get_market_fills_history(&mut self, symbol: String, start_time: String, end_time: String, limit: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-            "limit": "1000"
-         });
-        if start_time.len() > 0 {
-            params["startTime"] = serde_json::json!(start_time);
-        }
-        if end_time.len() > 0 {
-            params["endTime"] = serde_json::json!(end_time);
-        }
-        if limit.len() > 0 {
-            params["limit"] = serde_json::json!(limit);
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/market/fills-history".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //下单
-    pub async fn spot_order(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/place-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //批量下单
-    pub async fn spot_orders(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/batch-orders".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //撤单
-    pub async fn spot_cancel_order(&mut self, symbol: String, order_id: String, client_oid: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-         });
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        if client_oid.len() > 0 {
-            params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
-        }
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/cancel-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //批量撤单
-    pub async fn spot_cancel_orders(&mut self, symbol: String, order_list: Vec<Value>) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "orderList":order_list,
-         });
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/batch-cancel-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //按币对撤单
-    pub async fn spot_cancel_symbol_orders(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-         });
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/cancel-symbol-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取订单详情
-    pub async fn get_order(&mut self, order_id: String, client_oid: String) -> ResponseData {
-        let params = serde_json::json!({
-            "orderId":order_id,
-            "clientOid":client_oid,
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/orderInfo".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取当前委托列表
-    pub async fn get_unfilled_orders(&mut self,
-                                     symbol: String,
-                                     start_time: String,
-                                     end_time: String,
-                                     id_less_than: String,
-                                     limit: String,
-                                     order_id: String,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-         });
-        if start_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-        }
-        if end_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-        }
-        if id_less_than.len() > 0 {
-            params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-        }
-        if limit.len() > 0 {
-            params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
-        }
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/unfilled-orders".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取历史委托列表
-    pub async fn get_history_orders(&mut self,
-                                    symbol: String,
-                                    start_time: String,
-                                    end_time: String,
-                                    id_less_than: String,
-                                    limit: String,
-                                    order_id: String,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-         });
-        if start_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-        }
-        if end_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-        }
-        if id_less_than.len() > 0 {
-            params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-        }
-        if limit.len() > 0 {
-            params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
-        }
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/history-orders".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //获取成交明细
-    pub async fn get_fills(&mut self,
-                           symbol: String,
-                           order_id: String,
-                           start_time: String,
-                           end_time: String,
-                           limit: String,
-                           id_less_than: String,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-         });
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        if start_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-        }
-        if end_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-        }
-        if limit.len() > 0 {
-            params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
-        }
-        if id_less_than.len() > 0 {
-            params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/fills".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //下单计划委托
-    pub async fn spot_place_plan_order(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/place-plan-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //修改计划委托
-    pub async fn update_place_plan_order(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/modify-plan-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //撤销计划委托
-    pub async fn cancel_plan_order(&mut self, order_id: String, client_oid: String) -> ResponseData {
-        let mut params = serde_json::json!({
-         });
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        if client_oid.len() > 0 {
-            params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
-        }
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/cancel-plan-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取当前计划委托
-    pub async fn get_current_plan_order(&mut self,
-                                        symbol: String,
-                                        limit: String,
-                                        id_less_than: String,
-                                        start_time: String,
-                                        end_time: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-            "limit":limit,
-         });
-
-
-        if id_less_than.len() > 0 {
-            params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-        }
-        if start_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-        }
-        if end_time.len() > 0 {
-            params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/current-plan-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取历史计划委托
-    pub async fn get_history_plan_order(&mut self,
-                                        symbol: String,
-                                        start_time: String,
-                                        end_time: String,
-                                        limit: String,
-    ) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "startTime":start_time,
-            "endTime":end_time,
-            "limit":limit,
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/history-plan-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //批量撤销计划委托
-    pub async fn cancel_plan_orders(&mut self, symbol_list: Vec<String>) -> ResponseData {
-        let mut params = serde_json::json!({
-         });
-        if symbol_list.len() > 0 {
-            params.as_object_mut().unwrap().insert("symbolList".parse().unwrap(), serde_json::Value::from(symbol_list));
-        }
-        let data = self.request("POST".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/trade/batch-cancel-plan-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //划转
-    pub async fn wallet_transfer(&mut self,
-                                 from_type: String,
-                                 to_type: String,
-                                 amount: String,
-                                 coin: String,
-                                 symbol: String,
-                                 client_oid: String,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-                   "fromType":from_type ,
-                   "toType":to_type ,
-                   "amount":amount ,
-                   "coin":coin ,
-         });
-        if symbol.len() > 0 {
-            params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
-        }
-        if client_oid.len() > 0 {
-            params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/wallet/transfer".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取账单流水
-    pub async fn get_account_bills(&mut self,
-                                   coin: String,
-                                   limit: String,
-                                   start_time: String,
-                                   end_time: String,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-                   "coin":coin ,
-                   "groupType":"transaction" ,
-                   "limit":limit ,
-
-         });
-        if start_time.len() > 0 {
-            params["startTime"] = serde_json::json!(start_time);
-        }
-        if end_time.len() > 0 {
-            params["endTime"] = serde_json::json!(end_time);
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/spot/account/bills".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        self.delays.clone()
-    }
-    pub fn get_avg_delay(&self) -> Decimal {
-        self.avg_delay.clone()
-    }
-    pub fn get_max_delay(&self) -> i64 {
-        self.max_delay.clone()
-    }
-    fn get_delay_info(&mut self) {
-        let last_100 = if self.delays.len() > 100 {
-            self.delays[self.delays.len() - 100..].to_vec()
-        } else {
-            self.delays.clone()
-        };
-
-        let max_value = last_100.iter().max().unwrap();
-        if max_value.clone().to_owned() > self.max_delay {
-            self.max_delay = max_value.clone().to_owned();
-        }
-
-        let sum: i64 = last_100.iter().sum();
-        let sum_v = Decimal::from_i64(sum).unwrap();
-        let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
-        self.avg_delay = (sum_v / len_v).round_dp(1);
-        self.delays = last_100.clone().into_iter().collect();
-    }
-    //调用请求
-    pub async fn request(&mut self,
-                         method: String,
-                         prefix_url: String,
-                         request_url: String,
-                         is_login: bool,
-                         params: String) -> ResponseData
-    {
-        trace!("login_param:{:?}", self.login_param);
-        //解析账号信息
-        let mut access_key = "".to_string();
-        let mut secret_key = "".to_string();
-        let mut passphrase = "".to_string();
-        if self.login_param.contains_key("access_key") {
-            access_key = self.login_param.get("access_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("secret_key") {
-            secret_key = self.login_param.get("secret_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("pass_key") {
-            passphrase = self.login_param.get("pass_key").unwrap().to_string();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" || passphrase == "" {
-            is_login_param = false
-        }
-
-
-        //请求头配置-如果需要登陆则存在额外配置
-        let mut body = "".to_string();
-        let timestamp = Self::get_timestamp();
-        let mut headers = HeaderMap::new();
-        headers.insert("Content-Type", "application/json".parse().unwrap());
-        headers.insert("locale", "en-US".parse().unwrap());
-        if method == "POST" {
-            body = params.clone();
-        }
-
-
-        //是否需要登陆-- 组装sing
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
-                return e;
-            } else {
-                //需要登陆-且登陆参数齐全
-                trace!("param:{}", params);
-                trace!("body:{}", body);
-                //组装sing
-                let sing = Self::sign(secret_key.clone(),
-                                      method.clone(),
-                                      prefix_url.clone(),
-                                      request_url.clone(),
-                                      params.clone(),
-                                      body.clone(),
-                                      timestamp.clone(),
-                );
-                //组装header
-                headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
-            }
-        }
-
-
-        // trace!("headers:{:?}", headers);
-        let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let get_response = self.http_toll(
-            format!("{}{}", prefix_url.clone(), request_url.clone()),
-            method.to_string(),
-            params.clone(),
-            headers,
-        ).await;
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        self.get_delay_info();
-        let res_data = Self::res_data_analysis(get_response, base_url, params);
-        res_data
-    }
-
-    pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("ACCESS-KEY", access_key.parse().unwrap());
-        headers.insert("ACCESS-SIGN", sign.parse().unwrap());
-        headers.insert("ACCESS-TIMESTAMP", timestamp.parse().unwrap());
-        headers.insert("ACCESS-PASSPHRASE", passphrase.parse().unwrap());
-        headers
-    }
-    pub fn sign(secret_key: String,
-                method: String, prefix_url: String, request_url: String,
-                params: String, body: String, timestamp: String) -> String
-    {
-        /*签名生成*/
-        let url_param_str = RestTool::parse_params_to_str(params);
-        let base_url = if method == "GET" && url_param_str.len() > 0 {
-            format!("{}{}?{}", prefix_url, request_url, url_param_str)
-        } else {
-            format!("{}{}", prefix_url, request_url)
-        };
-
-        // 时间戳 + 请求类型+ 请求参数字符串
-        let message = format!("{}{}{}{}", timestamp, method, base_url, body);
-        trace!("message:{}",message);
-
-        // 做签名
-        let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-        let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-        let sign = base64::encode(result);
-        sign
-    }
-
-    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        let res_data: ResponseData;
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-        let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
-            url.clone()
-        } else {
-            format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
-        };
-        trace!("url:{}", url);
-        trace!("addrs_url:{}", addrs_url);
-        let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-        trace!("params_json:{}",params_json);
-        trace!("headers:{:?}",headers);
-
-
-        let req = match request_type.as_str() {
-            "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(url.clone()).body(params).headers(headers),
-            "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
-        };
-
-        let response = req.send().await?;
-        if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await?;
-            // trace!("ok-----{}", body);
-            res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
-        } else {
-            let body = response.text().await?;
-            // trace!("error-----{}", body);
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
-        }
-
-        Ok(res_data)
-    }
-
-
-    //res_data 解析
-    pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-        // trace!("原始数据:{:?}",result);
-        match result {
-            Ok(res_data) => {
-                if res_data.code != "200" {
-                    // trace!("不等于200");
-                    let message: String = res_data.message;
-                    let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
-                    let code = json_value["code"].as_str().unwrap();
-                    let msg = json_value["msg"].as_str().unwrap();
-                    let error = ResponseData::new("".to_string(),
-                                                  format!("{}", code),
-                                                  format!("{}", msg),
-                                                  format!("请求地址:{},请求参数:{}", base_url, params));
-                    error
-                } else {
-                    // trace!("等于200");
-                    let body: String = res_data.data;
-                    let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
-
-                    let code = json_value["code"].as_str().unwrap();
-                    if code == "00000" {
-                        let data = serde_json::to_string(&json_value["data"]).unwrap();
-                        let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
-                        success
-                    } else {
-                        let msg = json_value["msg"].as_str().unwrap();
-                        // trace!("发生错误:??{:?}",data_json.to_string());
-                        let error = ResponseData::new("".to_string(),
-                                                      format!("{}", code),
-                                                      format!("{}", msg),
-                                                      format!("请求地址:{},请求参数:{}", base_url, params));
-                        error
-                    }
-                }
-            }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
-                error
-            }
-        }
-    }
-    fn get_timestamp() -> String {
-        chrono::Utc::now().timestamp_millis().to_string()
-    }
-}
+// use std::collections::BTreeMap;
+// use reqwest::header::HeaderMap;
+// use reqwest::{Client};
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use rust_decimal_macros::dec;
+// use tracing::{info, trace};
+// use crate::http_tool::RestTool;
+// use crate::response_base::ResponseData;
+// use ring::hmac;
+// use serde_json::Value;
+//
+// #[derive(Clone, Debug)]
+// pub struct BitgetSpotRest {
+//     pub label: String,
+//     base_url: String,
+//     client: reqwest::Client,
+//     /*******参数*/
+//     //是否需要登陆
+//     //登陆所需参数
+//     login_param: BTreeMap<String, String>,
+//     delays: Vec<i64>,
+//     max_delay: i64,
+//     avg_delay: Decimal,
+//
+// }
+//
+// impl BitgetSpotRest {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//
+//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSpotRest
+//     {
+//         return BitgetSpotRest::new_label("default-BitgetSpotRest".to_string(), is_colo, login_param);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSpotRest {
+//         let base_url = if is_colo {
+//             "https://api.bitget.com".to_string()
+//         } else {
+//             "https://api.bitget.com".to_string()
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",base_url);
+//         } else {
+//             info!("走普通通道:{}",base_url);
+//         }
+//         /*****返回结构体*******/
+//         BitgetSpotRest {
+//             label,
+//             base_url,
+//             client: Client::new(),
+//             login_param,
+//             delays: vec![],
+//             max_delay: 0,
+//             avg_delay: dec!(0.0),
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************rest请求函数********************************************************/
+//     /*******************************************************************************************************/
+//     //获取系统时间
+//     pub async fn get_server_time(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/public/time".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //账户信息
+//     pub async fn get_account_info(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/account/info".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取账户币种资产
+//     pub async fn get_account_assets(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/account/assets".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取币种信息
+//     pub async fn get_coins(&mut self, coin: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "coin":coin
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/public/coins".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取交易对信息
+//     pub async fn get_symbols(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/public/symbols".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取现货VIP费率
+//     pub async fn get_vip_fee_rate(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/market/vip-fee-rate".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取行情信息
+//     pub async fn get_tickers(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/market/tickers".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取合并交易深度
+//     pub async fn get_merge_depth(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/market/merge-depth".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取K线数据
+//     //参数:granularity: K线的时间颗粒度
+//     //                   分钟:1min,5min,15min,30min
+//     //                   小时:1h,4h,6h,12h
+//     //                   天:1day,3day
+//     //                   周:1week
+//     //                   月:1M
+//     //                   零时区小时线:6Hutc,12Hutc
+//     //                   零时区日线:1Dutc ,3Dutc
+//     //                   零时区周线:1Wutc
+//     //                   零时区月线:1Mutc
+//     //                   1m、3m、5m可以查一个月 ;15m可以查52天; 30m查62天; 1H可以查83天; 2H可以查120天; 4H可以查240天; 6H可以查360天
+//     //start_time :K线数据的时间起始点,即获取该时间戳以后的K线数据 Unix毫秒时间戳,例如1690196141868
+//     //end_time :K线数据的时间终止点,即获取该时间戳以前的K线数据 Unix毫秒时间戳,例如1690196141868
+//     //limit :查询条数  默认100,最大1000
+//     pub async fn get_candles(&mut self, symbol: String, granularity: String, start_time: String, end_time: String, limit: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol,
+//             "granularity":granularity,
+//             "startTime":start_time,
+//             "endTime":end_time,
+//             "limit":limit,
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/market/candles".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取历史K线数据
+//     pub async fn get_history_candles(&mut self, symbol: String, granularity: String, end_time: String, limit: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol,
+//             "granularity":granularity,
+//             "endTime":end_time,
+//             "limit":limit,
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/market/history-candles".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取最近成交数据
+//     pub async fn get_market_fills(&mut self, symbol: String, limit: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol,
+//             "limit":limit,
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/market/fills".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取历史成交数据
+//     pub async fn get_market_fills_history(&mut self, symbol: String, start_time: String, end_time: String, limit: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//             "limit": "1000"
+//          });
+//         if start_time.len() > 0 {
+//             params["startTime"] = serde_json::json!(start_time);
+//         }
+//         if end_time.len() > 0 {
+//             params["endTime"] = serde_json::json!(end_time);
+//         }
+//         if limit.len() > 0 {
+//             params["limit"] = serde_json::json!(limit);
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/market/fills-history".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //下单
+//     pub async fn spot_order(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/place-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //批量下单
+//     pub async fn spot_orders(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/batch-orders".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //撤单
+//     pub async fn spot_cancel_order(&mut self, symbol: String, order_id: String, client_oid: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//          });
+//         if order_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
+//         }
+//         if client_oid.len() > 0 {
+//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
+//         }
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/cancel-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //批量撤单
+//     pub async fn spot_cancel_orders(&mut self, symbol: String, order_list: Vec<Value>) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol,
+//             "orderList":order_list,
+//          });
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/batch-cancel-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //按币对撤单
+//     pub async fn spot_cancel_symbol_orders(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol,
+//          });
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/cancel-symbol-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取订单详情
+//     pub async fn get_order(&mut self, order_id: String, client_oid: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "orderId":order_id,
+//             "clientOid":client_oid,
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/orderInfo".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取当前委托列表
+//     pub async fn get_unfilled_orders(&mut self,
+//                                      symbol: String,
+//                                      start_time: String,
+//                                      end_time: String,
+//                                      id_less_than: String,
+//                                      limit: String,
+//                                      order_id: String,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//          });
+//         if start_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
+//         }
+//         if end_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
+//         }
+//         if id_less_than.len() > 0 {
+//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
+//         }
+//         if limit.len() > 0 {
+//             params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
+//         }
+//         if order_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/unfilled-orders".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取历史委托列表
+//     pub async fn get_history_orders(&mut self,
+//                                     symbol: String,
+//                                     start_time: String,
+//                                     end_time: String,
+//                                     id_less_than: String,
+//                                     limit: String,
+//                                     order_id: String,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//          });
+//         if start_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
+//         }
+//         if end_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
+//         }
+//         if id_less_than.len() > 0 {
+//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
+//         }
+//         if limit.len() > 0 {
+//             params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
+//         }
+//         if order_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/history-orders".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //获取成交明细
+//     pub async fn get_fills(&mut self,
+//                            symbol: String,
+//                            order_id: String,
+//                            start_time: String,
+//                            end_time: String,
+//                            limit: String,
+//                            id_less_than: String,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//          });
+//         if order_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
+//         }
+//         if start_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
+//         }
+//         if end_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
+//         }
+//         if limit.len() > 0 {
+//             params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
+//         }
+//         if id_less_than.len() > 0 {
+//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/fills".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //下单计划委托
+//     pub async fn spot_place_plan_order(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/place-plan-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //修改计划委托
+//     pub async fn update_place_plan_order(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/modify-plan-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //撤销计划委托
+//     pub async fn cancel_plan_order(&mut self, order_id: String, client_oid: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//          });
+//         if order_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
+//         }
+//         if client_oid.len() > 0 {
+//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
+//         }
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/cancel-plan-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取当前计划委托
+//     pub async fn get_current_plan_order(&mut self,
+//                                         symbol: String,
+//                                         limit: String,
+//                                         id_less_than: String,
+//                                         start_time: String,
+//                                         end_time: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//             "limit":limit,
+//          });
+//
+//
+//         if id_less_than.len() > 0 {
+//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
+//         }
+//         if start_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
+//         }
+//         if end_time.len() > 0 {
+//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/current-plan-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取历史计划委托
+//     pub async fn get_history_plan_order(&mut self,
+//                                         symbol: String,
+//                                         start_time: String,
+//                                         end_time: String,
+//                                         limit: String,
+//     ) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol,
+//             "startTime":start_time,
+//             "endTime":end_time,
+//             "limit":limit,
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/history-plan-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //批量撤销计划委托
+//     pub async fn cancel_plan_orders(&mut self, symbol_list: Vec<String>) -> ResponseData {
+//         let mut params = serde_json::json!({
+//          });
+//         if symbol_list.len() > 0 {
+//             params.as_object_mut().unwrap().insert("symbolList".parse().unwrap(), serde_json::Value::from(symbol_list));
+//         }
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/trade/batch-cancel-plan-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //划转
+//     pub async fn wallet_transfer(&mut self,
+//                                  from_type: String,
+//                                  to_type: String,
+//                                  amount: String,
+//                                  coin: String,
+//                                  symbol: String,
+//                                  client_oid: String,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//                    "fromType":from_type ,
+//                    "toType":to_type ,
+//                    "amount":amount ,
+//                    "coin":coin ,
+//          });
+//         if symbol.len() > 0 {
+//             params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
+//         }
+//         if client_oid.len() > 0 {
+//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/wallet/transfer".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取账单流水
+//     pub async fn get_account_bills(&mut self,
+//                                    coin: String,
+//                                    limit: String,
+//                                    start_time: String,
+//                                    end_time: String,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//                    "coin":coin ,
+//                    "groupType":"transaction" ,
+//                    "limit":limit ,
+//
+//          });
+//         if start_time.len() > 0 {
+//             params["startTime"] = serde_json::json!(start_time);
+//         }
+//         if end_time.len() > 0 {
+//             params["endTime"] = serde_json::json!(end_time);
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 "/spot/account/bills".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     pub fn get_delays(&self) -> Vec<i64> {
+//         self.delays.clone()
+//     }
+//     pub fn get_avg_delay(&self) -> Decimal {
+//         self.avg_delay.clone()
+//     }
+//     pub fn get_max_delay(&self) -> i64 {
+//         self.max_delay.clone()
+//     }
+//     fn get_delay_info(&mut self) {
+//         let last_100 = if self.delays.len() > 100 {
+//             self.delays[self.delays.len() - 100..].to_vec()
+//         } else {
+//             self.delays.clone()
+//         };
+//
+//         let max_value = last_100.iter().max().unwrap();
+//         if max_value.clone().to_owned() > self.max_delay {
+//             self.max_delay = max_value.clone().to_owned();
+//         }
+//
+//         let sum: i64 = last_100.iter().sum();
+//         let sum_v = Decimal::from_i64(sum).unwrap();
+//         let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
+//         self.avg_delay = (sum_v / len_v).round_dp(1);
+//         self.delays = last_100.clone().into_iter().collect();
+//     }
+//     //调用请求
+//     pub async fn request(&mut self,
+//                          method: String,
+//                          prefix_url: String,
+//                          request_url: String,
+//                          is_login: bool,
+//                          params: String) -> ResponseData
+//     {
+//         trace!("login_param:{:?}", self.login_param);
+//         //解析账号信息
+//         let mut access_key = "".to_string();
+//         let mut secret_key = "".to_string();
+//         let mut passphrase = "".to_string();
+//         if self.login_param.contains_key("access_key") {
+//             access_key = self.login_param.get("access_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("secret_key") {
+//             secret_key = self.login_param.get("secret_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("pass_key") {
+//             passphrase = self.login_param.get("pass_key").unwrap().to_string();
+//         }
+//         let mut is_login_param = true;
+//         if access_key == "" || secret_key == "" || passphrase == "" {
+//             is_login_param = false
+//         }
+//
+//
+//         //请求头配置-如果需要登陆则存在额外配置
+//         let mut body = "".to_string();
+//         let timestamp = Self::get_timestamp();
+//         let mut headers = HeaderMap::new();
+//         headers.insert("Content-Type", "application/json".parse().unwrap());
+//         headers.insert("locale", "en-US".parse().unwrap());
+//         if method == "POST" {
+//             body = params.clone();
+//         }
+//
+//
+//         //是否需要登陆-- 组装sing
+//         if is_login {
+//             if !is_login_param {
+//                 let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
+//                 return e;
+//             } else {
+//                 //需要登陆-且登陆参数齐全
+//                 trace!("param:{}", params);
+//                 trace!("body:{}", body);
+//                 //组装sing
+//                 let sing = Self::sign(secret_key.clone(),
+//                                       method.clone(),
+//                                       prefix_url.clone(),
+//                                       request_url.clone(),
+//                                       params.clone(),
+//                                       body.clone(),
+//                                       timestamp.clone(),
+//                 );
+//                 //组装header
+//                 headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
+//             }
+//         }
+//
+//
+//         // trace!("headers:{:?}", headers);
+//         let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
+//         let start_time = chrono::Utc::now().timestamp_millis();
+//         let get_response = self.http_toll(
+//             format!("{}{}", prefix_url.clone(), request_url.clone()),
+//             method.to_string(),
+//             params.clone(),
+//             headers,
+//         ).await;
+//         let time_array = chrono::Utc::now().timestamp_millis() - start_time;
+//         self.delays.push(time_array);
+//         self.get_delay_info();
+//         let res_data = Self::res_data_analysis(get_response, base_url, params);
+//         res_data
+//     }
+//
+//     pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
+//         let mut headers = HeaderMap::new();
+//         headers.insert("ACCESS-KEY", access_key.parse().unwrap());
+//         headers.insert("ACCESS-SIGN", sign.parse().unwrap());
+//         headers.insert("ACCESS-TIMESTAMP", timestamp.parse().unwrap());
+//         headers.insert("ACCESS-PASSPHRASE", passphrase.parse().unwrap());
+//         headers
+//     }
+//     pub fn sign(secret_key: String,
+//                 method: String, prefix_url: String, request_url: String,
+//                 params: String, body: String, timestamp: String) -> String
+//     {
+//         /*签名生成*/
+//         let url_param_str = RestTool::parse_params_to_str(params);
+//         let base_url = if method == "GET" && url_param_str.len() > 0 {
+//             format!("{}{}?{}", prefix_url, request_url, url_param_str)
+//         } else {
+//             format!("{}{}", prefix_url, request_url)
+//         };
+//
+//         // 时间戳 + 请求类型+ 请求参数字符串
+//         let message = format!("{}{}{}{}", timestamp, method, base_url, body);
+//         trace!("message:{}",message);
+//
+//         // 做签名
+//         let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
+//         let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
+//         let sign = base64::encode(result);
+//         sign
+//     }
+//
+//     async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
+//         let res_data: ResponseData;
+//         /****请求接口与 地址*/
+//         let url = format!("{}{}", self.base_url.to_string(), request_path);
+//         let request_type = request_type.clone().to_uppercase();
+//         let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
+//             url.clone()
+//         } else {
+//             format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
+//         };
+//         trace!("url:{}", url);
+//         trace!("addrs_url:{}", addrs_url);
+//         let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
+//         trace!("params_json:{}",params_json);
+//         trace!("headers:{:?}",headers);
+//
+//
+//         let req = match request_type.as_str() {
+//             "GET" => self.client.get(addrs_url.clone()).headers(headers),
+//             "POST" => self.client.post(url.clone()).body(params).headers(headers),
+//             "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
+//             // "PUT" => self.client.put(url.clone()).json(&params),
+//             _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
+//         };
+//
+//         let response = req.send().await?;
+//         if response.status().is_success() {
+//             // 读取响应的内容
+//             let body = response.text().await?;
+//             // trace!("ok-----{}", body);
+//             res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
+//         } else {
+//             let body = response.text().await?;
+//             // trace!("error-----{}", body);
+//             res_data = ResponseData::error(self.label.clone(), body.to_string())
+//         }
+//
+//         Ok(res_data)
+//     }
+//
+//
+//     //res_data 解析
+//     pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
+//         // trace!("原始数据:{:?}",result);
+//         match result {
+//             Ok(res_data) => {
+//                 if res_data.code != "200" {
+//                     // trace!("不等于200");
+//                     let message: String = res_data.message;
+//                     let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
+//                     let code = json_value["code"].as_str().unwrap();
+//                     let msg = json_value["msg"].as_str().unwrap();
+//                     let error = ResponseData::new("".to_string(),
+//                                                   format!("{}", code),
+//                                                   format!("{}", msg),
+//                                                   format!("请求地址:{},请求参数:{}", base_url, params));
+//                     error
+//                 } else {
+//                     // trace!("等于200");
+//                     let body: String = res_data.data;
+//                     let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
+//
+//                     let code = json_value["code"].as_str().unwrap();
+//                     if code == "00000" {
+//                         let data = serde_json::to_string(&json_value["data"]).unwrap();
+//                         let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
+//                         success
+//                     } else {
+//                         let msg = json_value["msg"].as_str().unwrap();
+//                         // trace!("发生错误:??{:?}",data_json.to_string());
+//                         let error = ResponseData::new("".to_string(),
+//                                                       format!("{}", code),
+//                                                       format!("{}", msg),
+//                                                       format!("请求地址:{},请求参数:{}", base_url, params));
+//                         error
+//                     }
+//                 }
+//             }
+//             Err(err) => {
+//                 let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
+//                 error
+//             }
+//         }
+//     }
+//     fn get_timestamp() -> String {
+//         chrono::Utc::now().timestamp_millis().to_string()
+//     }
+// }

+ 513 - 513
exchanges/src/bybit_swap_rest.rs

@@ -1,513 +1,513 @@
-use std::collections::BTreeMap;
-
-use reqwest::Client;
-use reqwest::header::HeaderMap;
-use ring::hmac;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use tracing::{info, trace};
-
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-
-#[derive(Clone, Debug)]
-pub struct BybitSwapRest {
-    pub label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //登陆所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl BybitSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BybitSwapRest
-    {
-        return BybitSwapRest::new_label("default-BybitSwapRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BybitSwapRest {
-        let base_url = if is_colo {
-            "https://api.bytick.com".to_string()
-        } else {
-            "https://api.bytick.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",base_url);
-        } else {
-            info!("走普通通道:{}",base_url);
-        }
-        /*****返回结构体*******/
-        BybitSwapRest {
-            label,
-            base_url,
-            client: Client::new(),
-            login_param,
-            delays: vec![],
-            max_delay: 0,
-            avg_delay: dec!(0.0),
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************rest请求函数********************************************************/
-    /*******************************************************************************************************/
-    //服務器時間
-    pub async fn get_server_time(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/market/time".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢最新行情信息
-    pub async fn get_tickers(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-               "category":"linear",
-                "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/market/tickers".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢市場價格K線數據
-    pub async fn get_kline(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-               "category":"linear",
-                "symbol":symbol,
-                "interval":"1",
-                "limit":"200"
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/market/kline".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢公告
-    pub async fn get_announcements(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "locale":"zh-TW"
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/announcements/index".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢可交易產品的規格信息
-    pub async fn get_instruments_info(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "category":"linear",
-            "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/market/instruments-info".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //查看持仓信息
-    pub async fn get_positions(&mut self, symbol: String, settle_coin: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "category":"linear",
-         });
-        if symbol.len() > 0 {
-            params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
-        }
-        if settle_coin.len() > 0 {
-            params.as_object_mut().unwrap().insert("settleCoin".parse().unwrap(), serde_json::Value::from(settle_coin));
-        }
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/position/list".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //设置持仓模式
-    pub async fn set_position_mode(&mut self, symbol: String, mode: i64) -> ResponseData {
-        let params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-             "mode": mode,
-         });
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/position/switch-mode".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //設置槓桿
-    pub async fn set_leverage(&mut self, symbol: String,
-                              lever: String) -> ResponseData {
-        let params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-             "buyLeverage": lever,
-             "sellLeverage": lever,
-         });
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/position/set-leverage".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-
-    //查詢錢包餘額
-    pub async fn get_account_balance(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "accountType":"UNIFIED",
-            "coin":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/account/wallet-balance".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //創建委託單
-    pub async fn swap_order(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/order/create".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢實時委託單
-    pub async fn get_order(&mut self, symbol: String, order_id: String, order_link_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "category":"linear",
-            "symbol":symbol,
-         });
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        if order_link_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderLinkId".parse().unwrap(), serde_json::Value::from(order_link_id));
-        }
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/order/realtime".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //撤单
-    pub async fn cancel_order(&mut self, symbol: String, order_id: String, order_link_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-         });
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        if order_link_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderLinkId".parse().unwrap(), serde_json::Value::from(order_link_id));
-        }
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/order/cancel".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //撤銷所有訂單
-    pub async fn cancel_orders(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-         });
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/order/cancel-all".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        self.delays.clone()
-    }
-    pub fn get_avg_delay(&self) -> Decimal {
-        self.avg_delay.clone()
-    }
-    pub fn get_max_delay(&self) -> i64 {
-        self.max_delay.clone()
-    }
-    fn get_delay_info(&mut self) {
-        let last_100 = if self.delays.len() > 100 {
-            self.delays[self.delays.len() - 100..].to_vec()
-        } else {
-            self.delays.clone()
-        };
-
-        let max_value = last_100.iter().max().unwrap();
-        if max_value.clone().to_owned() > self.max_delay {
-            self.max_delay = max_value.clone().to_owned();
-        }
-
-        let sum: i64 = last_100.iter().sum();
-        let sum_v = Decimal::from_i64(sum).unwrap();
-        let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
-        self.avg_delay = (sum_v / len_v).round_dp(1);
-        self.delays = last_100.clone().into_iter().collect();
-    }
-    //调用请求
-    pub async fn request(&mut self,
-                         method: String,
-                         prefix_url: String,
-                         request_url: String,
-                         is_login: bool,
-                         params: String) -> ResponseData
-    {
-        trace!("login_param:{:?}", self.login_param);
-        //解析账号信息
-        let mut access_key = "".to_string();
-        let mut secret_key = "".to_string();
-        // let mut passphrase = "".to_string();
-        if self.login_param.contains_key("access_key") {
-            access_key = self.login_param.get("access_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("secret_key") {
-            secret_key = self.login_param.get("secret_key").unwrap().to_string();
-        }
-        // if self.login_param.contains_key("pass_key") {
-        //     passphrase = self.login_param.get("pass_key").unwrap().to_string();
-        // }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" {
-            is_login_param = false
-        }
-
-
-        //请求头配置-如果需要登陆则存在额外配置
-        let mut body = "".to_string();
-        let timestamp = Self::get_timestamp();
-        let mut headers = HeaderMap::new();
-        headers.insert("Content-Type", "application/json; charset=utf-8".parse().unwrap());
-        headers.insert("X-BAPI-RECV-WINDOW", "5000".parse().unwrap());
-
-        if method == "POST" {
-            body = params.clone();
-        }
-
-
-        //是否需要登陆-- 组装sing
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
-                return e;
-            } else {
-                //需要登陆-且登陆参数齐全
-                trace!("param:{}", params);
-                trace!("body:{}", body);
-                //组装sing
-                let sing = Self::sign(
-                    access_key.clone(),
-                    secret_key.clone(),
-                    method.clone(),
-                    params.clone(),
-                    timestamp.clone(),
-                );
-                //组装header
-                headers.extend(Self::headers(sing, timestamp, access_key));
-            }
-        }
-
-
-        // trace!("headers:{:?}", headers);
-        let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let get_response = self.http_toll(
-            format!("{}{}", prefix_url.clone(), request_url.clone()),
-            method.to_string(),
-            params.clone(),
-            headers,
-        ).await;
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        self.get_delay_info();
-        let res_data = Self::res_data_analysis(get_response, base_url, params);
-        res_data
-    }
-
-    pub fn headers(sign: String, timestamp: String, access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("X-BAPI-SIGN-TYPE", "2".parse().unwrap());
-        headers.insert("X-BAPI-API-KEY", access_key.parse().unwrap());
-        headers.insert("X-BAPI-TIMESTAMP", timestamp.parse().unwrap());
-        headers.insert("X-BAPI-SIGN", sign.parse().unwrap());
-        // headers.insert("X-Referer", passphrase.parse().unwrap());
-        headers
-    }
-    pub fn sign(access_key: String,
-                secret_key: String,
-                method: String,
-                params: String, timestamp: String) -> String
-    {
-        /*签名生成*/
-        let url_param_str = RestTool::parse_params_to_str(params.clone());
-        let parameters = if method == "GET" {
-            url_param_str
-        } else {
-            params
-        };
-
-        let message = format!("{}{}5000{}", timestamp, access_key, parameters);
-        trace!("message:{}",message);
-
-        // 做签名
-        let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-        let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-        let sign = hex::encode(result.as_ref());
-        sign
-    }
-
-    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        let res_data: ResponseData;
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-        let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
-            url.clone()
-        } else {
-            format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
-        };
-        trace!("url:{}", url);
-        trace!("addrs_url:{}", addrs_url);
-        let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-        trace!("params_json:{}",params_json);
-        trace!("headers:{:?}",headers);
-
-
-        let req = match request_type.as_str() {
-            "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(url.clone()).body(params).headers(headers),
-            "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
-        };
-
-        let response = req.send().await?;
-        if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await?;
-            // trace!("ok-----{}", body);
-            res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
-        } else {
-            let body = response.text().await?;
-            // trace!("error-----{}", body);
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
-        }
-
-        Ok(res_data)
-    }
-
-
-    //res_data 解析
-    pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-        // trace!("原始数据:{:?}",result);
-        match result {
-            Ok(res_data) => {
-                if res_data.code != "200" {
-                    // trace!("不等于200");
-                    let message: String = res_data.message;
-                    let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
-                    let code = json_value["code"].as_str().unwrap();
-                    let msg = json_value["msg"].as_str().unwrap();
-                    let error = ResponseData::new("".to_string(),
-                                                  format!("{}", code),
-                                                  format!("{}", msg),
-                                                  format!("请求地址:{},请求参数:{}", base_url, params));
-                    error
-                } else {
-                    let body: String = res_data.data.as_str().parse().unwrap();
-                    let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
-                    // trace!("json_value:{:?}",json_value.to_string().as_str());
-                    let code: i64 = if json_value["retCode"].as_i64().is_some() {
-                        json_value["retCode"].as_i64().unwrap()
-                    } else if json_value["ret_code"].as_i64().is_some() {
-                        json_value["ret_code"].as_i64().unwrap()
-                    } else {
-                        -1
-                    };
-
-                    let msg: &str = if json_value["retMsg"].as_str().is_some() {
-                        json_value["retMsg"].as_str().unwrap()
-                    } else if json_value["ret_msg"].as_str().is_some() {
-                        json_value["ret_msg"].as_str().unwrap()
-                    } else {
-                        ""
-                    };
-
-
-                    if code == 0 {
-                        let data = serde_json::to_string(&json_value["result"]).unwrap();
-                        let mut success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
-                        success.time = json_value["time"].as_i64().unwrap();
-                        success
-                    } else {
-                        let error = ResponseData::new("".to_string(),
-                                                      format!("{}", code),
-                                                      format!("{}", msg),
-                                                      format!("请求地址:{},请求参数:{}", base_url, params));
-                        error
-                    }
-                }
-            }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
-                error
-            }
-        }
-    }
-    fn get_timestamp() -> String {
-        chrono::Utc::now().timestamp_millis()
-            .to_string()
-    }
-}
+// use std::collections::BTreeMap;
+//
+// use reqwest::Client;
+// use reqwest::header::HeaderMap;
+// use ring::hmac;
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use rust_decimal_macros::dec;
+// use tracing::{info, trace};
+//
+// use crate::http_tool::RestTool;
+// use crate::response_base::ResponseData;
+//
+// #[derive(Clone, Debug)]
+// pub struct BybitSwapRest {
+//     pub label: String,
+//     base_url: String,
+//     client: reqwest::Client,
+//     /*******参数*/
+//     //登陆所需参数
+//     login_param: BTreeMap<String, String>,
+//     delays: Vec<i64>,
+//     max_delay: i64,
+//     avg_delay: Decimal,
+// }
+//
+// impl BybitSwapRest {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//
+//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BybitSwapRest
+//     {
+//         return BybitSwapRest::new_label("default-BybitSwapRest".to_string(), is_colo, login_param);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BybitSwapRest {
+//         let base_url = if is_colo {
+//             "https://api.bytick.com".to_string()
+//         } else {
+//             "https://api.bytick.com".to_string()
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",base_url);
+//         } else {
+//             info!("走普通通道:{}",base_url);
+//         }
+//         /*****返回结构体*******/
+//         BybitSwapRest {
+//             label,
+//             base_url,
+//             client: Client::new(),
+//             login_param,
+//             delays: vec![],
+//             max_delay: 0,
+//             avg_delay: dec!(0.0),
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************rest请求函数********************************************************/
+//     /*******************************************************************************************************/
+//     //服務器時間
+//     pub async fn get_server_time(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/market/time".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查詢最新行情信息
+//     pub async fn get_tickers(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//                "category":"linear",
+//                 "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/market/tickers".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查詢市場價格K線數據
+//     pub async fn get_kline(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//                "category":"linear",
+//                 "symbol":symbol,
+//                 "interval":"1",
+//                 "limit":"200"
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/market/kline".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查詢公告
+//     pub async fn get_announcements(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//             "locale":"zh-TW"
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/announcements/index".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查詢可交易產品的規格信息
+//     pub async fn get_instruments_info(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "category":"linear",
+//             "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/market/instruments-info".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //查看持仓信息
+//     pub async fn get_positions(&mut self, symbol: String, settle_coin: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "category":"linear",
+//          });
+//         if symbol.len() > 0 {
+//             params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
+//         }
+//         if settle_coin.len() > 0 {
+//             params.as_object_mut().unwrap().insert("settleCoin".parse().unwrap(), serde_json::Value::from(settle_coin));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/position/list".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //设置持仓模式
+//     pub async fn set_position_mode(&mut self, symbol: String, mode: i64) -> ResponseData {
+//         let params = serde_json::json!({
+//              "category": "linear",
+//              "symbol": symbol,
+//              "mode": mode,
+//          });
+//         let data = self.request("POST".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/position/switch-mode".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //設置槓桿
+//     pub async fn set_leverage(&mut self, symbol: String,
+//                               lever: String) -> ResponseData {
+//         let params = serde_json::json!({
+//              "category": "linear",
+//              "symbol": symbol,
+//              "buyLeverage": lever,
+//              "sellLeverage": lever,
+//          });
+//         let data = self.request("POST".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/position/set-leverage".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//
+//     //查詢錢包餘額
+//     pub async fn get_account_balance(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "accountType":"UNIFIED",
+//             "coin":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/account/wallet-balance".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //創建委託單
+//     pub async fn swap_order(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/order/create".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查詢實時委託單
+//     pub async fn get_order(&mut self, symbol: String, order_id: String, order_link_id: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "category":"linear",
+//             "symbol":symbol,
+//          });
+//         if order_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
+//         }
+//         if order_link_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderLinkId".parse().unwrap(), serde_json::Value::from(order_link_id));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/order/realtime".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //撤单
+//     pub async fn cancel_order(&mut self, symbol: String, order_id: String, order_link_id: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//              "category": "linear",
+//              "symbol": symbol,
+//          });
+//         if order_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
+//         }
+//         if order_link_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("orderLinkId".parse().unwrap(), serde_json::Value::from(order_link_id));
+//         }
+//         let data = self.request("POST".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/order/cancel".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //撤銷所有訂單
+//     pub async fn cancel_orders(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//              "category": "linear",
+//              "symbol": symbol,
+//          });
+//         let data = self.request("POST".to_string(),
+//                                 "/v5".to_string(),
+//                                 "/order/cancel-all".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     pub fn get_delays(&self) -> Vec<i64> {
+//         self.delays.clone()
+//     }
+//     pub fn get_avg_delay(&self) -> Decimal {
+//         self.avg_delay.clone()
+//     }
+//     pub fn get_max_delay(&self) -> i64 {
+//         self.max_delay.clone()
+//     }
+//     fn get_delay_info(&mut self) {
+//         let last_100 = if self.delays.len() > 100 {
+//             self.delays[self.delays.len() - 100..].to_vec()
+//         } else {
+//             self.delays.clone()
+//         };
+//
+//         let max_value = last_100.iter().max().unwrap();
+//         if max_value.clone().to_owned() > self.max_delay {
+//             self.max_delay = max_value.clone().to_owned();
+//         }
+//
+//         let sum: i64 = last_100.iter().sum();
+//         let sum_v = Decimal::from_i64(sum).unwrap();
+//         let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
+//         self.avg_delay = (sum_v / len_v).round_dp(1);
+//         self.delays = last_100.clone().into_iter().collect();
+//     }
+//     //调用请求
+//     pub async fn request(&mut self,
+//                          method: String,
+//                          prefix_url: String,
+//                          request_url: String,
+//                          is_login: bool,
+//                          params: String) -> ResponseData
+//     {
+//         trace!("login_param:{:?}", self.login_param);
+//         //解析账号信息
+//         let mut access_key = "".to_string();
+//         let mut secret_key = "".to_string();
+//         // let mut passphrase = "".to_string();
+//         if self.login_param.contains_key("access_key") {
+//             access_key = self.login_param.get("access_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("secret_key") {
+//             secret_key = self.login_param.get("secret_key").unwrap().to_string();
+//         }
+//         // if self.login_param.contains_key("pass_key") {
+//         //     passphrase = self.login_param.get("pass_key").unwrap().to_string();
+//         // }
+//         let mut is_login_param = true;
+//         if access_key == "" || secret_key == "" {
+//             is_login_param = false
+//         }
+//
+//
+//         //请求头配置-如果需要登陆则存在额外配置
+//         let mut body = "".to_string();
+//         let timestamp = Self::get_timestamp();
+//         let mut headers = HeaderMap::new();
+//         headers.insert("Content-Type", "application/json; charset=utf-8".parse().unwrap());
+//         headers.insert("X-BAPI-RECV-WINDOW", "5000".parse().unwrap());
+//
+//         if method == "POST" {
+//             body = params.clone();
+//         }
+//
+//
+//         //是否需要登陆-- 组装sing
+//         if is_login {
+//             if !is_login_param {
+//                 let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
+//                 return e;
+//             } else {
+//                 //需要登陆-且登陆参数齐全
+//                 trace!("param:{}", params);
+//                 trace!("body:{}", body);
+//                 //组装sing
+//                 let sing = Self::sign(
+//                     access_key.clone(),
+//                     secret_key.clone(),
+//                     method.clone(),
+//                     params.clone(),
+//                     timestamp.clone(),
+//                 );
+//                 //组装header
+//                 headers.extend(Self::headers(sing, timestamp, access_key));
+//             }
+//         }
+//
+//
+//         // trace!("headers:{:?}", headers);
+//         let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
+//         let start_time = chrono::Utc::now().timestamp_millis();
+//         let get_response = self.http_toll(
+//             format!("{}{}", prefix_url.clone(), request_url.clone()),
+//             method.to_string(),
+//             params.clone(),
+//             headers,
+//         ).await;
+//         let time_array = chrono::Utc::now().timestamp_millis() - start_time;
+//         self.delays.push(time_array);
+//         self.get_delay_info();
+//         let res_data = Self::res_data_analysis(get_response, base_url, params);
+//         res_data
+//     }
+//
+//     pub fn headers(sign: String, timestamp: String, access_key: String) -> HeaderMap {
+//         let mut headers = HeaderMap::new();
+//         headers.insert("X-BAPI-SIGN-TYPE", "2".parse().unwrap());
+//         headers.insert("X-BAPI-API-KEY", access_key.parse().unwrap());
+//         headers.insert("X-BAPI-TIMESTAMP", timestamp.parse().unwrap());
+//         headers.insert("X-BAPI-SIGN", sign.parse().unwrap());
+//         // headers.insert("X-Referer", passphrase.parse().unwrap());
+//         headers
+//     }
+//     pub fn sign(access_key: String,
+//                 secret_key: String,
+//                 method: String,
+//                 params: String, timestamp: String) -> String
+//     {
+//         /*签名生成*/
+//         let url_param_str = RestTool::parse_params_to_str(params.clone());
+//         let parameters = if method == "GET" {
+//             url_param_str
+//         } else {
+//             params
+//         };
+//
+//         let message = format!("{}{}5000{}", timestamp, access_key, parameters);
+//         trace!("message:{}",message);
+//
+//         // 做签名
+//         let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
+//         let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
+//         let sign = hex::encode(result.as_ref());
+//         sign
+//     }
+//
+//     async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
+//         let res_data: ResponseData;
+//         /****请求接口与 地址*/
+//         let url = format!("{}{}", self.base_url.to_string(), request_path);
+//         let request_type = request_type.clone().to_uppercase();
+//         let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
+//             url.clone()
+//         } else {
+//             format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
+//         };
+//         trace!("url:{}", url);
+//         trace!("addrs_url:{}", addrs_url);
+//         let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
+//         trace!("params_json:{}",params_json);
+//         trace!("headers:{:?}",headers);
+//
+//
+//         let req = match request_type.as_str() {
+//             "GET" => self.client.get(addrs_url.clone()).headers(headers),
+//             "POST" => self.client.post(url.clone()).body(params).headers(headers),
+//             "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
+//             // "PUT" => self.client.put(url.clone()).json(&params),
+//             _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
+//         };
+//
+//         let response = req.send().await?;
+//         if response.status().is_success() {
+//             // 读取响应的内容
+//             let body = response.text().await?;
+//             // trace!("ok-----{}", body);
+//             res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
+//         } else {
+//             let body = response.text().await?;
+//             // trace!("error-----{}", body);
+//             res_data = ResponseData::error(self.label.clone(), body.to_string())
+//         }
+//
+//         Ok(res_data)
+//     }
+//
+//
+//     //res_data 解析
+//     pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
+//         // trace!("原始数据:{:?}",result);
+//         match result {
+//             Ok(res_data) => {
+//                 if res_data.code != "200" {
+//                     // trace!("不等于200");
+//                     let message: String = res_data.message;
+//                     let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
+//                     let code = json_value["code"].as_str().unwrap();
+//                     let msg = json_value["msg"].as_str().unwrap();
+//                     let error = ResponseData::new("".to_string(),
+//                                                   format!("{}", code),
+//                                                   format!("{}", msg),
+//                                                   format!("请求地址:{},请求参数:{}", base_url, params));
+//                     error
+//                 } else {
+//                     let body: String = res_data.data.as_str().parse().unwrap();
+//                     let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
+//                     // trace!("json_value:{:?}",json_value.to_string().as_str());
+//                     let code: i64 = if json_value["retCode"].as_i64().is_some() {
+//                         json_value["retCode"].as_i64().unwrap()
+//                     } else if json_value["ret_code"].as_i64().is_some() {
+//                         json_value["ret_code"].as_i64().unwrap()
+//                     } else {
+//                         -1
+//                     };
+//
+//                     let msg: &str = if json_value["retMsg"].as_str().is_some() {
+//                         json_value["retMsg"].as_str().unwrap()
+//                     } else if json_value["ret_msg"].as_str().is_some() {
+//                         json_value["ret_msg"].as_str().unwrap()
+//                     } else {
+//                         ""
+//                     };
+//
+//
+//                     if code == 0 {
+//                         let data = serde_json::to_string(&json_value["result"]).unwrap();
+//                         let mut success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
+//                         success.time = json_value["time"].as_i64().unwrap();
+//                         success
+//                     } else {
+//                         let error = ResponseData::new("".to_string(),
+//                                                       format!("{}", code),
+//                                                       format!("{}", msg),
+//                                                       format!("请求地址:{},请求参数:{}", base_url, params));
+//                         error
+//                     }
+//                 }
+//             }
+//             Err(err) => {
+//                 let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
+//                 error
+//             }
+//         }
+//     }
+//     fn get_timestamp() -> String {
+//         chrono::Utc::now().timestamp_millis()
+//             .to_string()
+//     }
+// }

+ 35 - 55
exchanges/src/gate_swap_rest.rs

@@ -481,7 +481,7 @@ impl GateSwapRest {
         // trace!("headers:{:?}", headers);
         let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
         let start_time = chrono::Utc::now().timestamp_millis();
-        let get_response = self.http_toll(
+        let response = self.http_toll(
             base_url.clone(),
             requesst_type.to_string(),
             params.clone(),
@@ -492,8 +492,7 @@ impl GateSwapRest {
         self.delays.push(time_array);
         self.get_delay_info();
 
-        let res_data = Self::res_data_analysis(get_response, base_url, params);
-        res_data
+        response
     }
 
     pub fn headers(access_key: String, timestamp: String, sign: String) -> HeaderMap {
@@ -537,71 +536,52 @@ impl GateSwapRest {
     }
 
 
-    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        let res_data: ResponseData;
+    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> ResponseData {
         /****请求接口与 地址*/
         let url = format!("{}{}", self.base_url.to_string(), request_path);
         let request_type = request_type.clone().to_uppercase();
         let addrs_url = format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()));
-        // let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-        // trace!("url:{}",url);
-        // trace!("addrs_url:{}",url);
-        // trace!("params_json:{}",params_json);
-        // trace!("headers:{:?}",headers);
 
-        let req = match request_type.as_str() {
+        let request_builder = match request_type.as_str() {
             "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(addrs_url.clone()).body(params).headers(headers),
+            "POST" => self.client.post(addrs_url.clone()).body(params.clone()).headers(headers),
             "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
             // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
+            _ => {
+                panic!("{}", format!("错误的请求类型:{}", request_type.clone()))
+            }
         };
 
-        let response = req.send().await?;
-        if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await?;
-            // trace!("ok-----{}", body);
-            res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
+        // 读取响应的内容
+        let response = request_builder.send().await.unwrap();
+        let is_success = response.status().is_success(); // 先检查状态码
+        let text = response.text().await.unwrap();
+        return if is_success {
+            self.on_success_data(text)
         } else {
-            let body = response.text().await?;
-            // trace!("error-----{}", body);
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
+            self.on_error_data(text, addrs_url, params)
         }
-        Ok(res_data)
-    }
-
-    pub fn on_error_data() -> ResponseData {
-
-    }
-
-    //res_data 解析
-    pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-        match result {
-            Ok(res_data) => {
-                if res_data.code != "200" {
-                    let message = res_data.message;
-                    // let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();//这种方式会触发 解析错误
-                    let json_value = serde_json::from_str::<Value>(&message);
-                    match json_value {
-                        Ok(data) => {
-                            let label = data["label"].as_str().unwrap();
-                            let mut error = ResponseData::error(res_data.label, label.parse().unwrap());
-                            error.message = format!("请求地址:{},请求参数:{}", base_url, params);
-                            error
-                        }
-                        Err(e) => {
-                            error!("解析错误:{:?}",e);
-                            let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", e, message));
-                            error
-                        }
-                    }
-                } else {
-                    res_data
-                }
+    }
+
+    pub fn on_success_data(&mut self, text: String) -> ResponseData {
+        let data = serde_json::from_str(text.as_str()).unwrap();
+
+        ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), data)
+    }
+
+    pub fn on_error_data(&mut self, text: String, base_url: String, params: String) -> ResponseData {
+        let json_value = serde_json::from_str::<Value>(&text);
+
+        match json_value {
+            Ok(data) => {
+                let message = data["label"].as_str().unwrap();
+                let mut error = ResponseData::error(self.label.clone(), message.to_string());
+                error.message = format!("请求地址:{}, 请求参数:{}", base_url, params);
+                error
             }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", err, params));
+            Err(e) => {
+                error!("解析错误:{:?}", e);
+                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", e, text));
                 error
             }
         }

+ 2 - 4
exchanges/src/http_tool.rs

@@ -1,16 +1,14 @@
-use reqwest::{Client};
 use tracing::trace;
 use crate::response_base::ResponseData;
 
 #[derive(Clone)]
 pub struct RestTool {
-    pub base_url: String,
-    client: Client,
+    pub base_url: String
 }
 
 impl RestTool {
     pub fn new(base_url: String) -> RestTool {
-        RestTool { base_url, client: Client::new() }
+        RestTool { base_url }
     }
 
     // pub async fn http_toll(&self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {

+ 521 - 521
exchanges/src/kucoin_spot_rest.rs

@@ -1,521 +1,521 @@
-use std::collections::BTreeMap;
-use std::fmt::Debug;
-use reqwest::header::HeaderMap;
-use hmac::{Hmac, Mac, NewMac};
-use reqwest::{Client};
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use sha2::Sha256;
-use tracing::{info, trace};
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-use std::string::String;
-
-
-#[derive(Clone, Debug)]
-pub struct KucoinSpotRest {
-    pub label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //是否需要登陆
-    //登陆所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-
-}
-
-impl KucoinSpotRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSpotRest
-    {
-        return KucoinSpotRest::new_label("default-KucoinSpotRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSpotRest {
-        let base_url = if is_colo {
-            "https://api.kucoin.com".to_string()
-        } else {
-            "https://api.kucoin.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",base_url);
-        } else {
-            info!("走普通通道:{}",base_url);
-        }
-        /*****返回结构体*******/
-        KucoinSpotRest {
-            label,
-            base_url,
-            client: Client::new(),
-            login_param,
-            delays: vec![],
-            max_delay: 0,
-            avg_delay: dec!(0.0),
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************rest请求函数********************************************************/
-    /*******************************************************************************************************/
-    pub async fn get_server_time(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/timestamp".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    // 获取成交记录
-    pub async fn get_fills(&mut self,
-                           symbol: String,
-                           order_id: String,
-                           side: String,
-                           start_at: i64,
-                           end_at: i64,
-                           page_size: i64,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-            "pageSize": 1000
-         });
-        if order_id.len() > 0 {
-            params["orderId"] = serde_json::json!(order_id);
-        }
-        if side.len() > 0 {
-            params["side"] = serde_json::json!(side);
-        }
-        if start_at > 0 {
-            params["startAt"] = serde_json::json!(start_at);
-        }
-        if end_at > 0 {
-            params["endAt"] = serde_json::json!(end_at);
-        }
-        if page_size > 0 {
-            params["pageSize"] = serde_json::json!(page_size);
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/fills".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取订单
-    pub async fn get_order(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-             "status":"active",
-             "tradeType":"TRADE",
-             "type":"limit"
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/orders".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //獲取行情
-    pub async fn get_level1(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-             "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/market/orderbook/level1".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //通過orderId获取訂單詳情
-    pub async fn get_order_by_order_id(&mut self, order_id: String) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders/{}", order_id),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //通過clientOid獲取訂單詳情
-    pub async fn get_order_by_client_id(&mut self, client_id: String) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/order/client-order/{}", client_id),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //獲取賬戶列表 - 現貨/槓桿/現貨高頻
-    pub async fn get_accounts(&mut self, currency: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "type":"trade",
-         });
-        if currency.len() > 0 {
-            params.as_object_mut().unwrap().insert("currency".parse().unwrap(), serde_json::Value::from(currency));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/accounts"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //獲取交易對列表
-    pub async fn get_symbols(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                format!("/symbols"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //通過orderId撤單
-    pub async fn cancel_order_by_order_id(&mut self, order_id: String) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("DELETE".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders/{}", order_id),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //通過clientOid撤單
-    pub async fn cancel_order_by_client_id(&mut self, client_id: String) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("DELETE".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/order/client-order/{}", client_id),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //全部撤單
-    pub async fn cancel_order_all(&mut self, symbol: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "tradeType":"TRADE"
-         });
-        if symbol.len() > 0 {
-            params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
-        }
-        let data = self.request("DELETE".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //现货下单-
-    pub async fn spot_order(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //获取合约令牌-公共
-    pub async fn get_public_token(&mut self) -> ResponseData {
-        let params = serde_json::json!({});
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                "/bullet-public".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取合约令牌-私有
-    pub async fn get_private_token(&mut self) -> ResponseData {
-        let params = serde_json::json!({});
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                "/bullet-private".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        self.delays.clone()
-    }
-    pub fn get_avg_delay(&self) -> Decimal {
-        self.avg_delay.clone()
-    }
-    pub fn get_max_delay(&self) -> i64 {
-        self.max_delay.clone()
-    }
-    fn get_delay_info(&mut self) {
-        let last_100 = if self.delays.len() > 100 {
-            self.delays[self.delays.len() - 100..].to_vec()
-        } else {
-            self.delays.clone()
-        };
-
-        let max_value = last_100.iter().max().unwrap();
-        if max_value.clone().to_owned() > self.max_delay {
-            self.max_delay = max_value.clone().to_owned();
-        }
-
-        let sum: i64 = last_100.iter().sum();
-        let sum_v = Decimal::from_i64(sum).unwrap();
-        let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
-        self.avg_delay = (sum_v / len_v).round_dp(1);
-        self.delays = last_100.clone().into_iter().collect();
-    }
-    //调用请求
-    pub async fn request(&mut self,
-                         method: String,
-                         prefix_url: String,
-                         request_url: String,
-                         is_login: bool,
-                         params: String) -> ResponseData
-    {
-        trace!("login_param:{:?}", self.login_param);
-        //解析账号信息
-        let mut access_key = "".to_string();
-        let mut secret_key = "".to_string();
-        let mut pass_key = "".to_string();
-        if self.login_param.contains_key("access_key") {
-            access_key = self.login_param.get("access_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("secret_key") {
-            secret_key = self.login_param.get("secret_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("pass_key") {
-            pass_key = self.login_param.get("pass_key").unwrap().to_string();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" || pass_key == "" {
-            is_login_param = false
-        }
-
-
-        //请求头配置-如果需要登陆则存在额外配置
-        let mut body = "".to_string();
-
-        let timestamp = chrono::Utc::now().timestamp_millis().to_string();
-
-        let mut headers = HeaderMap::new();
-        headers.insert("Content-Type", "application/json".parse().unwrap());
-        if method == "POST" {
-            body = params.clone();
-        }
-
-        //是否需要登陆-- 组装sing
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
-                return e;
-            } else {
-                //需要登陆-且登陆参数齐全
-                trace!("param:{}", params);
-                trace!("body:{}", body);
-                //组装sing
-                let sing = Self::sign(secret_key.clone(),
-                                      method.clone(),
-                                      prefix_url.clone(),
-                                      request_url.clone(),
-                                      params.clone(),
-                                      body.clone(),
-                                      timestamp.clone(),
-                );
-                trace!("sing:{}", sing);
-                let passphrase = Self::passphrase(secret_key, pass_key);
-                trace!("passphrase:{}", passphrase);
-                //组装header
-                headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
-            }
-        }
-
-
-        trace!("headers:{:?}", headers);
-        let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let get_response = self.http_toll(
-            base_url.clone(),
-            method.to_string(),
-            params.clone(),
-            headers,
-        ).await;
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        self.get_delay_info();
-        let res_data = Self::res_data_analysis(get_response, base_url, params);
-        res_data
-    }
-
-    pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("KC-API-KEY", access_key.parse().unwrap());
-        headers.insert("KC-API-SIGN", sign.parse().unwrap());
-        headers.insert("KC-API-TIMESTAMP", timestamp.parse().unwrap());
-        headers.insert("KC-API-PASSPHRASE", passphrase.parse().unwrap());
-        headers.insert("KC-API-KEY-VERSION", "2".parse().unwrap());
-        headers
-    }
-    pub fn sign(secret_key: String,
-                method: String, prefix_url: String, request_url: String,
-                params: String, body_data: String, timestamp: String) -> String
-    {
-        let url = format!("{}{}", prefix_url, request_url);
-        let params_str = RestTool::parse_params_to_str(params.clone());
-        trace!("body_data:{}", body_data);
-        // let body = Some(body_data);
-        // let hashed_payload = if let Some(body) = body {
-        //     let mut m = digest::Context::new(&digest::SHA256);
-        //     m.update(body.as_bytes());
-        //     hex::encode(m.finish().as_ref())
-        // } else {
-        //     String::new()
-        // };
-        // trace!("hashed_payload:{}", hashed_payload);
-
-        let mut message = format!("{}{}{}",
-                                  timestamp,
-                                  method,
-                                  url
-        );
-        if method == "GET" || method == "DELETE" {
-            message = if params_str.len() > 0 {
-                format!("{}?{}", message, params_str)
-            } else {
-                format!("{}", message)
-            };
-        } else if method == "POST" || method == "PUT" {
-            message = format!("{}{}", message, body_data);
-        }
-
-        trace!("**********", );
-        trace!("组装数据:{}", message);
-        trace!("**********", );
-
-        let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
-        mac.update(message.as_bytes());
-        let result = mac.finalize().into_bytes();
-        let base64_encoded = base64::encode(result);
-        base64_encoded
-    }
-
-    pub fn passphrase(secret_key: String, pass_key: String) -> String
-    {
-        let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
-        mac.update(pass_key.as_bytes());
-        let result = mac.finalize().into_bytes();
-        let base64_encoded = base64::encode(result);
-        base64_encoded
-    }
-
-
-    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        let res_data: ResponseData;
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-        let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
-            url.clone()
-        } else {
-            format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
-        };
-        trace!("url:{}", url);
-        trace!("addrs_url:{}", addrs_url);
-
-
-        let req = match request_type.as_str() {
-            "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(url.clone()).body(params).headers(headers),
-            "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
-        };
-
-        let response = req.send().await?;
-        if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await?;
-            // trace!("ok-----{}", body);
-            res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
-        } else {
-            let body = response.text().await?;
-            // trace!("error-----{}", body);
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
-        }
-
-        Ok(res_data)
-    }
-
-
-    //res_data 解析
-    pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-        match result {
-            Ok(res_data) => {
-                if res_data.code != "200" {
-                    // res_data
-                    let mut error = res_data;
-                    error.message = format!("错误:{},url:{},相关参数:{}", error.message, base_url, params);
-                    error
-                } else {
-                    let body: String = res_data.data;
-                    let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
-
-                    let code = json_value["code"].as_str().unwrap();
-
-                    if code != "200000" {
-                        let msg = json_value["msg"].as_str().unwrap();
-                        // let error = ResponseData::new("".to_string(), code.to_string(),
-                        //                               format!("错误:{},url:{},相关参数:{}", msg, base_url, params),
-                        //                               "".parse().unwrap());
-                        // error
-
-                        let mut error = ResponseData::error(res_data.label, msg.parse().unwrap());
-                        error.code = code.parse().unwrap();
-                        error.data = format!("请求地址:{},请求参数:{}", base_url, params);
-                        error
-                    } else {
-                        let data = serde_json::to_string(&json_value["data"]).unwrap();
-                        let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
-                        success
-                    }
-                }
-            }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", err, params));
-                error
-            }
-        }
-    }
-}
+// use std::collections::BTreeMap;
+// use std::fmt::Debug;
+// use reqwest::header::HeaderMap;
+// use hmac::{Hmac, Mac, NewMac};
+// use reqwest::{Client};
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use rust_decimal_macros::dec;
+// use sha2::Sha256;
+// use tracing::{info, trace};
+// use crate::http_tool::RestTool;
+// use crate::response_base::ResponseData;
+// use std::string::String;
+//
+//
+// #[derive(Clone, Debug)]
+// pub struct KucoinSpotRest {
+//     pub label: String,
+//     base_url: String,
+//     client: reqwest::Client,
+//     /*******参数*/
+//     //是否需要登陆
+//     //登陆所需参数
+//     login_param: BTreeMap<String, String>,
+//     delays: Vec<i64>,
+//     max_delay: i64,
+//     avg_delay: Decimal,
+//
+// }
+//
+// impl KucoinSpotRest {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//
+//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSpotRest
+//     {
+//         return KucoinSpotRest::new_label("default-KucoinSpotRest".to_string(), is_colo, login_param);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSpotRest {
+//         let base_url = if is_colo {
+//             "https://api.kucoin.com".to_string()
+//         } else {
+//             "https://api.kucoin.com".to_string()
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",base_url);
+//         } else {
+//             info!("走普通通道:{}",base_url);
+//         }
+//         /*****返回结构体*******/
+//         KucoinSpotRest {
+//             label,
+//             base_url,
+//             client: Client::new(),
+//             login_param,
+//             delays: vec![],
+//             max_delay: 0,
+//             avg_delay: dec!(0.0),
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************rest请求函数********************************************************/
+//     /*******************************************************************************************************/
+//     pub async fn get_server_time(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/timestamp".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     // 获取成交记录
+//     pub async fn get_fills(&mut self,
+//                            symbol: String,
+//                            order_id: String,
+//                            side: String,
+//                            start_at: i64,
+//                            end_at: i64,
+//                            page_size: i64,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//             "pageSize": 1000
+//          });
+//         if order_id.len() > 0 {
+//             params["orderId"] = serde_json::json!(order_id);
+//         }
+//         if side.len() > 0 {
+//             params["side"] = serde_json::json!(side);
+//         }
+//         if start_at > 0 {
+//             params["startAt"] = serde_json::json!(start_at);
+//         }
+//         if end_at > 0 {
+//             params["endAt"] = serde_json::json!(end_at);
+//         }
+//         if page_size > 0 {
+//             params["pageSize"] = serde_json::json!(page_size);
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/fills".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取订单
+//     pub async fn get_order(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//              "status":"active",
+//              "tradeType":"TRADE",
+//              "type":"limit"
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/orders".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //獲取行情
+//     pub async fn get_level1(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//              "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/market/orderbook/level1".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //通過orderId获取訂單詳情
+//     pub async fn get_order_by_order_id(&mut self, order_id: String) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders/{}", order_id),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //通過clientOid獲取訂單詳情
+//     pub async fn get_order_by_client_id(&mut self, client_id: String) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/order/client-order/{}", client_id),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //獲取賬戶列表 - 現貨/槓桿/現貨高頻
+//     pub async fn get_accounts(&mut self, currency: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "type":"trade",
+//          });
+//         if currency.len() > 0 {
+//             params.as_object_mut().unwrap().insert("currency".parse().unwrap(), serde_json::Value::from(currency));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/accounts"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //獲取交易對列表
+//     pub async fn get_symbols(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v2".to_string(),
+//                                 format!("/symbols"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //通過orderId撤單
+//     pub async fn cancel_order_by_order_id(&mut self, order_id: String) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("DELETE".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders/{}", order_id),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //通過clientOid撤單
+//     pub async fn cancel_order_by_client_id(&mut self, client_id: String) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("DELETE".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/order/client-order/{}", client_id),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //全部撤單
+//     pub async fn cancel_order_all(&mut self, symbol: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "tradeType":"TRADE"
+//          });
+//         if symbol.len() > 0 {
+//             params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
+//         }
+//         let data = self.request("DELETE".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //现货下单-
+//     pub async fn spot_order(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //获取合约令牌-公共
+//     pub async fn get_public_token(&mut self) -> ResponseData {
+//         let params = serde_json::json!({});
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/bullet-public".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取合约令牌-私有
+//     pub async fn get_private_token(&mut self) -> ResponseData {
+//         let params = serde_json::json!({});
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/bullet-private".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     pub fn get_delays(&self) -> Vec<i64> {
+//         self.delays.clone()
+//     }
+//     pub fn get_avg_delay(&self) -> Decimal {
+//         self.avg_delay.clone()
+//     }
+//     pub fn get_max_delay(&self) -> i64 {
+//         self.max_delay.clone()
+//     }
+//     fn get_delay_info(&mut self) {
+//         let last_100 = if self.delays.len() > 100 {
+//             self.delays[self.delays.len() - 100..].to_vec()
+//         } else {
+//             self.delays.clone()
+//         };
+//
+//         let max_value = last_100.iter().max().unwrap();
+//         if max_value.clone().to_owned() > self.max_delay {
+//             self.max_delay = max_value.clone().to_owned();
+//         }
+//
+//         let sum: i64 = last_100.iter().sum();
+//         let sum_v = Decimal::from_i64(sum).unwrap();
+//         let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
+//         self.avg_delay = (sum_v / len_v).round_dp(1);
+//         self.delays = last_100.clone().into_iter().collect();
+//     }
+//     //调用请求
+//     pub async fn request(&mut self,
+//                          method: String,
+//                          prefix_url: String,
+//                          request_url: String,
+//                          is_login: bool,
+//                          params: String) -> ResponseData
+//     {
+//         trace!("login_param:{:?}", self.login_param);
+//         //解析账号信息
+//         let mut access_key = "".to_string();
+//         let mut secret_key = "".to_string();
+//         let mut pass_key = "".to_string();
+//         if self.login_param.contains_key("access_key") {
+//             access_key = self.login_param.get("access_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("secret_key") {
+//             secret_key = self.login_param.get("secret_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("pass_key") {
+//             pass_key = self.login_param.get("pass_key").unwrap().to_string();
+//         }
+//         let mut is_login_param = true;
+//         if access_key == "" || secret_key == "" || pass_key == "" {
+//             is_login_param = false
+//         }
+//
+//
+//         //请求头配置-如果需要登陆则存在额外配置
+//         let mut body = "".to_string();
+//
+//         let timestamp = chrono::Utc::now().timestamp_millis().to_string();
+//
+//         let mut headers = HeaderMap::new();
+//         headers.insert("Content-Type", "application/json".parse().unwrap());
+//         if method == "POST" {
+//             body = params.clone();
+//         }
+//
+//         //是否需要登陆-- 组装sing
+//         if is_login {
+//             if !is_login_param {
+//                 let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
+//                 return e;
+//             } else {
+//                 //需要登陆-且登陆参数齐全
+//                 trace!("param:{}", params);
+//                 trace!("body:{}", body);
+//                 //组装sing
+//                 let sing = Self::sign(secret_key.clone(),
+//                                       method.clone(),
+//                                       prefix_url.clone(),
+//                                       request_url.clone(),
+//                                       params.clone(),
+//                                       body.clone(),
+//                                       timestamp.clone(),
+//                 );
+//                 trace!("sing:{}", sing);
+//                 let passphrase = Self::passphrase(secret_key, pass_key);
+//                 trace!("passphrase:{}", passphrase);
+//                 //组装header
+//                 headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
+//             }
+//         }
+//
+//
+//         trace!("headers:{:?}", headers);
+//         let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
+//         let start_time = chrono::Utc::now().timestamp_millis();
+//         let get_response = self.http_toll(
+//             base_url.clone(),
+//             method.to_string(),
+//             params.clone(),
+//             headers,
+//         ).await;
+//         let time_array = chrono::Utc::now().timestamp_millis() - start_time;
+//         self.delays.push(time_array);
+//         self.get_delay_info();
+//         let res_data = Self::res_data_analysis(get_response, base_url, params);
+//         res_data
+//     }
+//
+//     pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
+//         let mut headers = HeaderMap::new();
+//         headers.insert("KC-API-KEY", access_key.parse().unwrap());
+//         headers.insert("KC-API-SIGN", sign.parse().unwrap());
+//         headers.insert("KC-API-TIMESTAMP", timestamp.parse().unwrap());
+//         headers.insert("KC-API-PASSPHRASE", passphrase.parse().unwrap());
+//         headers.insert("KC-API-KEY-VERSION", "2".parse().unwrap());
+//         headers
+//     }
+//     pub fn sign(secret_key: String,
+//                 method: String, prefix_url: String, request_url: String,
+//                 params: String, body_data: String, timestamp: String) -> String
+//     {
+//         let url = format!("{}{}", prefix_url, request_url);
+//         let params_str = RestTool::parse_params_to_str(params.clone());
+//         trace!("body_data:{}", body_data);
+//         // let body = Some(body_data);
+//         // let hashed_payload = if let Some(body) = body {
+//         //     let mut m = digest::Context::new(&digest::SHA256);
+//         //     m.update(body.as_bytes());
+//         //     hex::encode(m.finish().as_ref())
+//         // } else {
+//         //     String::new()
+//         // };
+//         // trace!("hashed_payload:{}", hashed_payload);
+//
+//         let mut message = format!("{}{}{}",
+//                                   timestamp,
+//                                   method,
+//                                   url
+//         );
+//         if method == "GET" || method == "DELETE" {
+//             message = if params_str.len() > 0 {
+//                 format!("{}?{}", message, params_str)
+//             } else {
+//                 format!("{}", message)
+//             };
+//         } else if method == "POST" || method == "PUT" {
+//             message = format!("{}{}", message, body_data);
+//         }
+//
+//         trace!("**********", );
+//         trace!("组装数据:{}", message);
+//         trace!("**********", );
+//
+//         let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
+//         mac.update(message.as_bytes());
+//         let result = mac.finalize().into_bytes();
+//         let base64_encoded = base64::encode(result);
+//         base64_encoded
+//     }
+//
+//     pub fn passphrase(secret_key: String, pass_key: String) -> String
+//     {
+//         let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
+//         mac.update(pass_key.as_bytes());
+//         let result = mac.finalize().into_bytes();
+//         let base64_encoded = base64::encode(result);
+//         base64_encoded
+//     }
+//
+//
+//     async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
+//         let res_data: ResponseData;
+//         /****请求接口与 地址*/
+//         let url = format!("{}{}", self.base_url.to_string(), request_path);
+//         let request_type = request_type.clone().to_uppercase();
+//         let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
+//             url.clone()
+//         } else {
+//             format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
+//         };
+//         trace!("url:{}", url);
+//         trace!("addrs_url:{}", addrs_url);
+//
+//
+//         let req = match request_type.as_str() {
+//             "GET" => self.client.get(addrs_url.clone()).headers(headers),
+//             "POST" => self.client.post(url.clone()).body(params).headers(headers),
+//             "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
+//             // "PUT" => self.client.put(url.clone()).json(&params),
+//             _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
+//         };
+//
+//         let response = req.send().await?;
+//         if response.status().is_success() {
+//             // 读取响应的内容
+//             let body = response.text().await?;
+//             // trace!("ok-----{}", body);
+//             res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
+//         } else {
+//             let body = response.text().await?;
+//             // trace!("error-----{}", body);
+//             res_data = ResponseData::error(self.label.clone(), body.to_string())
+//         }
+//
+//         Ok(res_data)
+//     }
+//
+//
+//     //res_data 解析
+//     pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
+//         match result {
+//             Ok(res_data) => {
+//                 if res_data.code != "200" {
+//                     // res_data
+//                     let mut error = res_data;
+//                     error.message = format!("错误:{},url:{},相关参数:{}", error.message, base_url, params);
+//                     error
+//                 } else {
+//                     let body: String = res_data.data;
+//                     let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
+//
+//                     let code = json_value["code"].as_str().unwrap();
+//
+//                     if code != "200000" {
+//                         let msg = json_value["msg"].as_str().unwrap();
+//                         // let error = ResponseData::new("".to_string(), code.to_string(),
+//                         //                               format!("错误:{},url:{},相关参数:{}", msg, base_url, params),
+//                         //                               "".parse().unwrap());
+//                         // error
+//
+//                         let mut error = ResponseData::error(res_data.label, msg.parse().unwrap());
+//                         error.code = code.parse().unwrap();
+//                         error.data = format!("请求地址:{},请求参数:{}", base_url, params);
+//                         error
+//                     } else {
+//                         let data = serde_json::to_string(&json_value["data"]).unwrap();
+//                         let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
+//                         success
+//                     }
+//                 }
+//             }
+//             Err(err) => {
+//                 let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", err, params));
+//                 error
+//             }
+//         }
+//     }
+// }

+ 625 - 625
exchanges/src/kucoin_swap_rest.rs

@@ -1,625 +1,625 @@
-use std::collections::BTreeMap;
-use reqwest::header::HeaderMap;
-use hmac::{Hmac, Mac, NewMac};
-use reqwest::{Client};
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use sha2::Sha256;
-use tracing::{info, trace};
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-
-#[derive(Clone, Debug)]
-pub struct KucoinSwapRest {
-    pub label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //是否需要登陆
-    //登陆所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl KucoinSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSwapRest
-    {
-        return KucoinSwapRest::new_label("default-KucoinSwapRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSwapRest {
-        let base_url = if is_colo {
-            "https://api-futures.kucoin.com".to_string()
-        } else {
-            "https://api-futures.kucoin.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",base_url);
-        } else {
-            info!("走普通通道:{}",base_url);
-        }
-        /*****返回结构体*******/
-        KucoinSwapRest {
-            label,
-            base_url,
-            client: Client::new(),
-            login_param,
-            delays: vec![],
-            max_delay: 0,
-            avg_delay: dec!(0.0),
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************rest请求函数********************************************************/
-    /*******************************************************************************************************/
-    pub async fn get_server_time(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/timestamp".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    // 获取成交记录
-    pub async fn get_fills(&mut self,
-                           symbol: String,
-                           order_id: String,
-                           side: String,
-                           start_at: i64,
-                           end_at: i64,
-                           page_size: i64,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-            "pageSize":1000
-         });
-        if order_id.len() > 0 {
-            params["orderId"] = serde_json::json!(order_id);
-        }
-        if side.len() > 0 {
-            params["side"] = serde_json::json!(side);
-        }
-        if start_at > 0 {
-            params["startAt"] = serde_json::json!(start_at);
-        }
-        if end_at > 0 {
-            params["endAt"] = serde_json::json!(end_at);
-        }
-        if page_size > 0 {
-            params["pageSize"] = serde_json::json!(page_size);
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/fills".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查询合约账户
-    pub async fn get_account(&mut self, contract: String) -> ResponseData {
-        let params = serde_json::json!({
-            "currency":contract
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/account-overview".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取仓位信息
-    pub async fn get_position(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                "/position".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查询所有的合约信息
-    pub async fn get_market_details(&mut self) -> ResponseData {
-        let params = serde_json::json!({});
-
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/contracts/active"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //实时行情
-    pub async fn get_ticker(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/ticker"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查看订单列表
-    pub async fn get_orders(&mut self, status: String, symbol: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            // "symbol":symbol
-         });
-        if symbol.len() > 0 {
-            params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
-        }
-        if status.len() > 0 {
-            params.as_object_mut().unwrap().insert("status".parse().unwrap(), serde_json::Value::from(status));
-        }
-        trace!("??{}",params.to_string());
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取用户仓位列表
-    pub async fn get_positions(&mut self, currency: String) -> ResponseData {
-        let params = serde_json::json!({
-            "currency":currency
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/positions"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //单个订单详情
-    pub async fn get_orders_details(&mut self, order_id: String, client_id: String) -> ResponseData {
-        let mut params = serde_json::json!({   });
-        let mut url = String::from("");
-        if order_id != "" {
-            url = format!("/orders/{}", order_id);
-        } else if client_id != "" {
-            url = format!("/orders/byClientOid");
-            params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_id));
-        }
-
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                url,
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    pub async fn swap_order(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //下单
-    pub async fn swap_bazaar_order(&mut self,
-                                   client_oid: String,
-                                   symbol: String,
-                                   origin_side: String,
-                                   size: u64,
-                                   leverage: String,
-                                   price: String,
-                                   order_type: String) -> ResponseData
-    {
-        let mut side = String::from("");
-        let mut params = serde_json::json!({
-            "clientOid":client_oid,
-            "symbol": symbol,
-            "size":size,
-            "leverage":leverage,
-            "reduceOnly":false,
-            "price":price,
-            "type":order_type,
-        });
-
-        let req = match origin_side.as_str() {
-            "kd" => {
-                side = "buy".to_string();
-                true
-            }
-            "pd" => {
-                side = "sell".to_string();
-                true
-            }
-            "kk" => {
-                side = "sell".to_string();
-                true
-            }
-            "pk" => {
-                side = "buy".to_string();
-                true
-            }
-            _ => { false } // 处理未知请求类型
-        };
-        if req {
-            params.as_object_mut().unwrap().insert("side".to_string(), serde_json::json!(side));
-        }
-
-        let data = self.swap_order(params).await;
-        data
-    }
-
-    //单个撤单
-    pub async fn cancel_order(&mut self, order_id: String, client_id: String) -> ResponseData {
-        let mut params = serde_json::json!({   });
-        let mut url = String::from("");
-        if order_id != "" {
-            url = format!("/orders/{}", order_id);
-        } else if client_id != "" {
-            url = format!("/orders/byClientOid");
-            params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_id));
-        }
-        let data = self.request("DELETE".to_string(),
-                                "/api/v1".to_string(),
-                                url,
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //批量撤单
-    pub async fn cancel_orders(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({   });
-        let data = self.request("DELETE".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders?symbol={}", symbol),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //全部撤單
-    pub async fn cancel_order_all(&mut self) -> ResponseData {
-        let params = serde_json::json!({   });
-        let data = self.request("DELETE".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/orders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-
-    //获取合约令牌-公共
-    pub async fn get_public_token(&mut self) -> ResponseData {
-        let params = serde_json::json!({});
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                "/bullet-public".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取合约令牌-私有
-    pub async fn get_private_token(&mut self) -> ResponseData {
-        let params = serde_json::json!({});
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                "/bullet-private".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //设置杠杆(修改階梯風險限額等級)
-    pub async fn set_leverage(&mut self, symbol: String, level: i8) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "level":level,
-        });
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/position/risk-limit-level/change"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查看杠杆(查詢杠桿代幣信息)
-    pub async fn get_leverage(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-        });
-        let data = self.request("GET".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/contracts/risk-limit/{}", symbol),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //设置 自动追加保证金
-    pub async fn auto_deposit_status(&mut self, symbol: String, status: bool) -> ResponseData {
-        let params = serde_json::json!({
-                "symbol":symbol,
-                "status":status
-        });
-        let data = self.request("POST".to_string(),
-                                "/api/v1".to_string(),
-                                format!("/position/margin/auto-deposit-status"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        self.delays.clone()
-    }
-    pub fn get_avg_delay(&self) -> Decimal {
-        self.avg_delay.clone()
-    }
-    pub fn get_max_delay(&self) -> i64 {
-        self.max_delay.clone()
-    }
-    fn get_delay_info(&mut self) {
-        let last_100 = if self.delays.len() > 100 {
-            self.delays[self.delays.len() - 100..].to_vec()
-        } else {
-            self.delays.clone()
-        };
-
-        let max_value = last_100.iter().max().unwrap();
-        if max_value.clone().to_owned() > self.max_delay {
-            self.max_delay = max_value.clone().to_owned();
-        }
-
-        let sum: i64 = last_100.iter().sum();
-        let sum_v = Decimal::from_i64(sum).unwrap();
-        let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
-        self.avg_delay = (sum_v / len_v).round_dp(1);
-        self.delays = last_100.clone().into_iter().collect();
-    }
-    //调用请求
-    pub async fn request(&mut self,
-                         method: String,
-                         prefix_url: String,
-                         request_url: String,
-                         is_login: bool,
-                         params: String) -> ResponseData
-    {
-        trace!("login_param:{:?}", self.login_param);
-        //解析账号信息
-        let mut access_key = "".to_string();
-        let mut secret_key = "".to_string();
-        let mut pass_key = "".to_string();
-        if self.login_param.contains_key("access_key") {
-            access_key = self.login_param.get("access_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("secret_key") {
-            secret_key = self.login_param.get("secret_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("pass_key") {
-            pass_key = self.login_param.get("pass_key").unwrap().to_string();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" || pass_key == "" {
-            is_login_param = false
-        }
-
-
-        //请求头配置-如果需要登陆则存在额外配置
-        let mut body = "".to_string();
-
-        let timestamp = chrono::Utc::now().timestamp_millis().to_string();
-
-        let mut headers = HeaderMap::new();
-        headers.insert("Content-Type", "application/json".parse().unwrap());
-        if method == "POST" {
-            body = params.clone();
-        }
-
-        //是否需要登陆-- 组装sing
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
-                return e;
-            } else {
-                //需要登陆-且登陆参数齐全
-                trace!("param:{}", params);
-                trace!("body:{}", body);
-                //组装sing
-                let sing = Self::sign(secret_key.clone(),
-                                      method.clone(),
-                                      prefix_url.clone(),
-                                      request_url.clone(),
-                                      params.clone(),
-                                      body.clone(),
-                                      timestamp.clone(),
-                );
-                trace!("sing:{}", sing);
-                let passphrase = Self::passphrase(secret_key, pass_key);
-                trace!("passphrase:{}", passphrase);
-                //组装header
-                headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
-            }
-        }
-
-
-        // trace!("headers:{:?}", headers);
-        let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let get_response = self.http_toll(
-            base_url.clone(),
-            method.to_string(),
-            params.clone(),
-            headers,
-        ).await;
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        self.get_delay_info();
-        let res_data = Self::res_data_analysis(get_response, base_url, params);
-        res_data
-    }
-
-    pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("KC-API-KEY", access_key.parse().unwrap());
-        headers.insert("KC-API-SIGN", sign.parse().unwrap());
-        headers.insert("KC-API-TIMESTAMP", timestamp.parse().unwrap());
-        headers.insert("KC-API-PASSPHRASE", passphrase.parse().unwrap());
-        headers.insert("KC-API-KEY-VERSION", "2".parse().unwrap());
-        headers
-    }
-    pub fn sign(secret_key: String,
-                method: String, prefix_url: String, request_url: String,
-                params: String, body_data: String, timestamp: String) -> String
-    {
-        let url = format!("{}{}", prefix_url, request_url);
-        let params_str = RestTool::parse_params_to_str(params.clone());
-        trace!("body_data:{}", body_data);
-        // let body = Some(body_data);
-        // let hashed_payload = if let Some(body) = body {
-        //     let mut m = digest::Context::new(&digest::SHA256);
-        //     m.update(body.as_bytes());
-        //     hex::encode(m.finish().as_ref())
-        // } else {
-        //     String::new()
-        // };
-        // trace!("hashed_payload:{}", hashed_payload);
-
-        let mut message = format!("{}{}{}",
-                                  timestamp,
-                                  method,
-                                  url
-        );
-        if method == "GET" || method == "DELETE" {
-            message = if params_str.len() > 0 {
-                format!("{}?{}", message, params_str)
-            } else {
-                format!("{}", message)
-            };
-        } else if method == "POST" || method == "PUT" {
-            message = format!("{}{}", message, body_data);
-        }
-
-        trace!("**********", );
-        trace!("组装数据:{}", message);
-        trace!("**********", );
-
-        let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
-        mac.update(message.as_bytes());
-        let result = mac.finalize().into_bytes();
-        let base64_encoded = base64::encode(result);
-        base64_encoded
-    }
-
-    pub fn passphrase(secret_key: String, pass_key: String) -> String
-    {
-        let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
-        mac.update(pass_key.as_bytes());
-        let result = mac.finalize().into_bytes();
-        let base64_encoded = base64::encode(result);
-        base64_encoded
-    }
-
-
-    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        let res_data: ResponseData;
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-        let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
-            url.clone()
-        } else {
-            format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
-        };
-        trace!("url:{}", url);
-        trace!("addrs_url:{}", addrs_url);
-
-        let req = match request_type.as_str() {
-            "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(url.clone()).body(params).headers(headers),
-            "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
-        };
-
-        let response = req.send().await?;
-        if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await?;
-            // trace!("ok-----{}", body);
-            res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
-        } else {
-            let body = response.text().await?;
-            // trace!("error-----{}", body);
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
-        }
-
-        Ok(res_data)
-    }
-
-
-    //res_data 解析
-    pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-        match result {
-            Ok(res_data) => {
-                if res_data.code != "200" {
-                    // res_data
-                    let mut error = res_data;
-                    error.message = format!("错误:{},url:{},相关参数:{}", error.message, base_url, params);
-                    error
-                } else {
-                    let body: String = res_data.data;
-                    let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
-
-                    let code = json_value["code"].as_str().unwrap();
-
-                    if code != "200000" {
-                        let msg = json_value["msg"].as_str().unwrap();
-                        // let error = ResponseData::new("".to_string(), code.to_string(),
-                        //                               format!("错误:{},url:{},相关参数:{}", msg, base_url, params),
-                        //                               "".parse().unwrap());
-                        // error
-
-                        let mut error = ResponseData::error(res_data.label, msg.parse().unwrap());
-                        error.code = code.parse().unwrap();
-                        error.data = format!("请求地址:{},请求参数:{}", base_url, params);
-                        error
-                    } else {
-                        let data = serde_json::to_string(&json_value["data"]).unwrap();
-                        let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
-                        success
-                    }
-                }
-            }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", err, params));
-                error
-            }
-        }
-    }
-}
+// use std::collections::BTreeMap;
+// use reqwest::header::HeaderMap;
+// use hmac::{Hmac, Mac, NewMac};
+// use reqwest::{Client};
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use rust_decimal_macros::dec;
+// use sha2::Sha256;
+// use tracing::{info, trace};
+// use crate::http_tool::RestTool;
+// use crate::response_base::ResponseData;
+//
+// #[derive(Clone, Debug)]
+// pub struct KucoinSwapRest {
+//     pub label: String,
+//     base_url: String,
+//     client: reqwest::Client,
+//     /*******参数*/
+//     //是否需要登陆
+//     //登陆所需参数
+//     login_param: BTreeMap<String, String>,
+//     delays: Vec<i64>,
+//     max_delay: i64,
+//     avg_delay: Decimal,
+// }
+//
+// impl KucoinSwapRest {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//
+//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSwapRest
+//     {
+//         return KucoinSwapRest::new_label("default-KucoinSwapRest".to_string(), is_colo, login_param);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSwapRest {
+//         let base_url = if is_colo {
+//             "https://api-futures.kucoin.com".to_string()
+//         } else {
+//             "https://api-futures.kucoin.com".to_string()
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",base_url);
+//         } else {
+//             info!("走普通通道:{}",base_url);
+//         }
+//         /*****返回结构体*******/
+//         KucoinSwapRest {
+//             label,
+//             base_url,
+//             client: Client::new(),
+//             login_param,
+//             delays: vec![],
+//             max_delay: 0,
+//             avg_delay: dec!(0.0),
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************rest请求函数********************************************************/
+//     /*******************************************************************************************************/
+//     pub async fn get_server_time(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/timestamp".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     // 获取成交记录
+//     pub async fn get_fills(&mut self,
+//                            symbol: String,
+//                            order_id: String,
+//                            side: String,
+//                            start_at: i64,
+//                            end_at: i64,
+//                            page_size: i64,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "symbol":symbol,
+//             "pageSize":1000
+//          });
+//         if order_id.len() > 0 {
+//             params["orderId"] = serde_json::json!(order_id);
+//         }
+//         if side.len() > 0 {
+//             params["side"] = serde_json::json!(side);
+//         }
+//         if start_at > 0 {
+//             params["startAt"] = serde_json::json!(start_at);
+//         }
+//         if end_at > 0 {
+//             params["endAt"] = serde_json::json!(end_at);
+//         }
+//         if page_size > 0 {
+//             params["pageSize"] = serde_json::json!(page_size);
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/fills".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查询合约账户
+//     pub async fn get_account(&mut self, contract: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "currency":contract
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/account-overview".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取仓位信息
+//     pub async fn get_position(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/position".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查询所有的合约信息
+//     pub async fn get_market_details(&mut self) -> ResponseData {
+//         let params = serde_json::json!({});
+//
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/contracts/active"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //实时行情
+//     pub async fn get_ticker(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/ticker"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查看订单列表
+//     pub async fn get_orders(&mut self, status: String, symbol: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             // "symbol":symbol
+//          });
+//         if symbol.len() > 0 {
+//             params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
+//         }
+//         if status.len() > 0 {
+//             params.as_object_mut().unwrap().insert("status".parse().unwrap(), serde_json::Value::from(status));
+//         }
+//         trace!("??{}",params.to_string());
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取用户仓位列表
+//     pub async fn get_positions(&mut self, currency: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "currency":currency
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/positions"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //单个订单详情
+//     pub async fn get_orders_details(&mut self, order_id: String, client_id: String) -> ResponseData {
+//         let mut params = serde_json::json!({   });
+//         let mut url = String::from("");
+//         if order_id != "" {
+//             url = format!("/orders/{}", order_id);
+//         } else if client_id != "" {
+//             url = format!("/orders/byClientOid");
+//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_id));
+//         }
+//
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 url,
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     pub async fn swap_order(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //下单
+//     pub async fn swap_bazaar_order(&mut self,
+//                                    client_oid: String,
+//                                    symbol: String,
+//                                    origin_side: String,
+//                                    size: u64,
+//                                    leverage: String,
+//                                    price: String,
+//                                    order_type: String) -> ResponseData
+//     {
+//         let mut side = String::from("");
+//         let mut params = serde_json::json!({
+//             "clientOid":client_oid,
+//             "symbol": symbol,
+//             "size":size,
+//             "leverage":leverage,
+//             "reduceOnly":false,
+//             "price":price,
+//             "type":order_type,
+//         });
+//
+//         let req = match origin_side.as_str() {
+//             "kd" => {
+//                 side = "buy".to_string();
+//                 true
+//             }
+//             "pd" => {
+//                 side = "sell".to_string();
+//                 true
+//             }
+//             "kk" => {
+//                 side = "sell".to_string();
+//                 true
+//             }
+//             "pk" => {
+//                 side = "buy".to_string();
+//                 true
+//             }
+//             _ => { false } // 处理未知请求类型
+//         };
+//         if req {
+//             params.as_object_mut().unwrap().insert("side".to_string(), serde_json::json!(side));
+//         }
+//
+//         let data = self.swap_order(params).await;
+//         data
+//     }
+//
+//     //单个撤单
+//     pub async fn cancel_order(&mut self, order_id: String, client_id: String) -> ResponseData {
+//         let mut params = serde_json::json!({   });
+//         let mut url = String::from("");
+//         if order_id != "" {
+//             url = format!("/orders/{}", order_id);
+//         } else if client_id != "" {
+//             url = format!("/orders/byClientOid");
+//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_id));
+//         }
+//         let data = self.request("DELETE".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 url,
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //批量撤单
+//     pub async fn cancel_orders(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({   });
+//         let data = self.request("DELETE".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders?symbol={}", symbol),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //全部撤單
+//     pub async fn cancel_order_all(&mut self) -> ResponseData {
+//         let params = serde_json::json!({   });
+//         let data = self.request("DELETE".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/orders"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//
+//     //获取合约令牌-公共
+//     pub async fn get_public_token(&mut self) -> ResponseData {
+//         let params = serde_json::json!({});
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/bullet-public".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取合约令牌-私有
+//     pub async fn get_private_token(&mut self) -> ResponseData {
+//         let params = serde_json::json!({});
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 "/bullet-private".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //设置杠杆(修改階梯風險限額等級)
+//     pub async fn set_leverage(&mut self, symbol: String, level: i8) -> ResponseData {
+//         let params = serde_json::json!({
+//             "symbol":symbol,
+//             "level":level,
+//         });
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/position/risk-limit-level/change"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查看杠杆(查詢杠桿代幣信息)
+//     pub async fn get_leverage(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//         });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/contracts/risk-limit/{}", symbol),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //设置 自动追加保证金
+//     pub async fn auto_deposit_status(&mut self, symbol: String, status: bool) -> ResponseData {
+//         let params = serde_json::json!({
+//                 "symbol":symbol,
+//                 "status":status
+//         });
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v1".to_string(),
+//                                 format!("/position/margin/auto-deposit-status"),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     pub fn get_delays(&self) -> Vec<i64> {
+//         self.delays.clone()
+//     }
+//     pub fn get_avg_delay(&self) -> Decimal {
+//         self.avg_delay.clone()
+//     }
+//     pub fn get_max_delay(&self) -> i64 {
+//         self.max_delay.clone()
+//     }
+//     fn get_delay_info(&mut self) {
+//         let last_100 = if self.delays.len() > 100 {
+//             self.delays[self.delays.len() - 100..].to_vec()
+//         } else {
+//             self.delays.clone()
+//         };
+//
+//         let max_value = last_100.iter().max().unwrap();
+//         if max_value.clone().to_owned() > self.max_delay {
+//             self.max_delay = max_value.clone().to_owned();
+//         }
+//
+//         let sum: i64 = last_100.iter().sum();
+//         let sum_v = Decimal::from_i64(sum).unwrap();
+//         let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
+//         self.avg_delay = (sum_v / len_v).round_dp(1);
+//         self.delays = last_100.clone().into_iter().collect();
+//     }
+//     //调用请求
+//     pub async fn request(&mut self,
+//                          method: String,
+//                          prefix_url: String,
+//                          request_url: String,
+//                          is_login: bool,
+//                          params: String) -> ResponseData
+//     {
+//         trace!("login_param:{:?}", self.login_param);
+//         //解析账号信息
+//         let mut access_key = "".to_string();
+//         let mut secret_key = "".to_string();
+//         let mut pass_key = "".to_string();
+//         if self.login_param.contains_key("access_key") {
+//             access_key = self.login_param.get("access_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("secret_key") {
+//             secret_key = self.login_param.get("secret_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("pass_key") {
+//             pass_key = self.login_param.get("pass_key").unwrap().to_string();
+//         }
+//         let mut is_login_param = true;
+//         if access_key == "" || secret_key == "" || pass_key == "" {
+//             is_login_param = false
+//         }
+//
+//
+//         //请求头配置-如果需要登陆则存在额外配置
+//         let mut body = "".to_string();
+//
+//         let timestamp = chrono::Utc::now().timestamp_millis().to_string();
+//
+//         let mut headers = HeaderMap::new();
+//         headers.insert("Content-Type", "application/json".parse().unwrap());
+//         if method == "POST" {
+//             body = params.clone();
+//         }
+//
+//         //是否需要登陆-- 组装sing
+//         if is_login {
+//             if !is_login_param {
+//                 let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
+//                 return e;
+//             } else {
+//                 //需要登陆-且登陆参数齐全
+//                 trace!("param:{}", params);
+//                 trace!("body:{}", body);
+//                 //组装sing
+//                 let sing = Self::sign(secret_key.clone(),
+//                                       method.clone(),
+//                                       prefix_url.clone(),
+//                                       request_url.clone(),
+//                                       params.clone(),
+//                                       body.clone(),
+//                                       timestamp.clone(),
+//                 );
+//                 trace!("sing:{}", sing);
+//                 let passphrase = Self::passphrase(secret_key, pass_key);
+//                 trace!("passphrase:{}", passphrase);
+//                 //组装header
+//                 headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
+//             }
+//         }
+//
+//
+//         // trace!("headers:{:?}", headers);
+//         let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
+//         let start_time = chrono::Utc::now().timestamp_millis();
+//         let get_response = self.http_toll(
+//             base_url.clone(),
+//             method.to_string(),
+//             params.clone(),
+//             headers,
+//         ).await;
+//         let time_array = chrono::Utc::now().timestamp_millis() - start_time;
+//         self.delays.push(time_array);
+//         self.get_delay_info();
+//         let res_data = Self::res_data_analysis(get_response, base_url, params);
+//         res_data
+//     }
+//
+//     pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
+//         let mut headers = HeaderMap::new();
+//         headers.insert("KC-API-KEY", access_key.parse().unwrap());
+//         headers.insert("KC-API-SIGN", sign.parse().unwrap());
+//         headers.insert("KC-API-TIMESTAMP", timestamp.parse().unwrap());
+//         headers.insert("KC-API-PASSPHRASE", passphrase.parse().unwrap());
+//         headers.insert("KC-API-KEY-VERSION", "2".parse().unwrap());
+//         headers
+//     }
+//     pub fn sign(secret_key: String,
+//                 method: String, prefix_url: String, request_url: String,
+//                 params: String, body_data: String, timestamp: String) -> String
+//     {
+//         let url = format!("{}{}", prefix_url, request_url);
+//         let params_str = RestTool::parse_params_to_str(params.clone());
+//         trace!("body_data:{}", body_data);
+//         // let body = Some(body_data);
+//         // let hashed_payload = if let Some(body) = body {
+//         //     let mut m = digest::Context::new(&digest::SHA256);
+//         //     m.update(body.as_bytes());
+//         //     hex::encode(m.finish().as_ref())
+//         // } else {
+//         //     String::new()
+//         // };
+//         // trace!("hashed_payload:{}", hashed_payload);
+//
+//         let mut message = format!("{}{}{}",
+//                                   timestamp,
+//                                   method,
+//                                   url
+//         );
+//         if method == "GET" || method == "DELETE" {
+//             message = if params_str.len() > 0 {
+//                 format!("{}?{}", message, params_str)
+//             } else {
+//                 format!("{}", message)
+//             };
+//         } else if method == "POST" || method == "PUT" {
+//             message = format!("{}{}", message, body_data);
+//         }
+//
+//         trace!("**********", );
+//         trace!("组装数据:{}", message);
+//         trace!("**********", );
+//
+//         let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
+//         mac.update(message.as_bytes());
+//         let result = mac.finalize().into_bytes();
+//         let base64_encoded = base64::encode(result);
+//         base64_encoded
+//     }
+//
+//     pub fn passphrase(secret_key: String, pass_key: String) -> String
+//     {
+//         let mut mac = Hmac::<Sha256>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
+//         mac.update(pass_key.as_bytes());
+//         let result = mac.finalize().into_bytes();
+//         let base64_encoded = base64::encode(result);
+//         base64_encoded
+//     }
+//
+//
+//     async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
+//         let res_data: ResponseData;
+//         /****请求接口与 地址*/
+//         let url = format!("{}{}", self.base_url.to_string(), request_path);
+//         let request_type = request_type.clone().to_uppercase();
+//         let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
+//             url.clone()
+//         } else {
+//             format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
+//         };
+//         trace!("url:{}", url);
+//         trace!("addrs_url:{}", addrs_url);
+//
+//         let req = match request_type.as_str() {
+//             "GET" => self.client.get(addrs_url.clone()).headers(headers),
+//             "POST" => self.client.post(url.clone()).body(params).headers(headers),
+//             "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
+//             // "PUT" => self.client.put(url.clone()).json(&params),
+//             _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
+//         };
+//
+//         let response = req.send().await?;
+//         if response.status().is_success() {
+//             // 读取响应的内容
+//             let body = response.text().await?;
+//             // trace!("ok-----{}", body);
+//             res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
+//         } else {
+//             let body = response.text().await?;
+//             // trace!("error-----{}", body);
+//             res_data = ResponseData::error(self.label.clone(), body.to_string())
+//         }
+//
+//         Ok(res_data)
+//     }
+//
+//
+//     //res_data 解析
+//     pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
+//         match result {
+//             Ok(res_data) => {
+//                 if res_data.code != "200" {
+//                     // res_data
+//                     let mut error = res_data;
+//                     error.message = format!("错误:{},url:{},相关参数:{}", error.message, base_url, params);
+//                     error
+//                 } else {
+//                     let body: String = res_data.data;
+//                     let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
+//
+//                     let code = json_value["code"].as_str().unwrap();
+//
+//                     if code != "200000" {
+//                         let msg = json_value["msg"].as_str().unwrap();
+//                         // let error = ResponseData::new("".to_string(), code.to_string(),
+//                         //                               format!("错误:{},url:{},相关参数:{}", msg, base_url, params),
+//                         //                               "".parse().unwrap());
+//                         // error
+//
+//                         let mut error = ResponseData::error(res_data.label, msg.parse().unwrap());
+//                         error.code = code.parse().unwrap();
+//                         error.data = format!("请求地址:{},请求参数:{}", base_url, params);
+//                         error
+//                     } else {
+//                         let data = serde_json::to_string(&json_value["data"]).unwrap();
+//                         let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
+//                         success
+//                     }
+//                 }
+//             }
+//             Err(err) => {
+//                 let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", err, params));
+//                 error
+//             }
+//         }
+//     }
+// }

+ 580 - 580
exchanges/src/okx_swap_rest.rs

@@ -1,580 +1,580 @@
-use std::collections::BTreeMap;
-use reqwest::header::HeaderMap;
-use reqwest::{Client};
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use tracing::{info, trace};
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-use ring::hmac;
-
-#[derive(Clone, Debug)]
-pub struct OkxSwapRest {
-    pub label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //是否需要登陆
-    //登陆所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-
-}
-
-impl OkxSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> OkxSwapRest
-    {
-        return OkxSwapRest::new_label("default-OkxSwapRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> OkxSwapRest {
-        let base_url = if is_colo {
-            "https://www.okx.com".to_string()
-        } else {
-            "https://www.okx.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",base_url);
-        } else {
-            info!("走普通通道:{}",base_url);
-        }
-        /*****返回结构体*******/
-        OkxSwapRest {
-            label,
-            base_url,
-            client: Client::new(),
-            login_param,
-            delays: vec![],
-            max_delay: 0,
-            avg_delay: dec!(0.0),
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************rest请求函数********************************************************/
-    /*******************************************************************************************************/
-    //获取订单信息
-    pub async fn get_order(&mut self, symbol: String, ord_id: String, cl_ord_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "instId":symbol
-         });
-        if ord_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("ordId".parse().unwrap(), serde_json::Value::from(ord_id));
-        }
-        if cl_ord_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("clOrdId".parse().unwrap(), serde_json::Value::from(cl_ord_id));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/trade/order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取未成交订单列表
-    pub async fn get_incomplete_order(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "instId":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/trade/orders-pending".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取系统时间
-    pub async fn get_server_time(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/public/time".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查看持仓信息
-    pub async fn get_positions(&mut self, inst_type: String) -> ResponseData {
-        let mut params = serde_json::json!({
-         });
-        if inst_type.len() > 0 {
-            params.as_object_mut().unwrap().insert("instType".parse().unwrap(), serde_json::Value::from(inst_type));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/account/positions".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取单个产品行情信息
-    pub async fn get_ticker(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "instId":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/market/ticker".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查看账户余额
-    pub async fn get_balance(&mut self, ccy: String) -> ResponseData {
-        let params = serde_json::json!({
-            "ccy":ccy
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/account/balance".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取交易产品基础信息
-    pub async fn get_instruments(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-           "instType":"SWAP"
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/public/instruments".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取成交明细(近三天)
-    pub async fn get_trade_fills(&mut self, after: String) -> ResponseData {
-        let mut params = serde_json::json!({
-             "instType": "SWAP",
-             "limit":"100"
-         });
-        if after.len() > 0 {
-            params.as_object_mut().unwrap().insert("after".parse().unwrap(), serde_json::Value::from(after));
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/trade/fills".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //获取成交明细(近三个月)
-    pub async fn get_trade_fills_history(&mut self, inst_id: String, begin: String, end: String, limit: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "instType": "SWAP",
-            "instId":inst_id,
-            "limit":100,
-         });
-
-        if begin.len() > 0 {
-            params["begin"] = serde_json::json!(begin);
-        }
-        if end.len() > 0 {
-            params["end"] = serde_json::json!(end);
-        }
-        if limit.len() > 0 {
-            params["limit"] = serde_json::json!(limit);
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/trade/fills-history".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //合约-下单
-    pub async fn swap_order(&mut self, params: serde_json::Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/api/v5".to_string(),
-                                "/trade/order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //撤单
-    pub async fn cancel_order(&mut self, symbol: String, ord_id: String, cl_ord_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-             "instId": symbol
-         });
-        if ord_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("ordId".parse().unwrap(), serde_json::Value::from(ord_id));
-        }
-        if cl_ord_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("clOrdId".parse().unwrap(), serde_json::Value::from(cl_ord_id));
-        }
-        let data = self.request("POST".to_string(),
-                                "/api/v5".to_string(),
-                                "/trade/cancel-order".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //设置杠杆倍数-单币种保证金`账户在`全仓`交易模式下,设置`币币杠杆`的杠杆倍数(币对层面)
-    pub async fn set_leverage(&mut self, symbol: String, lever: String) -> ResponseData {
-        let params = serde_json::json!({
-             "instId": symbol,
-             "lever": lever,
-             "mgnMode": "cross"
-         });
-        let data = self.request("POST".to_string(),
-                                "/api/v5".to_string(),
-                                "/account/set-leverage".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //设置持仓模式
-    pub async fn set_position_mode(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-             "posMode": "long_short_mode",
-         });
-        let data = self.request("POST".to_string(),
-                                "/api/v5".to_string(),
-                                "/account/set-position-mode".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //获取历史订单记录(近七天)
-    pub async fn get_orders_history(&mut self,
-                                    sprd_id: String,
-                                    ord_type: String,
-                                    state: String,
-                                    begin: String,
-                                    end: String,
-                                    limit: String,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-         });
-        if sprd_id.len() > 0 {
-            params["sprdId"] = serde_json::json!(sprd_id);
-        }
-        if ord_type.len() > 0 {
-            params["ordType"] = serde_json::json!(ord_type);
-        }
-        if state.len() > 0 {
-            params["state"] = serde_json::json!(state);
-        }
-        if begin.len() > 0 {
-            params["begin"] = serde_json::json!(begin);
-        }
-        if end.len() > 0 {
-            params["end"] = serde_json::json!(end);
-        }
-        if limit.len() > 0 {
-            params["limit"] = serde_json::json!(limit);
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/sprd/orders-history".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //获取历史成交数据(近七天)
-    pub async fn get_trades(&mut self,
-                            sprd_id: String,
-                            trade_id: String,
-                            ord_id: String,
-                            begin: String,
-                            end: String,
-                            limit: String,
-    ) -> ResponseData {
-        let mut params = serde_json::json!({
-         });
-        if sprd_id.len() > 0 {
-            params["sprdId"] = serde_json::json!(sprd_id);
-        }
-        if trade_id.len() > 0 {
-            params["tradeId"] = serde_json::json!(trade_id);
-        }
-        if ord_id.len() > 0 {
-            params["ordId"] = serde_json::json!(ord_id);
-        }
-        if begin.len() > 0 {
-            params["begin"] = serde_json::json!(begin);
-        }
-        if end.len() > 0 {
-            params["end"] = serde_json::json!(end);
-        }
-        if limit.len() > 0 {
-            params["limit"] = serde_json::json!(limit);
-        }
-        let data = self.request("GET".to_string(),
-                                "/api/v5".to_string(),
-                                "/sprd/trades".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        self.delays.clone()
-    }
-    pub fn get_avg_delay(&self) -> Decimal {
-        self.avg_delay.clone()
-    }
-    pub fn get_max_delay(&self) -> i64 {
-        self.max_delay.clone()
-    }
-    fn get_delay_info(&mut self) {
-        let last_100 = if self.delays.len() > 100 {
-            self.delays[self.delays.len() - 100..].to_vec()
-        } else {
-            self.delays.clone()
-        };
-
-        let max_value = last_100.iter().max().unwrap();
-        if max_value.clone().to_owned() > self.max_delay {
-            self.max_delay = max_value.clone().to_owned();
-        }
-
-        let sum: i64 = last_100.iter().sum();
-        let sum_v = Decimal::from_i64(sum).unwrap();
-        let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
-        self.avg_delay = (sum_v / len_v).round_dp(1);
-        self.delays = last_100.clone().into_iter().collect();
-    }
-    //调用请求
-    pub async fn request(&mut self,
-                         method: String,
-                         prefix_url: String,
-                         request_url: String,
-                         is_login: bool,
-                         params: String) -> ResponseData
-    {
-        trace!("login_param:{:?}", self.login_param);
-        //解析账号信息
-        let mut access_key = "".to_string();
-        let mut secret_key = "".to_string();
-        let mut passphrase = "".to_string();
-        if self.login_param.contains_key("access_key") {
-            access_key = self.login_param.get("access_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("secret_key") {
-            secret_key = self.login_param.get("secret_key").unwrap().to_string();
-        }
-        if self.login_param.contains_key("pass_key") {
-            passphrase = self.login_param.get("pass_key").unwrap().to_string();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" || passphrase == "" {
-            is_login_param = false
-        }
-
-
-        //请求头配置-如果需要登陆则存在额外配置
-        let mut body = "".to_string();
-        let timestamp = Self::get_timestamp();
-        let mut headers = HeaderMap::new();
-        headers.insert("Content-Type", "application/json".parse().unwrap());
-        if method == "POST" {
-            body = params.clone();
-        }
-
-
-        //是否需要登陆-- 组装sing
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
-                return e;
-            } else {
-                //需要登陆-且登陆参数齐全
-                trace!("param:{}", params);
-                trace!("body:{}", body);
-                //组装sing
-                let sing = Self::sign(secret_key.clone(),
-                                      method.clone(),
-                                      prefix_url.clone(),
-                                      request_url.clone(),
-                                      params.clone(),
-                                      body.clone(),
-                                      timestamp.clone(),
-                );
-                //组装header
-                headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
-            }
-        }
-
-
-        // trace!("headers:{:?}", headers);
-        let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let get_response = self.http_toll(
-            format!("{}{}", prefix_url.clone(), request_url.clone()),
-            method.to_string(),
-            params.clone(),
-            headers,
-        ).await;
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        self.get_delay_info();
-        let res_data = Self::res_data_analysis(get_response, base_url, params);
-        res_data
-    }
-
-    pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("OK-ACCESS-KEY", access_key.parse().unwrap());
-        headers.insert("OK-ACCESS-SIGN", sign.parse().unwrap());
-        headers.insert("OK-ACCESS-TIMESTAMP", timestamp.parse().unwrap());
-        headers.insert("OK-ACCESS-PASSPHRASE", passphrase.parse().unwrap());
-        headers
-    }
-    pub fn sign(secret_key: String,
-                method: String, prefix_url: String, request_url: String,
-                params: String, body: String, timestamp: String) -> String
-    {
-        /*签名生成*/
-        let url_param_str = RestTool::parse_params_to_str(params);
-        let base_url = if method == "GET" {
-            format!("{}{}?{}", prefix_url, request_url, url_param_str)
-        } else {
-            format!("{}{}", prefix_url, request_url)
-        };
-
-        // 时间戳 + 请求类型+ 请求参数字符串
-        let message = format!("{}{}{}{}", timestamp, method, base_url, body);
-        trace!("message:{}",message);
-
-        // 做签名
-        let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-        let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-        let sign = base64::encode(result);
-        sign
-    }
-
-    async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        let res_data: ResponseData;
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-        let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
-            url.clone()
-        } else {
-            format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
-        };
-        trace!("url:{}", url);
-        trace!("addrs_url:{}", addrs_url);
-        let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-        trace!("params_json:{}",params_json);
-        trace!("headers:{:?}",headers);
-
-
-        let req = match request_type.as_str() {
-            "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(url.clone()).body(params).headers(headers),
-            "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
-        };
-
-        let response = req.send().await?;
-        if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await?;
-            // trace!("ok-----{}", body);
-            res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
-        } else {
-            let body = response.text().await?;
-            // trace!("error-----{}", body);
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
-        }
-
-        Ok(res_data)
-    }
-
-
-    //res_data 解析
-    pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-        // trace!("原始数据:{:?}",result);
-        match result {
-            Ok(res_data) => {
-                if res_data.code != "200" {
-                    // trace!("不等于200");
-                    let message: String = res_data.message;
-                    let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
-                    let code = json_value["code"].as_str().unwrap();
-                    let msg = json_value["msg"].as_str().unwrap();
-                    let error = ResponseData::new("".to_string(),
-                                                  format!("{}", code),
-                                                  format!("{}", msg),
-                                                  format!("请求地址:{},请求参数:{}", base_url, params));
-                    error
-                } else {
-                    // trace!("等于200");
-                    let body: String = res_data.data;
-                    let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
-
-                    let code = json_value["code"].as_str().unwrap();
-                    if code == "0" {
-                        let data = serde_json::to_string(&json_value["data"]).unwrap();
-                        let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
-                        success
-                    } else if code == "1" || code == "0" {
-                        let msg = json_value["msg"].as_str().unwrap();
-                        let data = serde_json::to_string(&json_value["data"]).unwrap();
-
-                        let data_json: serde_json::Value = serde_json::from_str(&data).unwrap();
-                        let code_v = data_json[0]["sCode"].as_str().unwrap();
-                        let msg_v = data_json[0]["sMsg"].as_str().unwrap();
-                        // trace!("发生错误:??{:?}",data_json.to_string());
-                        let error = ResponseData::new("".to_string(),
-                                                      format!("{}", code_v),
-                                                      format!("{}:{}", msg, msg_v),
-                                                      format!("请求地址:{},请求参数:{}", base_url, params));
-                        error
-                    } else {
-                        let msg = json_value["msg"].as_str().unwrap();
-                        // trace!("发生错误:??{:?}",data_json.to_string());
-                        let error = ResponseData::new("".to_string(),
-                                                      format!("{}", code),
-                                                      format!("{}", msg),
-                                                      format!("请求地址:{},请求参数:{}", base_url, params));
-                        error
-                    }
-                }
-            }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
-                error
-            }
-        }
-    }
-    fn get_timestamp() -> String {
-        chrono::Utc::now()
-            .format("%Y-%m-%dT%H:%M:%S%.3fZ")
-            .to_string()
-    }
-}
+// use std::collections::BTreeMap;
+// use reqwest::header::HeaderMap;
+// use reqwest::{Client};
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use rust_decimal_macros::dec;
+// use tracing::{info, trace};
+// use crate::http_tool::RestTool;
+// use crate::response_base::ResponseData;
+// use ring::hmac;
+//
+// #[derive(Clone, Debug)]
+// pub struct OkxSwapRest {
+//     pub label: String,
+//     base_url: String,
+//     client: reqwest::Client,
+//     /*******参数*/
+//     //是否需要登陆
+//     //登陆所需参数
+//     login_param: BTreeMap<String, String>,
+//     delays: Vec<i64>,
+//     max_delay: i64,
+//     avg_delay: Decimal,
+//
+// }
+//
+// impl OkxSwapRest {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//
+//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> OkxSwapRest
+//     {
+//         return OkxSwapRest::new_label("default-OkxSwapRest".to_string(), is_colo, login_param);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> OkxSwapRest {
+//         let base_url = if is_colo {
+//             "https://www.okx.com".to_string()
+//         } else {
+//             "https://www.okx.com".to_string()
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",base_url);
+//         } else {
+//             info!("走普通通道:{}",base_url);
+//         }
+//         /*****返回结构体*******/
+//         OkxSwapRest {
+//             label,
+//             base_url,
+//             client: Client::new(),
+//             login_param,
+//             delays: vec![],
+//             max_delay: 0,
+//             avg_delay: dec!(0.0),
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************rest请求函数********************************************************/
+//     /*******************************************************************************************************/
+//     //获取订单信息
+//     pub async fn get_order(&mut self, symbol: String, ord_id: String, cl_ord_id: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "instId":symbol
+//          });
+//         if ord_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("ordId".parse().unwrap(), serde_json::Value::from(ord_id));
+//         }
+//         if cl_ord_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("clOrdId".parse().unwrap(), serde_json::Value::from(cl_ord_id));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/trade/order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取未成交订单列表
+//     pub async fn get_incomplete_order(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "instId":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/trade/orders-pending".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取系统时间
+//     pub async fn get_server_time(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/public/time".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查看持仓信息
+//     pub async fn get_positions(&mut self, inst_type: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//          });
+//         if inst_type.len() > 0 {
+//             params.as_object_mut().unwrap().insert("instType".parse().unwrap(), serde_json::Value::from(inst_type));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/account/positions".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取单个产品行情信息
+//     pub async fn get_ticker(&mut self, symbol: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "instId":symbol
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/market/ticker".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //查看账户余额
+//     pub async fn get_balance(&mut self, ccy: String) -> ResponseData {
+//         let params = serde_json::json!({
+//             "ccy":ccy
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/account/balance".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取交易产品基础信息
+//     pub async fn get_instruments(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//            "instType":"SWAP"
+//          });
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/public/instruments".to_string(),
+//                                 false,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //获取成交明细(近三天)
+//     pub async fn get_trade_fills(&mut self, after: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//              "instType": "SWAP",
+//              "limit":"100"
+//          });
+//         if after.len() > 0 {
+//             params.as_object_mut().unwrap().insert("after".parse().unwrap(), serde_json::Value::from(after));
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/trade/fills".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //获取成交明细(近三个月)
+//     pub async fn get_trade_fills_history(&mut self, inst_id: String, begin: String, end: String, limit: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//             "instType": "SWAP",
+//             "instId":inst_id,
+//             "limit":100,
+//          });
+//
+//         if begin.len() > 0 {
+//             params["begin"] = serde_json::json!(begin);
+//         }
+//         if end.len() > 0 {
+//             params["end"] = serde_json::json!(end);
+//         }
+//         if limit.len() > 0 {
+//             params["limit"] = serde_json::json!(limit);
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/trade/fills-history".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //合约-下单
+//     pub async fn swap_order(&mut self, params: serde_json::Value) -> ResponseData {
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/trade/order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //撤单
+//     pub async fn cancel_order(&mut self, symbol: String, ord_id: String, cl_ord_id: String) -> ResponseData {
+//         let mut params = serde_json::json!({
+//              "instId": symbol
+//          });
+//         if ord_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("ordId".parse().unwrap(), serde_json::Value::from(ord_id));
+//         }
+//         if cl_ord_id.len() > 0 {
+//             params.as_object_mut().unwrap().insert("clOrdId".parse().unwrap(), serde_json::Value::from(cl_ord_id));
+//         }
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/trade/cancel-order".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //设置杠杆倍数-单币种保证金`账户在`全仓`交易模式下,设置`币币杠杆`的杠杆倍数(币对层面)
+//     pub async fn set_leverage(&mut self, symbol: String, lever: String) -> ResponseData {
+//         let params = serde_json::json!({
+//              "instId": symbol,
+//              "lever": lever,
+//              "mgnMode": "cross"
+//          });
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/account/set-leverage".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//     //设置持仓模式
+//     pub async fn set_position_mode(&mut self) -> ResponseData {
+//         let params = serde_json::json!({
+//              "posMode": "long_short_mode",
+//          });
+//         let data = self.request("POST".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/account/set-position-mode".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //获取历史订单记录(近七天)
+//     pub async fn get_orders_history(&mut self,
+//                                     sprd_id: String,
+//                                     ord_type: String,
+//                                     state: String,
+//                                     begin: String,
+//                                     end: String,
+//                                     limit: String,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//          });
+//         if sprd_id.len() > 0 {
+//             params["sprdId"] = serde_json::json!(sprd_id);
+//         }
+//         if ord_type.len() > 0 {
+//             params["ordType"] = serde_json::json!(ord_type);
+//         }
+//         if state.len() > 0 {
+//             params["state"] = serde_json::json!(state);
+//         }
+//         if begin.len() > 0 {
+//             params["begin"] = serde_json::json!(begin);
+//         }
+//         if end.len() > 0 {
+//             params["end"] = serde_json::json!(end);
+//         }
+//         if limit.len() > 0 {
+//             params["limit"] = serde_json::json!(limit);
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/sprd/orders-history".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     //获取历史成交数据(近七天)
+//     pub async fn get_trades(&mut self,
+//                             sprd_id: String,
+//                             trade_id: String,
+//                             ord_id: String,
+//                             begin: String,
+//                             end: String,
+//                             limit: String,
+//     ) -> ResponseData {
+//         let mut params = serde_json::json!({
+//          });
+//         if sprd_id.len() > 0 {
+//             params["sprdId"] = serde_json::json!(sprd_id);
+//         }
+//         if trade_id.len() > 0 {
+//             params["tradeId"] = serde_json::json!(trade_id);
+//         }
+//         if ord_id.len() > 0 {
+//             params["ordId"] = serde_json::json!(ord_id);
+//         }
+//         if begin.len() > 0 {
+//             params["begin"] = serde_json::json!(begin);
+//         }
+//         if end.len() > 0 {
+//             params["end"] = serde_json::json!(end);
+//         }
+//         if limit.len() > 0 {
+//             params["limit"] = serde_json::json!(limit);
+//         }
+//         let data = self.request("GET".to_string(),
+//                                 "/api/v5".to_string(),
+//                                 "/sprd/trades".to_string(),
+//                                 true,
+//                                 params.to_string(),
+//         ).await;
+//         data
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     pub fn get_delays(&self) -> Vec<i64> {
+//         self.delays.clone()
+//     }
+//     pub fn get_avg_delay(&self) -> Decimal {
+//         self.avg_delay.clone()
+//     }
+//     pub fn get_max_delay(&self) -> i64 {
+//         self.max_delay.clone()
+//     }
+//     fn get_delay_info(&mut self) {
+//         let last_100 = if self.delays.len() > 100 {
+//             self.delays[self.delays.len() - 100..].to_vec()
+//         } else {
+//             self.delays.clone()
+//         };
+//
+//         let max_value = last_100.iter().max().unwrap();
+//         if max_value.clone().to_owned() > self.max_delay {
+//             self.max_delay = max_value.clone().to_owned();
+//         }
+//
+//         let sum: i64 = last_100.iter().sum();
+//         let sum_v = Decimal::from_i64(sum).unwrap();
+//         let len_v = Decimal::from_u64(last_100.len() as u64).unwrap();
+//         self.avg_delay = (sum_v / len_v).round_dp(1);
+//         self.delays = last_100.clone().into_iter().collect();
+//     }
+//     //调用请求
+//     pub async fn request(&mut self,
+//                          method: String,
+//                          prefix_url: String,
+//                          request_url: String,
+//                          is_login: bool,
+//                          params: String) -> ResponseData
+//     {
+//         trace!("login_param:{:?}", self.login_param);
+//         //解析账号信息
+//         let mut access_key = "".to_string();
+//         let mut secret_key = "".to_string();
+//         let mut passphrase = "".to_string();
+//         if self.login_param.contains_key("access_key") {
+//             access_key = self.login_param.get("access_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("secret_key") {
+//             secret_key = self.login_param.get("secret_key").unwrap().to_string();
+//         }
+//         if self.login_param.contains_key("pass_key") {
+//             passphrase = self.login_param.get("pass_key").unwrap().to_string();
+//         }
+//         let mut is_login_param = true;
+//         if access_key == "" || secret_key == "" || passphrase == "" {
+//             is_login_param = false
+//         }
+//
+//
+//         //请求头配置-如果需要登陆则存在额外配置
+//         let mut body = "".to_string();
+//         let timestamp = Self::get_timestamp();
+//         let mut headers = HeaderMap::new();
+//         headers.insert("Content-Type", "application/json".parse().unwrap());
+//         if method == "POST" {
+//             body = params.clone();
+//         }
+//
+//
+//         //是否需要登陆-- 组装sing
+//         if is_login {
+//             if !is_login_param {
+//                 let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
+//                 return e;
+//             } else {
+//                 //需要登陆-且登陆参数齐全
+//                 trace!("param:{}", params);
+//                 trace!("body:{}", body);
+//                 //组装sing
+//                 let sing = Self::sign(secret_key.clone(),
+//                                       method.clone(),
+//                                       prefix_url.clone(),
+//                                       request_url.clone(),
+//                                       params.clone(),
+//                                       body.clone(),
+//                                       timestamp.clone(),
+//                 );
+//                 //组装header
+//                 headers.extend(Self::headers(sing, timestamp, passphrase, access_key));
+//             }
+//         }
+//
+//
+//         // trace!("headers:{:?}", headers);
+//         let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
+//         let start_time = chrono::Utc::now().timestamp_millis();
+//         let get_response = self.http_toll(
+//             format!("{}{}", prefix_url.clone(), request_url.clone()),
+//             method.to_string(),
+//             params.clone(),
+//             headers,
+//         ).await;
+//         let time_array = chrono::Utc::now().timestamp_millis() - start_time;
+//         self.delays.push(time_array);
+//         self.get_delay_info();
+//         let res_data = Self::res_data_analysis(get_response, base_url, params);
+//         res_data
+//     }
+//
+//     pub fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
+//         let mut headers = HeaderMap::new();
+//         headers.insert("OK-ACCESS-KEY", access_key.parse().unwrap());
+//         headers.insert("OK-ACCESS-SIGN", sign.parse().unwrap());
+//         headers.insert("OK-ACCESS-TIMESTAMP", timestamp.parse().unwrap());
+//         headers.insert("OK-ACCESS-PASSPHRASE", passphrase.parse().unwrap());
+//         headers
+//     }
+//     pub fn sign(secret_key: String,
+//                 method: String, prefix_url: String, request_url: String,
+//                 params: String, body: String, timestamp: String) -> String
+//     {
+//         /*签名生成*/
+//         let url_param_str = RestTool::parse_params_to_str(params);
+//         let base_url = if method == "GET" {
+//             format!("{}{}?{}", prefix_url, request_url, url_param_str)
+//         } else {
+//             format!("{}{}", prefix_url, request_url)
+//         };
+//
+//         // 时间戳 + 请求类型+ 请求参数字符串
+//         let message = format!("{}{}{}{}", timestamp, method, base_url, body);
+//         trace!("message:{}",message);
+//
+//         // 做签名
+//         let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
+//         let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
+//         let sign = base64::encode(result);
+//         sign
+//     }
+//
+//     async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
+//         let res_data: ResponseData;
+//         /****请求接口与 地址*/
+//         let url = format!("{}{}", self.base_url.to_string(), request_path);
+//         let request_type = request_type.clone().to_uppercase();
+//         let addrs_url: String = if RestTool::parse_params_to_str(params.clone()) == "" {
+//             url.clone()
+//         } else {
+//             format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()))
+//         };
+//         trace!("url:{}", url);
+//         trace!("addrs_url:{}", addrs_url);
+//         let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
+//         trace!("params_json:{}",params_json);
+//         trace!("headers:{:?}",headers);
+//
+//
+//         let req = match request_type.as_str() {
+//             "GET" => self.client.get(addrs_url.clone()).headers(headers),
+//             "POST" => self.client.post(url.clone()).body(params).headers(headers),
+//             "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
+//             // "PUT" => self.client.put(url.clone()).json(&params),
+//             _ => return Ok(ResponseData::error(self.label.clone(), format!("错误的请求类型:{}", request_type.clone()))), // 处理未知请求类型
+//         };
+//
+//         let response = req.send().await?;
+//         if response.status().is_success() {
+//             // 读取响应的内容
+//             let body = response.text().await?;
+//             // trace!("ok-----{}", body);
+//             res_data = ResponseData::new(self.label.clone(), "200".to_string(), "success".to_string(), body);
+//         } else {
+//             let body = response.text().await?;
+//             // trace!("error-----{}", body);
+//             res_data = ResponseData::error(self.label.clone(), body.to_string())
+//         }
+//
+//         Ok(res_data)
+//     }
+//
+//
+//     //res_data 解析
+//     pub fn res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
+//         // trace!("原始数据:{:?}",result);
+//         match result {
+//             Ok(res_data) => {
+//                 if res_data.code != "200" {
+//                     // trace!("不等于200");
+//                     let message: String = res_data.message;
+//                     let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
+//                     let code = json_value["code"].as_str().unwrap();
+//                     let msg = json_value["msg"].as_str().unwrap();
+//                     let error = ResponseData::new("".to_string(),
+//                                                   format!("{}", code),
+//                                                   format!("{}", msg),
+//                                                   format!("请求地址:{},请求参数:{}", base_url, params));
+//                     error
+//                 } else {
+//                     // trace!("等于200");
+//                     let body: String = res_data.data;
+//                     let json_value: serde_json::Value = serde_json::from_str(&body).unwrap();
+//
+//                     let code = json_value["code"].as_str().unwrap();
+//                     if code == "0" {
+//                         let data = serde_json::to_string(&json_value["data"]).unwrap();
+//                         let success = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), data.parse().unwrap());
+//                         success
+//                     } else if code == "1" || code == "0" {
+//                         let msg = json_value["msg"].as_str().unwrap();
+//                         let data = serde_json::to_string(&json_value["data"]).unwrap();
+//
+//                         let data_json: serde_json::Value = serde_json::from_str(&data).unwrap();
+//                         let code_v = data_json[0]["sCode"].as_str().unwrap();
+//                         let msg_v = data_json[0]["sMsg"].as_str().unwrap();
+//                         // trace!("发生错误:??{:?}",data_json.to_string());
+//                         let error = ResponseData::new("".to_string(),
+//                                                       format!("{}", code_v),
+//                                                       format!("{}:{}", msg, msg_v),
+//                                                       format!("请求地址:{},请求参数:{}", base_url, params));
+//                         error
+//                     } else {
+//                         let msg = json_value["msg"].as_str().unwrap();
+//                         // trace!("发生错误:??{:?}",data_json.to_string());
+//                         let error = ResponseData::new("".to_string(),
+//                                                       format!("{}", code),
+//                                                       format!("{}", msg),
+//                                                       format!("请求地址:{},请求参数:{}", base_url, params));
+//                         error
+//                     }
+//                 }
+//             }
+//             Err(err) => {
+//                 let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
+//                 error
+//             }
+//         }
+//     }
+//     fn get_timestamp() -> String {
+//         chrono::Utc::now()
+//             .format("%Y-%m-%dT%H:%M:%S%.3fZ")
+//             .to_string()
+//     }
+// }

+ 118 - 118
standard/src/binance_spot.rs

@@ -1,118 +1,118 @@
-use std::collections::BTreeMap;
-use std::io::{Error, ErrorKind};
-use std::result::Result;
-use async_trait::async_trait;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use tracing::{warn};
-use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand};
-use exchanges::binance_spot_rest::BinanceSpotRest;
-use global::trace_stack::TraceStack;
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct BinanceSpot {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: BinanceSpotRest,
-}
-
-impl BinanceSpot {
-    pub fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>) -> BinanceSpot {
-        BinanceSpot {
-            exchange: ExchangeEnum::BinanceSpot,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: BinanceSpotRest::new(is_colo, params.clone()),
-        }
-    }
-}
-
-
-#[async_trait]
-impl Platform for BinanceSpot {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    // 获取交易所模式
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::BinanceSpot
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取登录params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-
-    fn get_self_market(&self) -> Market {
-        warn!("binance_spot:该交易所方法未实现");
-        return Market::new();
-    }
-
-    fn get_request_delays(&self) -> Vec<i64> {
-        warn!("binance_spot:该交易所方法未实现");
-        return vec![];
-    }
-
-    fn get_request_avg_delay(&self) -> Decimal {
-        warn!("binance_spot:该交易所方法未实现");
-        return dec!(0);
-    }
-
-    fn get_request_max_delay(&self) -> i64 {
-        warn!("binance_spot:该交易所方法未实现");
-        return 0;
-    }
-
-    async fn get_server_time(&mut self) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    // 获取账号信息
-    async fn get_account(&mut self) -> Result<Account, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    // 获取仓位信息
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    // 获取市场行情
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_ticker_symbol(&mut self, _symbol: String) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_market(&mut self) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_market_symbol(&mut self, _symbol: String) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_order_detail(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-
-    async fn command_order(&mut self, _order_command: OrderCommand, _trace_stack: TraceStack) { warn!("binance_spot:该交易所方法未实现"); }
-}
+// use std::collections::BTreeMap;
+// use std::io::{Error, ErrorKind};
+// use std::result::Result;
+// use async_trait::async_trait;
+// use rust_decimal::Decimal;
+// use rust_decimal_macros::dec;
+// use tracing::{warn};
+// use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand};
+// use exchanges::binance_spot_rest::BinanceSpotRest;
+// use global::trace_stack::TraceStack;
+//
+// #[allow(dead_code)]
+// #[derive(Clone)]
+// pub struct BinanceSpot {
+//     exchange: ExchangeEnum,
+//     symbol: String,
+//     is_colo: bool,
+//     params: BTreeMap<String, String>,
+//     request: BinanceSpotRest,
+// }
+//
+// impl BinanceSpot {
+//     pub fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>) -> BinanceSpot {
+//         BinanceSpot {
+//             exchange: ExchangeEnum::BinanceSpot,
+//             symbol: symbol.to_uppercase(),
+//             is_colo,
+//             params: params.clone(),
+//             request: BinanceSpotRest::new(is_colo, params.clone()),
+//         }
+//     }
+// }
+//
+//
+// #[async_trait]
+// impl Platform for BinanceSpot {
+//     // 克隆方法
+//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
+//     // 获取交易所模式
+//     fn get_self_exchange(&self) -> ExchangeEnum {
+//         ExchangeEnum::BinanceSpot
+//     }
+//     // 获取交易对
+//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
+//     // 获取是否使用高速通道
+//     fn get_self_is_colo(&self) -> bool {
+//         self.is_colo
+//     }
+//     // 获取登录params信息
+//     fn get_self_params(&self) -> BTreeMap<String, String> {
+//         self.params.clone()
+//     }
+//
+//     fn get_self_market(&self) -> Market {
+//         warn!("binance_spot:该交易所方法未实现");
+//         return Market::new();
+//     }
+//
+//     fn get_request_delays(&self) -> Vec<i64> {
+//         warn!("binance_spot:该交易所方法未实现");
+//         return vec![];
+//     }
+//
+//     fn get_request_avg_delay(&self) -> Decimal {
+//         warn!("binance_spot:该交易所方法未实现");
+//         return dec!(0);
+//     }
+//
+//     fn get_request_max_delay(&self) -> i64 {
+//         warn!("binance_spot:该交易所方法未实现");
+//         return 0;
+//     }
+//
+//     async fn get_server_time(&mut self) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     // 获取账号信息
+//     async fn get_account(&mut self) -> Result<Account, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     // 获取仓位信息
+//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     // 获取市场行情
+//     async fn get_ticker(&mut self) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_ticker_symbol(&mut self, _symbol: String) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_market(&mut self) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_market_symbol(&mut self, _symbol: String) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_order_detail(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn command_order(&mut self, _order_command: OrderCommand, _trace_stack: TraceStack) { warn!("binance_spot:该交易所方法未实现"); }
+// }

+ 51 - 51
standard/src/binance_spot_handle.rs

@@ -1,51 +1,51 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use exchanges::response_base::ResponseData;
-use crate::{MarketOrder, SpecialDepth, SpecialTicker};
-use crate::exchange::ExchangeEnum;
-use crate::handle_info::HandleSwapInfo;
-
-
-// 处理特殊Ticker信息
-pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-    format_special_ticker(res_data_json, res_data.label)
-}
-
-pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let bp = Decimal::from_str(data["b"].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_str(data["B"].as_str().unwrap()).unwrap();
-    let ap = Decimal::from_str(data["a"].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_str(data["A"].as_str().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_str(&data["u"].to_string()).unwrap();
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at: Default::default() };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: label,
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at: Default::default(),
-    }
-}
-
-// 处理特殊深度数据
-pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-    HandleSwapInfo::handle_special_depth(ExchangeEnum::BinanceSpot, res_data)
-}
-
-// 格式化深度信息
-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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
+// use std::str::FromStr;
+// use rust_decimal::Decimal;
+// use rust_decimal_macros::dec;
+// use exchanges::response_base::ResponseData;
+// use crate::{MarketOrder, SpecialDepth, SpecialTicker};
+// use crate::exchange::ExchangeEnum;
+// use crate::handle_info::HandleSwapInfo;
+//
+//
+// // 处理特殊Ticker信息
+// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
+//     let res_data_str = res_data.data;
+//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+//     format_special_ticker(res_data_json, res_data.label)
+// }
+//
+// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
+//     let bp = Decimal::from_str(data["b"].as_str().unwrap()).unwrap();
+//     let bq = Decimal::from_str(data["B"].as_str().unwrap()).unwrap();
+//     let ap = Decimal::from_str(data["a"].as_str().unwrap()).unwrap();
+//     let aq = Decimal::from_str(data["A"].as_str().unwrap()).unwrap();
+//     let mp = (bp + ap) * dec!(0.5);
+//     let t = Decimal::from_str(&data["u"].to_string()).unwrap();
+//
+//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at: Default::default() };
+//     let depth_info = vec![bp, bq, ap, aq];
+//     SpecialDepth {
+//         name: label,
+//         depth: depth_info,
+//         ticker: ticker_info,
+//         t,
+//         create_at: Default::default(),
+//     }
+// }
+//
+// // 处理特殊深度数据
+// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
+//     HandleSwapInfo::handle_special_depth(ExchangeEnum::BinanceSpot, res_data)
+// }
+//
+// // 格式化深度信息
+// 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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
+//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
+//         })
+//     }
+//     return depth_items;
+// }

+ 18 - 28
standard/src/binance_swap.rs

@@ -75,8 +75,7 @@ impl Platform for BinanceSwap {
     async fn get_server_time(&mut self) -> Result<String, Error> {
         let res_data = self.request.get_server_time().await;
         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 res_data_json = res_data.data;
             let result = res_data_json["serverTime"].to_string();
             Ok(result)
         } else {
@@ -88,8 +87,7 @@ impl Platform for BinanceSwap {
         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
         let res_data = self.request.get_account().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 res_data_json = res_data.data.as_array().unwrap();
             let balance_info = res_data_json.iter().find(|item| item["asset"].as_str().unwrap().to_string() == symbol_array[1].to_string());
             match balance_info {
                 None => {
@@ -127,8 +125,7 @@ impl Platform for BinanceSwap {
         let ct_val = self.market.ct_val;
         let res_data = self.request.get_position_risk(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 res_data_json = res_data.data.as_array().unwrap();
             let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
             Ok(result)
         } else {
@@ -139,8 +136,7 @@ impl Platform for BinanceSwap {
     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
         let res_data = self.request.get_position_risk("".to_string()).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 res_data_json = res_data.data.as_array().unwrap();
             let result = res_data_json.iter().map(|item| { format_position_item(item, Decimal::ONE) }).collect();
             Ok(result)
         } else {
@@ -153,8 +149,7 @@ impl Platform for BinanceSwap {
         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
         let res_data = self.request.get_book_ticker(symbol_format).await;
         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 res_data_json: serde_json::Value = res_data.data;
             let result = Ticker {
                 time: res_data_json["time"].as_i64().unwrap(),
                 high: Decimal::from_str(res_data_json["askPrice"].as_str().unwrap()).unwrap(),
@@ -174,8 +169,7 @@ impl Platform for BinanceSwap {
         let symbol_format = utils::format_symbol(symbol.clone(), "");
         let res_data = self.request.get_book_ticker(symbol_format).await;
         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 res_data_json: serde_json::Value = res_data.data;
             let result = Ticker {
                 time: res_data_json["time"].as_i64().unwrap(),
                 high: Decimal::from_str(res_data_json["askPrice"].as_str().unwrap()).unwrap(),
@@ -195,14 +189,13 @@ impl Platform for BinanceSwap {
         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
         let res_data = self.request.get_exchange_info().await;
         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 symbols: Vec<serde_json::Value> = res_data_json["symbols"].as_array().unwrap().clone();
+            let res_data_json = res_data.data;
+            let symbols = res_data_json["symbols"].as_array().unwrap();
             let market_info = symbols.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format);
             match market_info {
                 None => {
-                    error!("binance_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
+                    error!("binance_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_json);
+                    Err(Error::new(ErrorKind::Other, res_data_json.to_string()))
                 }
                 Some(value) => {
                     let base_asset = value["baseAsset"].as_str().unwrap_or("").to_string();
@@ -238,14 +231,13 @@ impl Platform for BinanceSwap {
         let symbol_format = utils::format_symbol(symbol.clone(), "");
         let res_data = self.request.get_exchange_info().await;
         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 symbols: Vec<serde_json::Value> = res_data_json["symbols"].as_array().unwrap().clone();
+            let res_data_json: serde_json::Value = res_data.data;
+            let symbols = res_data_json["symbols"].as_array().unwrap();
             let market_info = symbols.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format);
             match market_info {
                 None => {
-                    error!("binance_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
+                    error!("binance_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_json);
+                    Err(Error::new(ErrorKind::Other, res_data_json.to_string()))
                 }
                 Some(value) => {
                     let base_asset = value["baseAsset"].as_str().unwrap_or("").to_string();
@@ -281,13 +273,12 @@ impl Platform for BinanceSwap {
         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
         let res_data = self.request.get_order(symbol_format, order_id.parse().unwrap_or(-1), custom_id.to_string()).await;
         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 res_data_json: serde_json::Value = res_data.data;
 
             let status = res_data_json["status"].as_str().unwrap();
             let custom_status = if ["CANCELED", "EXPIRED", "FILLED"].contains(&status) { "REMOVE".to_string() } else if status == "NEW" { "NEW".to_string() } else {
-                error!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data);
-                panic!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data)
+                error!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data_json);
+                panic!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data_json)
             };
             let result = Order {
                 id: res_data_json["orderId"].to_string(),
@@ -310,8 +301,7 @@ impl Platform for BinanceSwap {
         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 res_data_json = res_data.data.as_array().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();

+ 1 - 2
standard/src/binance_swap_handle.rs

@@ -9,8 +9,7 @@ use crate::handle_info::HandleSwapInfo;
 
 // 处理特殊Ticker信息
 pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+    let res_data_json = res_data.data;
     format_special_ticker(res_data_json, res_data.label)
 }
 

+ 625 - 625
standard/src/bitget_spot.rs

@@ -1,625 +1,625 @@
-use std::collections::{BTreeMap, HashMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::ToPrimitive;
-use rust_decimal_macros::dec;
-use serde_json::json;
-use tokio::time::Instant;
-use tracing::{error};
-use exchanges::bitget_spot_rest::BitgetSpotRest;
-use global::trace_stack::TraceStack;
-use crate::exchange::ExchangeEnum;
-use crate::{Account, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct BitgetSpot {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: BitgetSpotRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl BitgetSpot {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BitgetSpot {
-        let market = Market::new();
-        let mut bitget_spot = BitgetSpot {
-            exchange: ExchangeEnum::BitgetSpot,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: BitgetSpotRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        bitget_spot.market = BitgetSpot::get_market(&mut bitget_spot).await.unwrap_or(bitget_spot.market);
-        return bitget_spot;
-    }
-}
-
-#[async_trait]
-impl Platform for BitgetSpot {
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-
-    fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::BitgetSpot }
-
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-
-    fn get_self_is_colo(&self) -> bool { self.is_colo }
-
-    fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
-
-    fn get_self_market(&self) -> Market { self.market.clone() }
-
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        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 = res_data_json["serverTime"].as_str().unwrap().to_string();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        let res_data = self.request.get_account_assets().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 result = res_data_json.iter().map(|item| format_account_info(item.clone())).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let res_data = self.request.get_tickers(symbol_format).await;
-        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 ticker_info = res_data_json[0].clone();
-            let time = (Decimal::from_str(&*ticker_info["ts"].as_str().unwrap()).unwrap() / dec!(1000)).floor().to_i64().unwrap();
-            let result = Ticker {
-                time,
-                high: Decimal::from_str(ticker_info["high24h"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(ticker_info["low24h"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(ticker_info["askPr"].as_str().unwrap()).unwrap(),
-                buy: Decimal::from_str(ticker_info["bidPr"].as_str().unwrap()).unwrap(),
-                last: Decimal::from_str(ticker_info["lastPr"].as_str().unwrap()).unwrap(),
-                volume: Decimal::from_str(ticker_info["quoteVolume"].as_str().unwrap()).unwrap(),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let res_data = self.request.get_tickers(symbol_format).await;
-        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 ticker_info = res_data_json[0].clone();
-            let time = (Decimal::from_str(&*ticker_info["ts"].as_str().unwrap()).unwrap() / dec!(1000)).floor().to_i64().unwrap();
-            let result = Ticker {
-                time,
-                high: Decimal::from_str(ticker_info["high24h"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(ticker_info["low24h"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(ticker_info["askPr"].as_str().unwrap()).unwrap(),
-                buy: Decimal::from_str(ticker_info["bidPr"].as_str().unwrap()).unwrap(),
-                last: Decimal::from_str(ticker_info["lastPr"].as_str().unwrap()).unwrap(),
-                volume: Decimal::from_str(ticker_info["quoteVolume"].as_str().unwrap()).unwrap(),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let res_data = self.request.get_symbols(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 market_info = res_data_json.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format.clone());
-            match market_info {
-                None => {
-                    error!("bitget_spot:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseCoin"].as_str().unwrap().to_string();
-                    let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
-                    let price_precision = Decimal::from_str(value["pricePrecision"].as_str().unwrap()).unwrap();
-                    let amount_precision = Decimal::from_str(value["quantityPrecision"].as_str().unwrap()).unwrap();
-                    let min_qty = Decimal::from_str(&value["minTradeAmount"].as_str().unwrap()).unwrap();
-                    let max_qty = Decimal::from_str(&value["maxTradeAmount"].as_str().unwrap()).unwrap();
-
-                    let tick_size = if price_precision > dec!(0) {
-                        Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(price_precision - dec!(1)).unwrap()))).unwrap()
-                    } else {
-                        Decimal::ONE
-                    };
-                    let amount_size = if amount_precision > dec!(0) {
-                        Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(amount_precision - dec!(1)).unwrap()))).unwrap()
-                    } else {
-                        Decimal::ONE
-                    };
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset, quote_asset),
-                        base_asset,
-                        quote_asset,
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional: min_qty,
-                        max_notional: max_qty,
-                        ct_val: Decimal::ONE,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let res_data = self.request.get_symbols(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 market_info = res_data_json.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format.clone());
-            match market_info {
-                None => {
-                    error!("bitget_spot:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseCoin"].as_str().unwrap().to_string();
-                    let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
-                    let price_precision = Decimal::from_str(value["pricePrecision"].as_str().unwrap()).unwrap();
-                    let amount_precision = Decimal::from_str(value["quantityPrecision"].as_str().unwrap()).unwrap();
-                    let min_qty = Decimal::from_str(&value["minTradeAmount"].as_str().unwrap()).unwrap();
-                    let max_qty = Decimal::from_str(&value["maxTradeAmount"].as_str().unwrap()).unwrap();
-
-                    let tick_size = if price_precision > dec!(0) {
-                        Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(price_precision - dec!(1)).unwrap()))).unwrap()
-                    } else {
-                        Decimal::ONE
-                    };
-                    let amount_size = if amount_precision > dec!(0) {
-                        Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(amount_precision - dec!(1)).unwrap()))).unwrap()
-                    } else {
-                        Decimal::ONE
-                    };
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset, quote_asset),
-                        base_asset,
-                        quote_asset,
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional: min_qty,
-                        max_notional: max_qty,
-                        ct_val: Decimal::ONE,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_order(order_id.to_string(), custom_id.to_string()).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();
-            if res_data_json.len() == 0 {
-                Err(Error::new(ErrorKind::Other, res_data.to_string()))
-            } else {
-                let order_info = res_data_json[0].clone();
-                let result = format_order_item(order_info, ct_val);
-                Ok(result)
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_unfilled_orders(symbol_format.to_string(), "".to_string(), "".to_string(), "".to_string(), "100".to_string(), "".to_string()).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 result = res_data_json.iter().map(|item| format_order_item(item.clone(), ct_val)).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let mut params = json!({
-            "symbol": symbol_format.to_string(),
-            "clientOid": custom_id,
-            "price": price.to_string(),
-        });
-        if price.eq(&Decimal::ZERO) {
-            params["orderType"] = json!("market");
-            params["force"] = json!("post_only");
-        } else {
-            params["orderType"] = json!("limit");
-            params["force"] = json!("gtc");
-        };
-        params["size"] = json!(amount);
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.spot_order(params).await;
-        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 = Order {
-                id: res_data_json["orderId"].as_str().unwrap().to_string(),
-                custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("328 bitget_spot".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let mut params = json!({
-            "symbol": symbol_format.to_string(),
-            "clientOid": custom_id,
-            "price": price.to_string(),
-        });
-        if price.eq(&Decimal::ZERO) {
-            params["orderType"] = json!("market");
-            params["force"] = json!("post_only");
-        } else {
-            params["orderType"] = json!("limit");
-            params["force"] = json!("gtc");
-        };
-        let size = (amount / ct_val).floor();
-        params["size"] = json!(size);
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.spot_order(params).await;
-        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 = Order {
-                id: res_data_json["orderId"].as_str().unwrap().to_string(),
-                custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("380 bitget_spot".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let res_data = self.request.spot_cancel_order(symbol_format.clone(), order_id.to_string(), custom_id.to_string()).await;
-        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 = Order {
-                id: res_data_json["orderId"].as_str().unwrap().to_string(),
-                custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "REMOVE".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("403 bitget_spot".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let orders_res_data = self.request.get_unfilled_orders(symbol_format.to_string(), "".to_string(), "".to_string(), "".to_string(), "100".to_string(), "".to_string()).await;
-        if orders_res_data.code == "200" {
-            let mut result = vec![];
-            let orders_res_data_str = &orders_res_data.data;
-            let orders_res_data_json: Vec<serde_json::Value> = serde_json::from_str(orders_res_data_str).unwrap();
-            for order in orders_res_data_json {
-                let order_id = order["orderId"].as_str().unwrap().to_string();
-                let cancel_res_data = self.request.spot_cancel_order(symbol_format.clone(), order_id, "".to_string()).await;
-                if cancel_res_data.code == "200" {
-                    let cancel_res_data_str = &cancel_res_data.data;
-                    let cancel_res_data_json: serde_json::Value = serde_json::from_str(cancel_res_data_str).unwrap();
-                    result.push(Order {
-                        id: cancel_res_data_json["orderId"].as_str().unwrap().to_string(),
-                        custom_id: cancel_res_data_json["clientOid"].as_str().unwrap().to_string(),
-                        price: Decimal::ZERO,
-                        amount: Decimal::ZERO,
-                        deal_amount: Decimal::ZERO,
-                        avg_price: Decimal::ZERO,
-                        status: "REMOVE".to_string(),
-                        order_type: "".to_string(),
-                        trace_stack: TraceStack::new(0, Instant::now()).on_special("434 bitget_spot".to_string()),
-                    });
-                } else {
-                    return Err(Error::new(ErrorKind::Other, cancel_res_data.to_string()));
-                }
-            }
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, orders_res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn wallet_transfers(&mut self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error> {
-        let coin_format = coin.to_string().to_uppercase();
-        let res_data = self.request.wallet_transfer(from.to_string(), to.to_string(), amount.to_string(), coin_format.clone(), "".to_string(), "".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.to_string()))
-        }
-    }
-
-    async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-        let mut handles = vec![];
-        // 撤销订单
-        let cancel = order_command.cancel;
-        for item in cancel.keys() {
-            let mut self_clone = self.clone();
-            let cancel_clone = cancel.clone();
-            let item_clone = item.clone();
-            let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                match result {
-                    Ok(_) => {
-                        // result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        // 取消失败去查订单。
-                        let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                        match query_rst {
-                            Ok(order) => {
-                                result_sd.send(order).await.unwrap();
-                            }
-                            Err(_query_err) => {
-                                // error!(?_query_err);
-                                // error!("撤单失败,而且查单也失败了,bitget_spot,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                            }
-                        }
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 下单指令
-        let mut limits = HashMap::new();
-        limits.extend(order_command.limits_open);
-        limits.extend(order_command.limits_close);
-        for item in limits.keys() {
-            let mut self_clone = self.clone();
-            let limits_clone = limits.clone();
-            let item_clone = item.clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let ts = trace_stack.clone();
-
-            let handle = tokio::spawn(async move {
-                let value = limits_clone[&item_clone].clone();
-                let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-                let side = value.get(1).unwrap();
-                let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-                let cid = value.get(3).unwrap();
-
-                //  order_name: [数量,方向,价格,c_id]
-                let result = self_clone.take_order(cid, side, price, amount).await;
-                match result {
-                    Ok(mut result) => {
-                        // 记录此订单完成时间
-                        // ts.on_after_send();
-                        result.trace_stack = ts;
-
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        result_sd.send(err_order).await.unwrap();
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 检查订单指令
-        let check = order_command.check;
-        for item in check.keys() {
-            let mut self_clone = self.clone();
-            let check_clone = check.clone();
-            let item_clone = item.clone();
-            let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_account_info(balance_data: serde_json::Value) -> Account {
-    let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
-    let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-    let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
-    let balance = available_balance + frozen_balance;
-
-    Account {
-        coin: balance_coin,
-        balance,
-        available_balance,
-        frozen_balance,
-        stocks: Decimal::ZERO,
-        available_stocks: Decimal::ZERO,
-        frozen_stocks: Decimal::ZERO,
-    }
-}
-
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
-    let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
-    let status = order["status"].as_str().unwrap_or("");
-    let base_volume = Decimal::from_str(order["baseVolume"].as_str().unwrap()).unwrap();
-
-    let avg_price = Decimal::from_str(order["priceAvg"].as_str().unwrap()).unwrap();
-
-    let amount = size * ct_val;
-    let deal_amount = base_volume * ct_val;
-    let custom_status = if ["filled", "cancelled"].contains(&status) {
-        "REMOVE".to_string()
-    } else if ["init", "live", "new", "partially_filled"].contains(&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id: order["orderId"].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["orderType"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("622 bitget_spot".to_string()),
-    }
-}
+// use std::collections::{BTreeMap, HashMap};
+// use std::io::{Error, ErrorKind};
+// use std::str::FromStr;
+// use tokio::sync::mpsc::Sender;
+// use async_trait::async_trait;
+// use futures::stream::FuturesUnordered;
+// use futures::TryStreamExt;
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::ToPrimitive;
+// use rust_decimal_macros::dec;
+// use serde_json::json;
+// use tokio::time::Instant;
+// use tracing::{error};
+// use exchanges::bitget_spot_rest::BitgetSpotRest;
+// use global::trace_stack::TraceStack;
+// use crate::exchange::ExchangeEnum;
+// use crate::{Account, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
+//
+// #[allow(dead_code)]
+// #[derive(Clone)]
+// pub struct BitgetSpot {
+//     exchange: ExchangeEnum,
+//     symbol: String,
+//     is_colo: bool,
+//     params: BTreeMap<String, String>,
+//     request: BitgetSpotRest,
+//     market: Market,
+//     order_sender: Sender<Order>,
+//     error_sender: Sender<Error>,
+// }
+//
+// impl BitgetSpot {
+//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BitgetSpot {
+//         let market = Market::new();
+//         let mut bitget_spot = BitgetSpot {
+//             exchange: ExchangeEnum::BitgetSpot,
+//             symbol: symbol.to_uppercase(),
+//             is_colo,
+//             params: params.clone(),
+//             request: BitgetSpotRest::new(is_colo, params.clone()),
+//             market,
+//             order_sender,
+//             error_sender,
+//         };
+//         bitget_spot.market = BitgetSpot::get_market(&mut bitget_spot).await.unwrap_or(bitget_spot.market);
+//         return bitget_spot;
+//     }
+// }
+//
+// #[async_trait]
+// impl Platform for BitgetSpot {
+//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
+//
+//     fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::BitgetSpot }
+//
+//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
+//
+//     fn get_self_is_colo(&self) -> bool { self.is_colo }
+//
+//     fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
+//
+//     fn get_self_market(&self) -> Market { self.market.clone() }
+//
+//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
+//
+//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
+//
+//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
+//
+//     async fn get_server_time(&mut self) -> Result<String, Error> {
+//         let res_data = self.request.get_server_time().await;
+//         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 = res_data_json["serverTime"].as_str().unwrap().to_string();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_account(&mut self) -> Result<Account, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
+//         let res_data = self.request.get_account_assets().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 result = res_data_json.iter().map(|item| format_account_info(item.clone())).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
+//         let res_data = self.request.get_tickers(symbol_format).await;
+//         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 ticker_info = res_data_json[0].clone();
+//             let time = (Decimal::from_str(&*ticker_info["ts"].as_str().unwrap()).unwrap() / dec!(1000)).floor().to_i64().unwrap();
+//             let result = Ticker {
+//                 time,
+//                 high: Decimal::from_str(ticker_info["high24h"].as_str().unwrap()).unwrap(),
+//                 low: Decimal::from_str(ticker_info["low24h"].as_str().unwrap()).unwrap(),
+//                 sell: Decimal::from_str(ticker_info["askPr"].as_str().unwrap()).unwrap(),
+//                 buy: Decimal::from_str(ticker_info["bidPr"].as_str().unwrap()).unwrap(),
+//                 last: Decimal::from_str(ticker_info["lastPr"].as_str().unwrap()).unwrap(),
+//                 volume: Decimal::from_str(ticker_info["quoteVolume"].as_str().unwrap()).unwrap(),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
+//         let symbol_format = utils::format_symbol(symbol.clone(), "");
+//         let res_data = self.request.get_tickers(symbol_format).await;
+//         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 ticker_info = res_data_json[0].clone();
+//             let time = (Decimal::from_str(&*ticker_info["ts"].as_str().unwrap()).unwrap() / dec!(1000)).floor().to_i64().unwrap();
+//             let result = Ticker {
+//                 time,
+//                 high: Decimal::from_str(ticker_info["high24h"].as_str().unwrap()).unwrap(),
+//                 low: Decimal::from_str(ticker_info["low24h"].as_str().unwrap()).unwrap(),
+//                 sell: Decimal::from_str(ticker_info["askPr"].as_str().unwrap()).unwrap(),
+//                 buy: Decimal::from_str(ticker_info["bidPr"].as_str().unwrap()).unwrap(),
+//                 last: Decimal::from_str(ticker_info["lastPr"].as_str().unwrap()).unwrap(),
+//                 volume: Decimal::from_str(ticker_info["quoteVolume"].as_str().unwrap()).unwrap(),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market(&mut self) -> Result<Market, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
+//         let res_data = self.request.get_symbols(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 market_info = res_data_json.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format.clone());
+//             match market_info {
+//                 None => {
+//                     error!("bitget_spot:获取Market信息错误!\nget_market:res_data={:?}", res_data);
+//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//                 }
+//                 Some(value) => {
+//                     let base_asset = value["baseCoin"].as_str().unwrap().to_string();
+//                     let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
+//                     let price_precision = Decimal::from_str(value["pricePrecision"].as_str().unwrap()).unwrap();
+//                     let amount_precision = Decimal::from_str(value["quantityPrecision"].as_str().unwrap()).unwrap();
+//                     let min_qty = Decimal::from_str(&value["minTradeAmount"].as_str().unwrap()).unwrap();
+//                     let max_qty = Decimal::from_str(&value["maxTradeAmount"].as_str().unwrap()).unwrap();
+//
+//                     let tick_size = if price_precision > dec!(0) {
+//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(price_precision - dec!(1)).unwrap()))).unwrap()
+//                     } else {
+//                         Decimal::ONE
+//                     };
+//                     let amount_size = if amount_precision > dec!(0) {
+//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(amount_precision - dec!(1)).unwrap()))).unwrap()
+//                     } else {
+//                         Decimal::ONE
+//                     };
+//
+//                     let result = Market {
+//                         symbol: format!("{}_{}", base_asset, quote_asset),
+//                         base_asset,
+//                         quote_asset,
+//                         tick_size,
+//                         amount_size,
+//                         price_precision,
+//                         amount_precision,
+//                         min_qty,
+//                         max_qty,
+//                         min_notional: min_qty,
+//                         max_notional: max_qty,
+//                         ct_val: Decimal::ONE,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
+//         let symbol_format = utils::format_symbol(symbol.clone(), "");
+//         let res_data = self.request.get_symbols(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 market_info = res_data_json.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format.clone());
+//             match market_info {
+//                 None => {
+//                     error!("bitget_spot:获取Market信息错误!\nget_market:res_data={:?}", res_data);
+//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//                 }
+//                 Some(value) => {
+//                     let base_asset = value["baseCoin"].as_str().unwrap().to_string();
+//                     let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
+//                     let price_precision = Decimal::from_str(value["pricePrecision"].as_str().unwrap()).unwrap();
+//                     let amount_precision = Decimal::from_str(value["quantityPrecision"].as_str().unwrap()).unwrap();
+//                     let min_qty = Decimal::from_str(&value["minTradeAmount"].as_str().unwrap()).unwrap();
+//                     let max_qty = Decimal::from_str(&value["maxTradeAmount"].as_str().unwrap()).unwrap();
+//
+//                     let tick_size = if price_precision > dec!(0) {
+//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(price_precision - dec!(1)).unwrap()))).unwrap()
+//                     } else {
+//                         Decimal::ONE
+//                     };
+//                     let amount_size = if amount_precision > dec!(0) {
+//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(amount_precision - dec!(1)).unwrap()))).unwrap()
+//                     } else {
+//                         Decimal::ONE
+//                     };
+//
+//                     let result = Market {
+//                         symbol: format!("{}_{}", base_asset, quote_asset),
+//                         base_asset,
+//                         quote_asset,
+//                         tick_size,
+//                         amount_size,
+//                         price_precision,
+//                         amount_precision,
+//                         min_qty,
+//                         max_qty,
+//                         min_notional: min_qty,
+//                         max_notional: max_qty,
+//                         ct_val: Decimal::ONE,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_order(order_id.to_string(), custom_id.to_string()).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();
+//             if res_data_json.len() == 0 {
+//                 Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//             } else {
+//                 let order_info = res_data_json[0].clone();
+//                 let result = format_order_item(order_info, ct_val);
+//                 Ok(result)
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_unfilled_orders(symbol_format.to_string(), "".to_string(), "".to_string(), "".to_string(), "100".to_string(), "".to_string()).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 result = res_data_json.iter().map(|item| format_order_item(item.clone(), ct_val)).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
+//         let mut params = json!({
+//             "symbol": symbol_format.to_string(),
+//             "clientOid": custom_id,
+//             "price": price.to_string(),
+//         });
+//         if price.eq(&Decimal::ZERO) {
+//             params["orderType"] = json!("market");
+//             params["force"] = json!("post_only");
+//         } else {
+//             params["orderType"] = json!("limit");
+//             params["force"] = json!("gtc");
+//         };
+//         params["size"] = json!(amount);
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.spot_order(params).await;
+//         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 = Order {
+//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
+//                 custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("328 bitget_spot".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_format = utils::format_symbol(symbol.clone(), "");
+//         let mut params = json!({
+//             "symbol": symbol_format.to_string(),
+//             "clientOid": custom_id,
+//             "price": price.to_string(),
+//         });
+//         if price.eq(&Decimal::ZERO) {
+//             params["orderType"] = json!("market");
+//             params["force"] = json!("post_only");
+//         } else {
+//             params["orderType"] = json!("limit");
+//             params["force"] = json!("gtc");
+//         };
+//         let size = (amount / ct_val).floor();
+//         params["size"] = json!(size);
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.spot_order(params).await;
+//         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 = Order {
+//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
+//                 custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("380 bitget_spot".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
+//         let res_data = self.request.spot_cancel_order(symbol_format.clone(), order_id.to_string(), custom_id.to_string()).await;
+//         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 = Order {
+//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
+//                 custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "REMOVE".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("403 bitget_spot".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
+//         let orders_res_data = self.request.get_unfilled_orders(symbol_format.to_string(), "".to_string(), "".to_string(), "".to_string(), "100".to_string(), "".to_string()).await;
+//         if orders_res_data.code == "200" {
+//             let mut result = vec![];
+//             let orders_res_data_str = &orders_res_data.data;
+//             let orders_res_data_json: Vec<serde_json::Value> = serde_json::from_str(orders_res_data_str).unwrap();
+//             for order in orders_res_data_json {
+//                 let order_id = order["orderId"].as_str().unwrap().to_string();
+//                 let cancel_res_data = self.request.spot_cancel_order(symbol_format.clone(), order_id, "".to_string()).await;
+//                 if cancel_res_data.code == "200" {
+//                     let cancel_res_data_str = &cancel_res_data.data;
+//                     let cancel_res_data_json: serde_json::Value = serde_json::from_str(cancel_res_data_str).unwrap();
+//                     result.push(Order {
+//                         id: cancel_res_data_json["orderId"].as_str().unwrap().to_string(),
+//                         custom_id: cancel_res_data_json["clientOid"].as_str().unwrap().to_string(),
+//                         price: Decimal::ZERO,
+//                         amount: Decimal::ZERO,
+//                         deal_amount: Decimal::ZERO,
+//                         avg_price: Decimal::ZERO,
+//                         status: "REMOVE".to_string(),
+//                         order_type: "".to_string(),
+//                         trace_stack: TraceStack::new(0, Instant::now()).on_special("434 bitget_spot".to_string()),
+//                     });
+//                 } else {
+//                     return Err(Error::new(ErrorKind::Other, cancel_res_data.to_string()));
+//                 }
+//             }
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, orders_res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn wallet_transfers(&mut self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error> {
+//         let coin_format = coin.to_string().to_uppercase();
+//         let res_data = self.request.wallet_transfer(from.to_string(), to.to_string(), amount.to_string(), coin_format.clone(), "".to_string(), "".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.to_string()))
+//         }
+//     }
+//
+//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
+//         let mut handles = vec![];
+//         // 撤销订单
+//         let cancel = order_command.cancel;
+//         for item in cancel.keys() {
+//             let mut self_clone = self.clone();
+//             let cancel_clone = cancel.clone();
+//             let item_clone = item.clone();
+//             let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.cancel_order(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(_) => {
+//                         // result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         // 取消失败去查订单。
+//                         let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                         match query_rst {
+//                             Ok(order) => {
+//                                 result_sd.send(order).await.unwrap();
+//                             }
+//                             Err(_query_err) => {
+//                                 // error!(?_query_err);
+//                                 // error!("撤单失败,而且查单也失败了,bitget_spot,oid={}, cid={}。", order_id.clone(), custom_id.clone());
+//                             }
+//                         }
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 下单指令
+//         let mut limits = HashMap::new();
+//         limits.extend(order_command.limits_open);
+//         limits.extend(order_command.limits_close);
+//         for item in limits.keys() {
+//             let mut self_clone = self.clone();
+//             let limits_clone = limits.clone();
+//             let item_clone = item.clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let ts = trace_stack.clone();
+//
+//             let handle = tokio::spawn(async move {
+//                 let value = limits_clone[&item_clone].clone();
+//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
+//                 let side = value.get(1).unwrap();
+//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
+//                 let cid = value.get(3).unwrap();
+//
+//                 //  order_name: [数量,方向,价格,c_id]
+//                 let result = self_clone.take_order(cid, side, price, amount).await;
+//                 match result {
+//                     Ok(mut result) => {
+//                         // 记录此订单完成时间
+//                         // ts.on_after_send();
+//                         result.trace_stack = ts;
+//
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         let mut err_order = Order::new();
+//                         err_order.custom_id = cid.clone();
+//                         err_order.status = "REMOVE".to_string();
+//
+//                         result_sd.send(err_order).await.unwrap();
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 检查订单指令
+//         let check = order_command.check;
+//         for item in check.keys() {
+//             let mut self_clone = self.clone();
+//             let check_clone = check.clone();
+//             let item_clone = item.clone();
+//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(result) => {
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//
+//         let futures = FuturesUnordered::from_iter(handles);
+//         let _: Result<Vec<_>, _> = futures.try_collect().await;
+//     }
+// }
+//
+// pub fn format_account_info(balance_data: serde_json::Value) -> Account {
+//     let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
+//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
+//     let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
+//     let balance = available_balance + frozen_balance;
+//
+//     Account {
+//         coin: balance_coin,
+//         balance,
+//         available_balance,
+//         frozen_balance,
+//         stocks: Decimal::ZERO,
+//         available_stocks: Decimal::ZERO,
+//         frozen_stocks: Decimal::ZERO,
+//     }
+// }
+//
+// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
+//     let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
+//     let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
+//     let status = order["status"].as_str().unwrap_or("");
+//     let base_volume = Decimal::from_str(order["baseVolume"].as_str().unwrap()).unwrap();
+//
+//     let avg_price = Decimal::from_str(order["priceAvg"].as_str().unwrap()).unwrap();
+//
+//     let amount = size * ct_val;
+//     let deal_amount = base_volume * ct_val;
+//     let custom_status = if ["filled", "cancelled"].contains(&status) {
+//         "REMOVE".to_string()
+//     } else if ["init", "live", "new", "partially_filled"].contains(&status) {
+//         "NEW".to_string()
+//     } else {
+//         "NULL".to_string()
+//     };
+//     Order {
+//         id: order["orderId"].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["orderType"].as_str().unwrap().to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("622 bitget_spot".to_string()),
+//     }
+// }

+ 136 - 136
standard/src/bitget_spot_handle.rs

@@ -1,136 +1,136 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use serde_json::json;
-use tokio::time::Instant;
-use tracing::trace;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, SpecialDepth, SpecialOrder, SpecialTicker};
-use crate::exchange::ExchangeEnum;
-use crate::handle_info::HandleSwapInfo;
-
-// 处理账号信息
-pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-    let symbol_upper = symbol.to_uppercase();
-    let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
-    let balance_info_default = json!({"available":"0","coin": symbol_array[1],"frozen":"0","limitAvailable":"0","locked":"0","uTime":"0"});
-    let balance_info = res_data_json.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[1]).unwrap_or(&balance_info_default);
-    let stocks_info_default = json!({"available":"0","coin": symbol_array[0],"frozen":"0","limitAvailable":"0","locked":"0","uTime":"0"});
-    let stocks_info = res_data_json.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[0]).unwrap_or(&stocks_info_default);
-    format_account_info(balance_info.clone(), stocks_info.clone())
-}
-
-pub fn format_account_info(balance_data: serde_json::Value, stocks_data: serde_json::Value) -> Account {
-    let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
-    let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-    let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
-    let balance = available_balance + frozen_balance;
-
-    let stocks_coin = stocks_data["coin"].as_str().unwrap().to_string().to_uppercase();
-    let available_stocks = Decimal::from_str(stocks_data["available"].as_str().unwrap()).unwrap();
-    let frozen_stocks = Decimal::from_str(stocks_data["frozen"].as_str().unwrap()).unwrap();
-    let stocks = available_stocks + frozen_stocks;
-
-    Account {
-        coin: format!("{}_{}", stocks_coin, balance_coin),
-        balance,
-        available_balance,
-        frozen_balance,
-        stocks,
-        available_stocks,
-        frozen_stocks,
-    }
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    }
-    trace!(?order_info);
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-// 处理订单信息
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
-    let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
-    let status = order["status"].as_str().unwrap_or("");
-    let acc_base_volume = Decimal::from_str(order["accBaseVolume"].as_str().unwrap()).unwrap();
-
-    let avg_price = Decimal::from_str(order["priceAvg"].as_str().unwrap()).unwrap();
-
-    let amount = size * ct_val;
-    let deal_amount = acc_base_volume * ct_val;
-    let custom_status = if ["filled", "cancelled"].contains(&status) {
-        "REMOVE".to_string()
-    } else if ["init", "live", "new", "partially_filled"].contains(&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id: order["orderId"].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["orderType"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("89 bitget_spot_handle".to_string()),
-    }
-}
-
-// 处理特殊深度数据
-pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-    HandleSwapInfo::handle_special_depth(ExchangeEnum::BitgetSpot, res_data)
-}
-
-// 格式化深度信息
-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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
-
-// 处理特殊Ticker信息
-pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-    format_special_ticker(res_data_json[0].clone(), res_data.label)
-}
-
-pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let bp = Decimal::from_str(data["bidPr"].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_str(data["bidSz"].as_str().unwrap()).unwrap();
-    let ap = Decimal::from_str(data["askPr"].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_str(data["askSz"].as_str().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_str(data["ts"].as_str().unwrap()).unwrap();
-    let create_at = data["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: label,
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
+// use std::str::FromStr;
+// use rust_decimal::Decimal;
+// use rust_decimal_macros::dec;
+// use serde_json::json;
+// use tokio::time::Instant;
+// use tracing::trace;
+// use exchanges::response_base::ResponseData;
+// use global::trace_stack::TraceStack;
+// use crate::{Account, MarketOrder, Order, SpecialDepth, SpecialOrder, SpecialTicker};
+// use crate::exchange::ExchangeEnum;
+// use crate::handle_info::HandleSwapInfo;
+//
+// // 处理账号信息
+// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
+//     let symbol_upper = symbol.to_uppercase();
+//     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
+//     let balance_info_default = json!({"available":"0","coin": symbol_array[1],"frozen":"0","limitAvailable":"0","locked":"0","uTime":"0"});
+//     let balance_info = res_data_json.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[1]).unwrap_or(&balance_info_default);
+//     let stocks_info_default = json!({"available":"0","coin": symbol_array[0],"frozen":"0","limitAvailable":"0","locked":"0","uTime":"0"});
+//     let stocks_info = res_data_json.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[0]).unwrap_or(&stocks_info_default);
+//     format_account_info(balance_info.clone(), stocks_info.clone())
+// }
+//
+// pub fn format_account_info(balance_data: serde_json::Value, stocks_data: serde_json::Value) -> Account {
+//     let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
+//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
+//     let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
+//     let balance = available_balance + frozen_balance;
+//
+//     let stocks_coin = stocks_data["coin"].as_str().unwrap().to_string().to_uppercase();
+//     let available_stocks = Decimal::from_str(stocks_data["available"].as_str().unwrap()).unwrap();
+//     let frozen_stocks = Decimal::from_str(stocks_data["frozen"].as_str().unwrap()).unwrap();
+//     let stocks = available_stocks + frozen_stocks;
+//
+//     Account {
+//         coin: format!("{}_{}", stocks_coin, balance_coin),
+//         balance,
+//         available_balance,
+//         frozen_balance,
+//         stocks,
+//         available_stocks,
+//         frozen_stocks,
+//     }
+// }
+//
+// // 处理order信息
+// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
+//     let mut order_info = Vec::new();
+//     for item in res_data_json.iter() {
+//         order_info.push(format_order_item(item.clone(), ct_val));
+//     }
+//     trace!(?order_info);
+//     SpecialOrder {
+//         name: res_data.label,
+//         order: order_info,
+//     }
+// }
+//
+// // 处理订单信息
+// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
+//     let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
+//     let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
+//     let status = order["status"].as_str().unwrap_or("");
+//     let acc_base_volume = Decimal::from_str(order["accBaseVolume"].as_str().unwrap()).unwrap();
+//
+//     let avg_price = Decimal::from_str(order["priceAvg"].as_str().unwrap()).unwrap();
+//
+//     let amount = size * ct_val;
+//     let deal_amount = acc_base_volume * ct_val;
+//     let custom_status = if ["filled", "cancelled"].contains(&status) {
+//         "REMOVE".to_string()
+//     } else if ["init", "live", "new", "partially_filled"].contains(&status) {
+//         "NEW".to_string()
+//     } else {
+//         "NULL".to_string()
+//     };
+//     Order {
+//         id: order["orderId"].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["orderType"].as_str().unwrap().to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("89 bitget_spot_handle".to_string()),
+//     }
+// }
+//
+// // 处理特殊深度数据
+// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
+//     HandleSwapInfo::handle_special_depth(ExchangeEnum::BitgetSpot, res_data)
+// }
+//
+// // 格式化深度信息
+// 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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
+//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
+//         })
+//     }
+//     return depth_items;
+// }
+//
+// // 处理特殊Ticker信息
+// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
+//     format_special_ticker(res_data_json[0].clone(), res_data.label)
+// }
+//
+// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
+//     let bp = Decimal::from_str(data["bidPr"].as_str().unwrap()).unwrap();
+//     let bq = Decimal::from_str(data["bidSz"].as_str().unwrap()).unwrap();
+//     let ap = Decimal::from_str(data["askPr"].as_str().unwrap()).unwrap();
+//     let aq = Decimal::from_str(data["askSz"].as_str().unwrap()).unwrap();
+//     let mp = (bp + ap) * dec!(0.5);
+//     let t = Decimal::from_str(data["ts"].as_str().unwrap()).unwrap();
+//     let create_at = data["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
+//
+//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
+//     let depth_info = vec![bp, bq, ap, aq];
+//     SpecialDepth {
+//         name: label,
+//         depth: depth_info,
+//         ticker: ticker_info,
+//         t,
+//         create_at,
+//     }
+// }

+ 778 - 778
standard/src/bybit_swap.rs

@@ -1,778 +1,778 @@
-use std::collections::{BTreeMap, HashMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use rust_decimal::Decimal;
-use serde_json::{from_str, from_value, json, Value};
-use futures::stream::FuturesUnordered;
-use futures::{TryStreamExt};
-use rust_decimal::prelude::FromPrimitive;
-use serde::{Deserialize, Serialize};
-use tokio::time::Instant;
-use tracing::{error, debug, trace};
-use exchanges::bybit_swap_rest::BybitSwapRest;
-use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand, PositionModeEnum};
-use global::trace_stack::TraceStack;
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapTicker{
-    symbol: String,
-    high_price24h: Decimal,
-    low_price24h: Decimal,
-    bid1_price: Decimal,
-    ask1_price: Decimal,
-    last_price: Decimal,
-    volume24h: Decimal
-}
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct BybitSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    symbol_uppercase: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: BybitSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl BybitSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BybitSwap {
-        let market = Market::new();
-        let mut bybit_swap = BybitSwap {
-            exchange: ExchangeEnum::BybitSwap,
-            symbol: symbol.to_uppercase(),
-            symbol_uppercase: symbol.replace("_", "").to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: BybitSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-
-        // 修改持仓模式
-        let symbol_array: Vec<&str> = symbol.split("_").collect();
-        let mode_result = bybit_swap.set_dual_mode(symbol_array[1], true).await;
-        match mode_result {
-            Ok(_) => {
-                trace!("Bybit:设置持仓模式成功!")
-            }
-            Err(error) => {
-                error!("Bybit:设置持仓模式失败!mode_result={}", error)
-            }
-        }
-        // 获取市场信息
-        bybit_swap.market = BybitSwap::get_market(&mut bybit_swap).await.unwrap_or(bybit_swap.market);
-        return bybit_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for BybitSwap {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    // 获取交易所模式
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::GateSwap
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-    // 获取market信息
-    fn get_self_market(&self) -> Market { self.market.clone() }
-    // 获取请求时间
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-    // 获取请求平均时间
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-    // 获取请求最大时间
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-
-    // 获取服务器时间
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        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 = res_data_json["server_time"].to_string();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取账号信息
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let res_data = self.request.get_account_balance(symbol_array[1].parse().unwrap()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str).unwrap();
-            let arr_infos: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
-            if arr_infos.len() < 1usize{
-                return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
-            }
-            let coin_infos: Vec<Value> = from_value(arr_infos[0]["coin"].clone()).unwrap();
-            if coin_infos.len() < 1usize{
-               return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
-            }
-            let balance = Decimal::from_str(coin_infos[0]["equity"].as_str().unwrap()).unwrap();
-            let available_balance = Decimal::from_str(coin_infos[0]["walletBalance"].as_str().unwrap()).unwrap();
-            let frozen_balance = balance - available_balance;
-            let result = Account {
-                coin: symbol_array[1].to_string(),
-                balance,
-                available_balance,
-                frozen_balance,
-                stocks: Decimal::ZERO,
-                available_stocks: Decimal::ZERO,
-                frozen_stocks: Decimal::ZERO,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bybit_swap:该交易所方法未实现".to_string()))
-    }
-
-    // 获取持仓信息
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_positions(symbol, "".to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str: Value = from_str(&res_data.data).unwrap();
-            let res_data_json: Vec<Value> = from_value(res_data_str["list"].clone()).unwrap();
-            let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取所有持仓
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_positions("".to_string(), symbol_array[1].to_string().to_uppercase()).await;
-        if res_data.code == "200" {
-            let res_data_str: Value = from_str(&res_data.data).unwrap();
-            let res_data_json: Vec<Value> = from_value(res_data_str["list"].clone()).unwrap();
-            let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取市场行情
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.get_tickers(symbol).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str).unwrap();
-            let list :Vec<SwapTicker>= from_value(res_data_json["list"].clone()).unwrap_or(Vec::new());
-
-            if list.len() < 1usize {
-                error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
-                return Err(Error::new(ErrorKind::Other, res_data.to_string()));
-            }
-            let value = list[0].clone();
-            Ok(Ticker{
-                time: chrono::Utc::now().timestamp_millis(),
-                high: value.high_price24h,
-                low: value.low_price24h,
-                sell: value.ask1_price,
-                buy: value.bid1_price,
-                last: value.last_price,
-                volume: value.volume24h
-            })
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_upper = symbol.replace("_", "").to_uppercase();
-        let res_data = self.request.get_tickers(symbol_upper.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let arr: Value = from_str(res_data_str).unwrap();
-            let list :Vec<SwapTicker> = from_value(arr["list"].clone()).unwrap();
-            let ticker_info = list.iter().find(|&item| item.symbol == symbol_upper);
-
-            match ticker_info {
-                None => {
-                    error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let result = Ticker {
-                        time: chrono::Utc::now().timestamp_millis(),
-                        high: value.high_price24h,
-                        low: value.low_price24h,
-                        sell: value.ask1_price,
-                        buy: value.bid1_price,
-                        last: value.last_price,
-                        volume: value.volume24h
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.get_instruments_info(symbol.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = res_data.data.clone();
-            let res_data_json: Value = from_str(res_data_str.as_str()).unwrap();
-            let arr_data: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
-            let market_info = arr_data.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol);
-            match market_info {
-                None => {
-                    error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_coin = value["baseCoin"].as_str().unwrap();
-                    let quote_coin = value["quoteCoin"].as_str().unwrap();
-                    let name = format!("{}_{}",base_coin, quote_coin);
-                    let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
-                    let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let ct_val = Decimal::ONE;
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-                    let max_notional = max_qty * ct_val;
-
-                    let result = Market {
-                        symbol: name,
-                        base_asset: base_coin.to_string(),
-                        quote_asset: quote_coin.to_string(),
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional,
-                        max_notional,
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol = symbol.replace("_", "").to_uppercase();
-        let res_data = self.request.get_instruments_info(symbol.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str.as_str()).unwrap();
-            let arr_data: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
-            let market_info = arr_data.iter().find(|item| item["symbol"].as_str().unwrap() == symbol);
-            match market_info {
-                None => {
-                    error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_coin = value["baseCoin"].as_str().unwrap();
-                    let quote_coin = value["quoteCoin"].as_str().unwrap();
-                    let name = format!("{}_{}",base_coin, quote_coin);
-                    let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
-                    let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let ct_val = Decimal::ONE;
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-                    let max_notional = max_qty * ct_val;
-
-                    let result = Market {
-                        symbol: name,
-                        base_asset: base_coin.to_string(),
-                        quote_asset: quote_coin.to_string(),
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional,
-                        max_notional,
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 获取订单详情
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let ct_val = self.market.ct_val;
-        let id = if !custom_id.trim().eq("") { format!("t-{}", custom_id) } else { String::new() };
-        let res_data = self.request.get_order(symbol, order_id.parse().unwrap(), id).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str::<Value>(res_data_str).unwrap()["list"].clone();
-            if res_data_json.is_array() && res_data_json.as_array().unwrap().len() == 0 {
-                return Err(Error::new(ErrorKind::Other, "没有该订单!"));
-            }
-            let result = format_order_item(res_data_json.as_array().unwrap()[0].clone(), ct_val);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取订单列表
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-       Err(Error::new(ErrorKind::Other, "bybit获取订单列表暂未实现".to_string()))
-    }
-    // 下单接口
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let ct_val = self.market.ct_val;
-        let size = amount / ct_val;
-        let mut params = json!({
-            "orderLinkId": format!("t-{}", custom_id),
-            "symbol": symbol.to_string(),
-            "price": price.to_string(),
-            "category": "linear",
-            "orderType":"Limit",
-            "qty": json!(size),
-            // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
-            "positionIdx": json!(1),
-            "reduceOnly": json!(false)
-        });
-
-        if price.eq(&Decimal::ZERO) {
-            params["timeInForce"] = json!("IOC".to_string());
-        }
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("Buy");
-            }
-            "pd" => {
-                params["side"] = json!("Sell");
-                // 减仓
-                params["reduceOnly"] = json!(true);
-            }
-            "kk" => {
-                params["side"] = json!("Sell");
-                params["positionIdx"] = json!(2);
-            }
-            "pk" => {
-                params["side"] = json!("Buy");
-                // 减仓
-                params["reduceOnly"] = json!(true);
-                params["positionIdx"] = json!(2);
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.swap_order(params).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str).unwrap();
-            let result = format_new_order_item(res_data_json, price, size);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_upper = symbol.replace("_", "").trim().to_uppercase();
-        let size = (amount / ct_val).floor();
-        let order_type = if price == Decimal::ZERO {
-            "Market"
-        } else {
-            "Limit"
-        };
-        let mut params = json!({
-            "orderLinkId": format!("t-{}", custom_id),
-            "symbol": symbol_upper,
-            "price": price.to_string(),
-            "category": "linear",
-            "orderType": order_type,
-            "qty": json!(size),
-            // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
-            "positionIdx": json!(1),
-            "reduceOnly": json!(false)
-        });
-
-        if price.eq(&Decimal::ZERO) {
-            params["timeInForce"] = json!("IOC".to_string());
-        }
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("Buy");
-            }
-            "pd" => {
-                params["side"] = json!("Sell");
-                params["positionIdx"] = json!(1);
-                // 减仓
-                params["reduceOnly"] = json!(true);
-            }
-            "kk" => {
-                params["side"] = json!("Sell");
-                params["positionIdx"] = json!(2);
-            }
-            "pk" => {
-                params["side"] = json!("Buy");
-                params["positionIdx"] = json!(2);
-                // 减仓
-                params["reduceOnly"] = json!(true);
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.swap_order(params.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str).unwrap();
-            let result = format_new_order_item(res_data_json, price, size);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 撤销订单
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let id = format!("t-{}", custom_id);
-        let res_data = self.request.cancel_order(symbol, String::from(order_id), id.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str).unwrap();
-            let result = format_cancel_order_item(res_data_json);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 批量撤销订单
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.cancel_orders(symbol).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str).unwrap();
-            let res_arr: Vec<Value> = from_value(res_data_json).unwrap();
-            let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.cancel_orders(symbol).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Value = from_str(res_data_str).unwrap();
-            let res_arr: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
-            let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 设置持仓模式
-    async fn set_dual_mode(&mut self, _coin: &str, is_dual_mode: bool) -> Result<String, Error> {
-        let coin_format = self.symbol_uppercase.clone();
-        let mut mod_num = 0;
-        if is_dual_mode {
-            mod_num = 3;
-        }
-        let res_data = self.request.set_position_mode(coin_format, mod_num).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.to_string()))
-        }
-    }
-
-    // 更新双持仓模式下杠杆
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.set_leverage(symbol, 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.to_string()))
-        }
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate:该交易所方法未实现".to_string())) }
-
-    // 交易账户互转
-    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.to_string()))
-        // }
-        Err(Error::new(ErrorKind::Other, "暂未实现!"))
-    }
-
-    // 指令下单
-    async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-        let mut handles = vec![];
-        // 撤销订单
-        let cancel = order_command.cancel;
-        for item in cancel.keys() {
-            let mut self_clone = self.clone();
-            let cancel_clone = cancel.clone();
-            let item_clone = item.clone();
-            let order_id = cancel_clone.get(&item_clone).unwrap().get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                match result {
-                    Ok(_) => {
-                        // result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        // 取消失败去查订单。
-                        let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                        match query_rst {
-                            Ok(order) => {
-                                result_sd.send(order).await.unwrap();
-                            }
-                            Err(_err) => {
-                                error!("bybit:撤单失败,而且查单也失败了,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                                // panic!("撤单失败,而且查单也失败了,gate_io_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                            }
-                        }
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 下单指令
-        let mut limits = HashMap::new();
-        limits.extend(order_command.limits_open);
-        limits.extend(order_command.limits_close);
-        for item in limits.keys() {
-            let mut self_clone = self.clone();
-            let limits_clone = limits.clone();
-            let item_clone = item.clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let ts = trace_stack.clone();
-
-            let handle = tokio::spawn(async move {
-                let value = limits_clone[&item_clone].clone();
-                let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-                let side = value.get(1).unwrap();
-                let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-                let cid = value.get(3).unwrap();
-
-                //  order_name: [数量,方向,价格,c_id]
-                let result = self_clone.take_order(cid, side, price, amount).await;
-                match result {
-                    Ok(mut result) => {
-                        // 记录此订单完成时间
-                        // ts.on_after_send();
-                        result.trace_stack = ts;
-
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        error!("bybit:下单失败:{:?}", error);
-
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        result_sd.send(err_order).await.unwrap();
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 检查订单指令
-        let check = order_command.check;
-        for item in check.keys() {
-            let mut self_clone = self.clone();
-            let check_clone = check.clone();
-            let item_clone = item.clone();
-            let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
-    let position_idx = position["positionIdx"].to_string();
-    let mut position_mode = match position_idx.as_str() {
-        "0" => PositionModeEnum::Both,
-        "1" => PositionModeEnum::Long,
-        "2" => PositionModeEnum::Short,
-        _ => {
-            error!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
-        }
-    };
-    let size_str: String = from_value(position["size"].clone()).unwrap();
-    let size = Decimal::from_str(size_str.as_str()).unwrap();
-    let amount = size * ct_val;
-    let mut profit = Decimal::ZERO;
-    let profit_str = position["unrealisedPnl"].as_str().unwrap_or("0");
-    if profit_str != "" {
-        profit = Decimal::from_str(profit_str).unwrap();
-    }
-
-    match position_mode {
-        PositionModeEnum::Both => {
-            position_mode = match amount {
-                amount if amount > Decimal::ZERO => PositionModeEnum::Long,
-                amount if amount < Decimal::ZERO => PositionModeEnum::Short,
-                _ => { PositionModeEnum::Both }
-            }
-        }
-        _ => {}
-    }
-    Position {
-        symbol: position["symbol"].as_str().unwrap_or("").parse().unwrap(),
-        margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(position["avgPrice"].as_str().unwrap()).unwrap(),
-        profit,
-        position_mode,
-        margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
-    }
-}
-
-fn format_cancel_order_item(order: Value) -> Order {
-     Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
-        price: Decimal::ZERO,
-        amount: Decimal::ZERO,
-        deal_amount: Decimal::ZERO,
-        avg_price: Decimal::ZERO,
-        status: "REMOVE".to_string(),
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string())
-    }
-}
-
-fn format_new_order_item(order: Value, price: Decimal, amount: Decimal) -> Order {
-    Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
-        price,
-        amount,
-        deal_amount: Decimal::ZERO,
-        avg_price: price,
-        status: "NEW".to_string(),
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string())
-    }
-}
-
-pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
-    debug!("format-order-start, bybit_swap");
-    debug!(?order);
-    let status = order["orderStatus"].as_str().unwrap_or("");
-    let text = order["orderLinkId"].as_str().unwrap_or("");
-    let mut size = Decimal::ZERO;
-    let mut deal_amount = Decimal::ZERO;
-    let mut avg_price = Decimal::ZERO;
-
-    let right_str = order["cumExecQty"].to_string();
-    let size_str = order["qty"].to_string();
-
-    if !order.get("qty").is_some() {
-        size = Decimal::from_str(size_str.as_str()).unwrap();
-        let right_val = Decimal::from_str(order["cumExecValue"].as_str().unwrap()).unwrap();
-        let right = Decimal::from_str(right_str.as_str()).unwrap();
-        if right != Decimal::ZERO {
-            avg_price = right_val / right;
-        }
-        deal_amount = right * ct_val;
-    }
-
-    let amount = size * ct_val;
-    let custom_status = if status == "Filled" || status == "Cancelled" { "REMOVE".to_string() } else if status == "New" { "NEW".to_string() } else {
-        "NULL".to_string()
-    };
-    let rst_order = Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
-        price: Decimal::from_str(order["price"].as_str().unwrap()).unwrap(),
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string()),
-    };
-    debug!(?rst_order);
-    debug!("format-order-end, bybit_swap");
-    return rst_order;
-}
+// use std::collections::{BTreeMap, HashMap};
+// use std::io::{Error, ErrorKind};
+// use std::str::FromStr;
+// use tokio::sync::mpsc::Sender;
+// use async_trait::async_trait;
+// use rust_decimal::Decimal;
+// use serde_json::{from_str, from_value, json, Value};
+// use futures::stream::FuturesUnordered;
+// use futures::{TryStreamExt};
+// use rust_decimal::prelude::FromPrimitive;
+// use serde::{Deserialize, Serialize};
+// use tokio::time::Instant;
+// use tracing::{error, debug, trace};
+// use exchanges::bybit_swap_rest::BybitSwapRest;
+// use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand, PositionModeEnum};
+// use global::trace_stack::TraceStack;
+//
+// #[derive(Debug, Clone, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SwapTicker{
+//     symbol: String,
+//     high_price24h: Decimal,
+//     low_price24h: Decimal,
+//     bid1_price: Decimal,
+//     ask1_price: Decimal,
+//     last_price: Decimal,
+//     volume24h: Decimal
+// }
+//
+// #[allow(dead_code)]
+// #[derive(Clone)]
+// pub struct BybitSwap {
+//     exchange: ExchangeEnum,
+//     symbol: String,
+//     symbol_uppercase: String,
+//     is_colo: bool,
+//     params: BTreeMap<String, String>,
+//     request: BybitSwapRest,
+//     market: Market,
+//     order_sender: Sender<Order>,
+//     error_sender: Sender<Error>,
+// }
+//
+// impl BybitSwap {
+//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BybitSwap {
+//         let market = Market::new();
+//         let mut bybit_swap = BybitSwap {
+//             exchange: ExchangeEnum::BybitSwap,
+//             symbol: symbol.to_uppercase(),
+//             symbol_uppercase: symbol.replace("_", "").to_uppercase(),
+//             is_colo,
+//             params: params.clone(),
+//             request: BybitSwapRest::new(is_colo, params.clone()),
+//             market,
+//             order_sender,
+//             error_sender,
+//         };
+//
+//         // 修改持仓模式
+//         let symbol_array: Vec<&str> = symbol.split("_").collect();
+//         let mode_result = bybit_swap.set_dual_mode(symbol_array[1], true).await;
+//         match mode_result {
+//             Ok(_) => {
+//                 trace!("Bybit:设置持仓模式成功!")
+//             }
+//             Err(error) => {
+//                 error!("Bybit:设置持仓模式失败!mode_result={}", error)
+//             }
+//         }
+//         // 获取市场信息
+//         bybit_swap.market = BybitSwap::get_market(&mut bybit_swap).await.unwrap_or(bybit_swap.market);
+//         return bybit_swap;
+//     }
+// }
+//
+// #[async_trait]
+// impl Platform for BybitSwap {
+//     // 克隆方法
+//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
+//     // 获取交易所模式
+//     fn get_self_exchange(&self) -> ExchangeEnum {
+//         ExchangeEnum::GateSwap
+//     }
+//     // 获取交易对
+//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
+//     // 获取是否使用高速通道
+//     fn get_self_is_colo(&self) -> bool {
+//         self.is_colo
+//     }
+//     // 获取params信息
+//     fn get_self_params(&self) -> BTreeMap<String, String> {
+//         self.params.clone()
+//     }
+//     // 获取market信息
+//     fn get_self_market(&self) -> Market { self.market.clone() }
+//     // 获取请求时间
+//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
+//     // 获取请求平均时间
+//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
+//     // 获取请求最大时间
+//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
+//
+//     // 获取服务器时间
+//     async fn get_server_time(&mut self) -> Result<String, Error> {
+//         let res_data = self.request.get_server_time().await;
+//         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 = res_data_json["server_time"].to_string();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//     // 获取账号信息
+//     async fn get_account(&mut self) -> Result<Account, Error> {
+//         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
+//         let res_data = self.request.get_account_balance(symbol_array[1].parse().unwrap()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str).unwrap();
+//             let arr_infos: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
+//             if arr_infos.len() < 1usize{
+//                 return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
+//             }
+//             let coin_infos: Vec<Value> = from_value(arr_infos[0]["coin"].clone()).unwrap();
+//             if coin_infos.len() < 1usize{
+//                return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
+//             }
+//             let balance = Decimal::from_str(coin_infos[0]["equity"].as_str().unwrap()).unwrap();
+//             let available_balance = Decimal::from_str(coin_infos[0]["walletBalance"].as_str().unwrap()).unwrap();
+//             let frozen_balance = balance - available_balance;
+//             let result = Account {
+//                 coin: symbol_array[1].to_string(),
+//                 balance,
+//                 available_balance,
+//                 frozen_balance,
+//                 stocks: Decimal::ZERO,
+//                 available_stocks: Decimal::ZERO,
+//                 frozen_stocks: Decimal::ZERO,
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "bybit_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     // 获取持仓信息
+//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_positions(symbol, "".to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str: Value = from_str(&res_data.data).unwrap();
+//             let res_data_json: Vec<Value> = from_value(res_data_str["list"].clone()).unwrap();
+//             let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//     // 获取所有持仓
+//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
+//         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_positions("".to_string(), symbol_array[1].to_string().to_uppercase()).await;
+//         if res_data.code == "200" {
+//             let res_data_str: Value = from_str(&res_data.data).unwrap();
+//             let res_data_json: Vec<Value> = from_value(res_data_str["list"].clone()).unwrap();
+//             let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//     // 获取市场行情
+//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let res_data = self.request.get_tickers(symbol).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str).unwrap();
+//             let list :Vec<SwapTicker>= from_value(res_data_json["list"].clone()).unwrap_or(Vec::new());
+//
+//             if list.len() < 1usize {
+//                 error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
+//                 return Err(Error::new(ErrorKind::Other, res_data.to_string()));
+//             }
+//             let value = list[0].clone();
+//             Ok(Ticker{
+//                 time: chrono::Utc::now().timestamp_millis(),
+//                 high: value.high_price24h,
+//                 low: value.low_price24h,
+//                 sell: value.ask1_price,
+//                 buy: value.bid1_price,
+//                 last: value.last_price,
+//                 volume: value.volume24h
+//             })
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
+//         let symbol_upper = symbol.replace("_", "").to_uppercase();
+//         let res_data = self.request.get_tickers(symbol_upper.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let arr: Value = from_str(res_data_str).unwrap();
+//             let list :Vec<SwapTicker> = from_value(arr["list"].clone()).unwrap();
+//             let ticker_info = list.iter().find(|&item| item.symbol == symbol_upper);
+//
+//             match ticker_info {
+//                 None => {
+//                     error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
+//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//                 }
+//                 Some(value) => {
+//                     let result = Ticker {
+//                         time: chrono::Utc::now().timestamp_millis(),
+//                         high: value.high_price24h,
+//                         low: value.low_price24h,
+//                         sell: value.ask1_price,
+//                         buy: value.bid1_price,
+//                         last: value.last_price,
+//                         volume: value.volume24h
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market(&mut self) -> Result<Market, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let res_data = self.request.get_instruments_info(symbol.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = res_data.data.clone();
+//             let res_data_json: Value = from_str(res_data_str.as_str()).unwrap();
+//             let arr_data: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
+//             let market_info = arr_data.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol);
+//             match market_info {
+//                 None => {
+//                     error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
+//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//                 }
+//                 Some(value) => {
+//                     let base_coin = value["baseCoin"].as_str().unwrap();
+//                     let quote_coin = value["quoteCoin"].as_str().unwrap();
+//                     let name = format!("{}_{}",base_coin, quote_coin);
+//                     let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
+//                     let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
+//                     let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
+//                     let ct_val = Decimal::ONE;
+//
+//                     let amount_size = min_qty * ct_val;
+//                     let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
+//                     let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
+//                     let min_notional = min_qty * ct_val;
+//                     let max_notional = max_qty * ct_val;
+//
+//                     let result = Market {
+//                         symbol: name,
+//                         base_asset: base_coin.to_string(),
+//                         quote_asset: quote_coin.to_string(),
+//                         tick_size,
+//                         amount_size,
+//                         price_precision,
+//                         amount_precision,
+//                         min_qty,
+//                         max_qty,
+//                         min_notional,
+//                         max_notional,
+//                         ct_val,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
+//         let symbol = symbol.replace("_", "").to_uppercase();
+//         let res_data = self.request.get_instruments_info(symbol.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str.as_str()).unwrap();
+//             let arr_data: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
+//             let market_info = arr_data.iter().find(|item| item["symbol"].as_str().unwrap() == symbol);
+//             match market_info {
+//                 None => {
+//                     error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
+//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//                 }
+//                 Some(value) => {
+//                     let base_coin = value["baseCoin"].as_str().unwrap();
+//                     let quote_coin = value["quoteCoin"].as_str().unwrap();
+//                     let name = format!("{}_{}",base_coin, quote_coin);
+//                     let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
+//                     let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
+//                     let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
+//                     let ct_val = Decimal::ONE;
+//
+//                     let amount_size = min_qty * ct_val;
+//                     let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
+//                     let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
+//                     let min_notional = min_qty * ct_val;
+//                     let max_notional = max_qty * ct_val;
+//
+//                     let result = Market {
+//                         symbol: name,
+//                         base_asset: base_coin.to_string(),
+//                         quote_asset: quote_coin.to_string(),
+//                         tick_size,
+//                         amount_size,
+//                         price_precision,
+//                         amount_precision,
+//                         min_qty,
+//                         max_qty,
+//                         min_notional,
+//                         max_notional,
+//                         ct_val,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     // 获取订单详情
+//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let ct_val = self.market.ct_val;
+//         let id = if !custom_id.trim().eq("") { format!("t-{}", custom_id) } else { String::new() };
+//         let res_data = self.request.get_order(symbol, order_id.parse().unwrap(), id).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str::<Value>(res_data_str).unwrap()["list"].clone();
+//             if res_data_json.is_array() && res_data_json.as_array().unwrap().len() == 0 {
+//                 return Err(Error::new(ErrorKind::Other, "没有该订单!"));
+//             }
+//             let result = format_order_item(res_data_json.as_array().unwrap()[0].clone(), ct_val);
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//     // 获取订单列表
+//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
+//        Err(Error::new(ErrorKind::Other, "bybit获取订单列表暂未实现".to_string()))
+//     }
+//     // 下单接口
+//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let ct_val = self.market.ct_val;
+//         let size = amount / ct_val;
+//         let mut params = json!({
+//             "orderLinkId": format!("t-{}", custom_id),
+//             "symbol": symbol.to_string(),
+//             "price": price.to_string(),
+//             "category": "linear",
+//             "orderType":"Limit",
+//             "qty": json!(size),
+//             // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
+//             "positionIdx": json!(1),
+//             "reduceOnly": json!(false)
+//         });
+//
+//         if price.eq(&Decimal::ZERO) {
+//             params["timeInForce"] = json!("IOC".to_string());
+//         }
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("Buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("Sell");
+//                 // 减仓
+//                 params["reduceOnly"] = json!(true);
+//             }
+//             "kk" => {
+//                 params["side"] = json!("Sell");
+//                 params["positionIdx"] = json!(2);
+//             }
+//             "pk" => {
+//                 params["side"] = json!("Buy");
+//                 // 减仓
+//                 params["reduceOnly"] = json!(true);
+//                 params["positionIdx"] = json!(2);
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.swap_order(params).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str).unwrap();
+//             let result = format_new_order_item(res_data_json, price, size);
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_upper = symbol.replace("_", "").trim().to_uppercase();
+//         let size = (amount / ct_val).floor();
+//         let order_type = if price == Decimal::ZERO {
+//             "Market"
+//         } else {
+//             "Limit"
+//         };
+//         let mut params = json!({
+//             "orderLinkId": format!("t-{}", custom_id),
+//             "symbol": symbol_upper,
+//             "price": price.to_string(),
+//             "category": "linear",
+//             "orderType": order_type,
+//             "qty": json!(size),
+//             // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
+//             "positionIdx": json!(1),
+//             "reduceOnly": json!(false)
+//         });
+//
+//         if price.eq(&Decimal::ZERO) {
+//             params["timeInForce"] = json!("IOC".to_string());
+//         }
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("Buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("Sell");
+//                 params["positionIdx"] = json!(1);
+//                 // 减仓
+//                 params["reduceOnly"] = json!(true);
+//             }
+//             "kk" => {
+//                 params["side"] = json!("Sell");
+//                 params["positionIdx"] = json!(2);
+//             }
+//             "pk" => {
+//                 params["side"] = json!("Buy");
+//                 params["positionIdx"] = json!(2);
+//                 // 减仓
+//                 params["reduceOnly"] = json!(true);
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.swap_order(params.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str).unwrap();
+//             let result = format_new_order_item(res_data_json, price, size);
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     // 撤销订单
+//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let id = format!("t-{}", custom_id);
+//         let res_data = self.request.cancel_order(symbol, String::from(order_id), id.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str).unwrap();
+//             let result = format_cancel_order_item(res_data_json);
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//     // 批量撤销订单
+//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let res_data = self.request.cancel_orders(symbol).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str).unwrap();
+//             let res_arr: Vec<Value> = from_value(res_data_json).unwrap();
+//             let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let res_data = self.request.cancel_orders(symbol).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Value = from_str(res_data_str).unwrap();
+//             let res_arr: Vec<Value> = from_value(res_data_json["list"].clone()).unwrap();
+//             let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     // 设置持仓模式
+//     async fn set_dual_mode(&mut self, _coin: &str, is_dual_mode: bool) -> Result<String, Error> {
+//         let coin_format = self.symbol_uppercase.clone();
+//         let mut mod_num = 0;
+//         if is_dual_mode {
+//             mod_num = 3;
+//         }
+//         let res_data = self.request.set_position_mode(coin_format, mod_num).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.to_string()))
+//         }
+//     }
+//
+//     // 更新双持仓模式下杠杆
+//     async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
+//         let symbol = self.symbol_uppercase.clone();
+//         let res_data = self.request.set_leverage(symbol, 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.to_string()))
+//         }
+//     }
+//
+//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate:该交易所方法未实现".to_string())) }
+//
+//     // 交易账户互转
+//     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.to_string()))
+//         // }
+//         Err(Error::new(ErrorKind::Other, "暂未实现!"))
+//     }
+//
+//     // 指令下单
+//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
+//         let mut handles = vec![];
+//         // 撤销订单
+//         let cancel = order_command.cancel;
+//         for item in cancel.keys() {
+//             let mut self_clone = self.clone();
+//             let cancel_clone = cancel.clone();
+//             let item_clone = item.clone();
+//             let order_id = cancel_clone.get(&item_clone).unwrap().get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.cancel_order(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(_) => {
+//                         // result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         // 取消失败去查订单。
+//                         let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                         match query_rst {
+//                             Ok(order) => {
+//                                 result_sd.send(order).await.unwrap();
+//                             }
+//                             Err(_err) => {
+//                                 error!("bybit:撤单失败,而且查单也失败了,oid={}, cid={}。", order_id.clone(), custom_id.clone());
+//                                 // panic!("撤单失败,而且查单也失败了,gate_io_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
+//                             }
+//                         }
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 下单指令
+//         let mut limits = HashMap::new();
+//         limits.extend(order_command.limits_open);
+//         limits.extend(order_command.limits_close);
+//         for item in limits.keys() {
+//             let mut self_clone = self.clone();
+//             let limits_clone = limits.clone();
+//             let item_clone = item.clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let ts = trace_stack.clone();
+//
+//             let handle = tokio::spawn(async move {
+//                 let value = limits_clone[&item_clone].clone();
+//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
+//                 let side = value.get(1).unwrap();
+//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
+//                 let cid = value.get(3).unwrap();
+//
+//                 //  order_name: [数量,方向,价格,c_id]
+//                 let result = self_clone.take_order(cid, side, price, amount).await;
+//                 match result {
+//                     Ok(mut result) => {
+//                         // 记录此订单完成时间
+//                         // ts.on_after_send();
+//                         result.trace_stack = ts;
+//
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         error!("bybit:下单失败:{:?}", error);
+//
+//                         let mut err_order = Order::new();
+//                         err_order.custom_id = cid.clone();
+//                         err_order.status = "REMOVE".to_string();
+//
+//                         result_sd.send(err_order).await.unwrap();
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 检查订单指令
+//         let check = order_command.check;
+//         for item in check.keys() {
+//             let mut self_clone = self.clone();
+//             let check_clone = check.clone();
+//             let item_clone = item.clone();
+//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(result) => {
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//
+//         let futures = FuturesUnordered::from_iter(handles);
+//         let _: Result<Vec<_>, _> = futures.try_collect().await;
+//     }
+// }
+//
+// pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
+//     let position_idx = position["positionIdx"].to_string();
+//     let mut position_mode = match position_idx.as_str() {
+//         "0" => PositionModeEnum::Both,
+//         "1" => PositionModeEnum::Long,
+//         "2" => PositionModeEnum::Short,
+//         _ => {
+//             error!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
+//             panic!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
+//         }
+//     };
+//     let size_str: String = from_value(position["size"].clone()).unwrap();
+//     let size = Decimal::from_str(size_str.as_str()).unwrap();
+//     let amount = size * ct_val;
+//     let mut profit = Decimal::ZERO;
+//     let profit_str = position["unrealisedPnl"].as_str().unwrap_or("0");
+//     if profit_str != "" {
+//         profit = Decimal::from_str(profit_str).unwrap();
+//     }
+//
+//     match position_mode {
+//         PositionModeEnum::Both => {
+//             position_mode = match amount {
+//                 amount if amount > Decimal::ZERO => PositionModeEnum::Long,
+//                 amount if amount < Decimal::ZERO => PositionModeEnum::Short,
+//                 _ => { PositionModeEnum::Both }
+//             }
+//         }
+//         _ => {}
+//     }
+//     Position {
+//         symbol: position["symbol"].as_str().unwrap_or("").parse().unwrap(),
+//         margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
+//         amount,
+//         frozen_amount: Decimal::ZERO,
+//         price: Decimal::from_str(position["avgPrice"].as_str().unwrap()).unwrap(),
+//         profit,
+//         position_mode,
+//         margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
+//     }
+// }
+//
+// fn format_cancel_order_item(order: Value) -> Order {
+//      Order {
+//         id: format!("{}", order["orderId"].as_str().unwrap()),
+//         custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
+//         price: Decimal::ZERO,
+//         amount: Decimal::ZERO,
+//         deal_amount: Decimal::ZERO,
+//         avg_price: Decimal::ZERO,
+//         status: "REMOVE".to_string(),
+//         order_type: "limit".to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string())
+//     }
+// }
+//
+// fn format_new_order_item(order: Value, price: Decimal, amount: Decimal) -> Order {
+//     Order {
+//         id: format!("{}", order["orderId"].as_str().unwrap()),
+//         custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
+//         price,
+//         amount,
+//         deal_amount: Decimal::ZERO,
+//         avg_price: price,
+//         status: "NEW".to_string(),
+//         order_type: "limit".to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string())
+//     }
+// }
+//
+// pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
+//     debug!("format-order-start, bybit_swap");
+//     debug!(?order);
+//     let status = order["orderStatus"].as_str().unwrap_or("");
+//     let text = order["orderLinkId"].as_str().unwrap_or("");
+//     let mut size = Decimal::ZERO;
+//     let mut deal_amount = Decimal::ZERO;
+//     let mut avg_price = Decimal::ZERO;
+//
+//     let right_str = order["cumExecQty"].to_string();
+//     let size_str = order["qty"].to_string();
+//
+//     if !order.get("qty").is_some() {
+//         size = Decimal::from_str(size_str.as_str()).unwrap();
+//         let right_val = Decimal::from_str(order["cumExecValue"].as_str().unwrap()).unwrap();
+//         let right = Decimal::from_str(right_str.as_str()).unwrap();
+//         if right != Decimal::ZERO {
+//             avg_price = right_val / right;
+//         }
+//         deal_amount = right * ct_val;
+//     }
+//
+//     let amount = size * ct_val;
+//     let custom_status = if status == "Filled" || status == "Cancelled" { "REMOVE".to_string() } else if status == "New" { "NEW".to_string() } else {
+//         "NULL".to_string()
+//     };
+//     let rst_order = Order {
+//         id: format!("{}", order["orderId"].as_str().unwrap()),
+//         custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
+//         price: Decimal::from_str(order["price"].as_str().unwrap()).unwrap(),
+//         amount,
+//         deal_amount,
+//         avg_price,
+//         status: custom_status,
+//         order_type: "limit".to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string()),
+//     };
+//     debug!(?rst_order);
+//     debug!("format-order-end, bybit_swap");
+//     return rst_order;
+// }

+ 189 - 189
standard/src/bybit_swap_handle.rs

@@ -1,189 +1,189 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use serde_json::{from_str, from_value};
-use tokio::time::Instant;
-use toml::Value;
-use tracing::{debug, error};
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
-
-// 处理账号信息
-pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = from_str(&res_data_str).unwrap();
-    format_account_info(res_data_json, symbol)
-}
-
-pub fn format_account_info(data: Vec<serde_json::Value>, symbol: String) -> Account {
-    let account = data.iter().find(| &item | item["accountType"] == "UNIFIED");
-    match account {
-        None => {
-            error!("Bybit:格式化统一账户信息错误!\nformat_account_info: data={:?}", data);
-            panic!("Bybit:格式化统一账户信息错误!\nformat_account_info: data={:?}", data)
-        }
-        Some(val) =>{
-            let arr: Vec<Value> = serde_json::from_value(val["coin"].clone()).unwrap();
-            let upper_str = symbol.to_uppercase();
-            let symbol_array: Vec<&str> = upper_str.split("_").collect();
-            let balance_info = arr.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[1]);
-            match balance_info {
-                None => {
-                    error!("Bybit:格式化usdt余额信息错误!\nformat_account_info: data={:?}", balance_info);
-                    panic!("Bybit:格式化usdt余额信息错误!\nformat_account_info: data={:?}", balance_info)
-                }
-                Some(value) => {
-                    let balance = Decimal::from_str(&value["walletBalance"].as_str().unwrap().to_string()).unwrap();
-                    Account {
-                        coin: symbol_array[1].to_string(),
-                        balance,
-                        available_balance: Decimal::ZERO,
-                        frozen_balance: Decimal::ZERO,
-                        stocks: Decimal::ZERO,
-                        available_stocks: Decimal::ZERO,
-                        frozen_stocks: Decimal::ZERO,
-                    }
-                }
-            }
-        }
-    }
-
-
-
-}
-
-// 处理position信息
-pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
-    let res_data_json: Vec<serde_json::Value> = from_str(&res_data.data).unwrap();
-    res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect()
-}
-
-pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Position {
-    let position_idx: String = position["positionIdx"].to_string();
-    let mut position_mode = match position_idx.as_str() {
-        "0" => PositionModeEnum::Both,
-        "1" => PositionModeEnum::Long,
-        "2" => PositionModeEnum::Short,
-        _ => {
-            error!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
-        }
-    };
-    let symbol_mapper =  position["symbol"].as_str().unwrap().to_string();
-    let currency = "USDT";
-    let coin = &symbol_mapper[..symbol_mapper.find(currency).unwrap_or(0)];
-    let size_str: String = from_value(position["size"].clone()).unwrap();
-    let size = Decimal::from_str(size_str.as_str()).unwrap();
-    let amount = size * ct_val;
-    match position_mode {
-        PositionModeEnum::Both => {
-            position_mode = match amount {
-                amount if amount > Decimal::ZERO => PositionModeEnum::Long,
-                amount if amount < Decimal::ZERO => PositionModeEnum::Short,
-                _ => { PositionModeEnum::Both }
-            }
-        }
-        _ => {}
-    }
-    Position {
-        symbol: format!{"{}_{}", coin, currency},
-        margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(position["entryPrice"].as_str().unwrap()).unwrap(),
-        profit: Decimal::from_str(position["unrealisedPnl"].as_str().unwrap()).unwrap(),
-        position_mode,
-        margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
-    }
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = from_str(&*res_data_str).unwrap();
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    };
-
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    debug!("format-order-start, bybit_handle");
-    debug!(?order);
-    let status = order["orderStatus"].as_str().unwrap_or("");
-    let text = order["orderLinkId"].as_str().unwrap_or("");
-    let size = Decimal::from_str(order["qty"].as_str().unwrap()).unwrap();
-    let right = Decimal::from_str(order["cumExecQty"].as_str().unwrap()).unwrap();
-    let right_val = Decimal::from_str(order["cumExecValue"].as_str().unwrap()).unwrap();
-    let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
-    let amount = size * ct_val;
-    let mut avg_price = Decimal::ZERO;
-    if right != Decimal::ZERO {
-        avg_price = right_val / right;
-    }
-    let deal_amount = right * ct_val;
-    let custom_status = if status == "Filled" || status == "Cancelled" { "REMOVE".to_string() } else if status == "New" { "NEW".to_string() } else {
-       "NULL".to_string()
-    };
-    let rst_order = Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("120 bybit_handle".to_string()),
-    };
-
-    debug!(?rst_order);
-    debug!("format-order-end, bybit_handle");
-    return rst_order;
-}
-// 处理特殊Ticket信息
-pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-    format_special_ticker(res_data_json, res_data.label)
-}
-
-pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let depth_asks = format_depth_items(data["a"].clone());
-    let depth_bids = format_depth_items(data["b"].clone());
-    let t = Decimal::from_str(&data["ts"].to_string()).unwrap();
-    let create_at = data["t"].as_i64().unwrap() * 1000;
-
-    let ap = depth_asks[0].price;
-    let bp = depth_bids[0].price;
-    let aq = depth_asks[0].amount;
-    let bq = depth_bids[0].amount;
-    let mp = (bp + ap) * dec!(0.5);
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: label,
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
-
-pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-    let mut depth_items: Vec<MarketOrder> = vec![];
-    for val in value.as_array().unwrap() {
-        let arr = val.as_array().unwrap();
-        depth_items.push(MarketOrder {
-            price: Decimal::from_str(arr[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(arr[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
+// use std::str::FromStr;
+// use rust_decimal::Decimal;
+// use rust_decimal_macros::dec;
+// use serde_json::{from_str, from_value};
+// use tokio::time::Instant;
+// use toml::Value;
+// use tracing::{debug, error};
+// use exchanges::response_base::ResponseData;
+// use global::trace_stack::TraceStack;
+// use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
+//
+// // 处理账号信息
+// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = from_str(&res_data_str).unwrap();
+//     format_account_info(res_data_json, symbol)
+// }
+//
+// pub fn format_account_info(data: Vec<serde_json::Value>, symbol: String) -> Account {
+//     let account = data.iter().find(| &item | item["accountType"] == "UNIFIED");
+//     match account {
+//         None => {
+//             error!("Bybit:格式化统一账户信息错误!\nformat_account_info: data={:?}", data);
+//             panic!("Bybit:格式化统一账户信息错误!\nformat_account_info: data={:?}", data)
+//         }
+//         Some(val) =>{
+//             let arr: Vec<Value> = serde_json::from_value(val["coin"].clone()).unwrap();
+//             let upper_str = symbol.to_uppercase();
+//             let symbol_array: Vec<&str> = upper_str.split("_").collect();
+//             let balance_info = arr.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[1]);
+//             match balance_info {
+//                 None => {
+//                     error!("Bybit:格式化usdt余额信息错误!\nformat_account_info: data={:?}", balance_info);
+//                     panic!("Bybit:格式化usdt余额信息错误!\nformat_account_info: data={:?}", balance_info)
+//                 }
+//                 Some(value) => {
+//                     let balance = Decimal::from_str(&value["walletBalance"].as_str().unwrap().to_string()).unwrap();
+//                     Account {
+//                         coin: symbol_array[1].to_string(),
+//                         balance,
+//                         available_balance: Decimal::ZERO,
+//                         frozen_balance: Decimal::ZERO,
+//                         stocks: Decimal::ZERO,
+//                         available_stocks: Decimal::ZERO,
+//                         frozen_stocks: Decimal::ZERO,
+//                     }
+//                 }
+//             }
+//         }
+//     }
+//
+//
+//
+// }
+//
+// // 处理position信息
+// pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
+//     let res_data_json: Vec<serde_json::Value> = from_str(&res_data.data).unwrap();
+//     res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect()
+// }
+//
+// pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Position {
+//     let position_idx: String = position["positionIdx"].to_string();
+//     let mut position_mode = match position_idx.as_str() {
+//         "0" => PositionModeEnum::Both,
+//         "1" => PositionModeEnum::Long,
+//         "2" => PositionModeEnum::Short,
+//         _ => {
+//             error!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
+//             panic!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
+//         }
+//     };
+//     let symbol_mapper =  position["symbol"].as_str().unwrap().to_string();
+//     let currency = "USDT";
+//     let coin = &symbol_mapper[..symbol_mapper.find(currency).unwrap_or(0)];
+//     let size_str: String = from_value(position["size"].clone()).unwrap();
+//     let size = Decimal::from_str(size_str.as_str()).unwrap();
+//     let amount = size * ct_val;
+//     match position_mode {
+//         PositionModeEnum::Both => {
+//             position_mode = match amount {
+//                 amount if amount > Decimal::ZERO => PositionModeEnum::Long,
+//                 amount if amount < Decimal::ZERO => PositionModeEnum::Short,
+//                 _ => { PositionModeEnum::Both }
+//             }
+//         }
+//         _ => {}
+//     }
+//     Position {
+//         symbol: format!{"{}_{}", coin, currency},
+//         margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
+//         amount,
+//         frozen_amount: Decimal::ZERO,
+//         price: Decimal::from_str(position["entryPrice"].as_str().unwrap()).unwrap(),
+//         profit: Decimal::from_str(position["unrealisedPnl"].as_str().unwrap()).unwrap(),
+//         position_mode,
+//         margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
+//     }
+// }
+//
+// // 处理order信息
+// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = from_str(&*res_data_str).unwrap();
+//     let mut order_info = Vec::new();
+//     for item in res_data_json.iter() {
+//         order_info.push(format_order_item(item.clone(), ct_val));
+//     };
+//
+//     SpecialOrder {
+//         name: res_data.label,
+//         order: order_info,
+//     }
+// }
+//
+// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
+//     debug!("format-order-start, bybit_handle");
+//     debug!(?order);
+//     let status = order["orderStatus"].as_str().unwrap_or("");
+//     let text = order["orderLinkId"].as_str().unwrap_or("");
+//     let size = Decimal::from_str(order["qty"].as_str().unwrap()).unwrap();
+//     let right = Decimal::from_str(order["cumExecQty"].as_str().unwrap()).unwrap();
+//     let right_val = Decimal::from_str(order["cumExecValue"].as_str().unwrap()).unwrap();
+//     let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
+//     let amount = size * ct_val;
+//     let mut avg_price = Decimal::ZERO;
+//     if right != Decimal::ZERO {
+//         avg_price = right_val / right;
+//     }
+//     let deal_amount = right * ct_val;
+//     let custom_status = if status == "Filled" || status == "Cancelled" { "REMOVE".to_string() } else if status == "New" { "NEW".to_string() } else {
+//        "NULL".to_string()
+//     };
+//     let rst_order = Order {
+//         id: format!("{}", order["orderId"].as_str().unwrap()),
+//         custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
+//         price,
+//         amount,
+//         deal_amount,
+//         avg_price,
+//         status: custom_status,
+//         order_type: "limit".to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("120 bybit_handle".to_string()),
+//     };
+//
+//     debug!(?rst_order);
+//     debug!("format-order-end, bybit_handle");
+//     return rst_order;
+// }
+// // 处理特殊Ticket信息
+// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
+//     let res_data_str = res_data.data;
+//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+//     format_special_ticker(res_data_json, res_data.label)
+// }
+//
+// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
+//     let depth_asks = format_depth_items(data["a"].clone());
+//     let depth_bids = format_depth_items(data["b"].clone());
+//     let t = Decimal::from_str(&data["ts"].to_string()).unwrap();
+//     let create_at = data["t"].as_i64().unwrap() * 1000;
+//
+//     let ap = depth_asks[0].price;
+//     let bp = depth_bids[0].price;
+//     let aq = depth_asks[0].amount;
+//     let bq = depth_bids[0].amount;
+//     let mp = (bp + ap) * dec!(0.5);
+//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
+//     let depth_info = vec![bp, bq, ap, aq];
+//     SpecialDepth {
+//         name: label,
+//         depth: depth_info,
+//         ticker: ticker_info,
+//         t,
+//         create_at,
+//     }
+// }
+//
+// pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
+//     let mut depth_items: Vec<MarketOrder> = vec![];
+//     for val in value.as_array().unwrap() {
+//         let arr = val.as_array().unwrap();
+//         depth_items.push(MarketOrder {
+//             price: Decimal::from_str(arr[0].as_str().unwrap()).unwrap(),
+//             amount: Decimal::from_str(arr[1].as_str().unwrap()).unwrap(),
+//         })
+//     }
+//     return depth_items;
+// }

+ 33 - 37
standard/src/exchange.rs

@@ -3,14 +3,14 @@ use std::io::Error;
 use tokio::sync::mpsc::Sender;
 use crate::{Order, Platform};
 use crate::binance_swap::BinanceSwap;
-use crate::binance_spot::BinanceSpot;
-use crate::gate_spot::GateSpot;
+// use crate::binance_spot::BinanceSpot;
+// use crate::gate_spot::GateSpot;
 use crate::gate_swap::GateSwap;
-use crate::kucoin_swap::KucoinSwap;
-use crate::bitget_spot::BitgetSpot;
-use crate::bybit_swap::BybitSwap;
-use crate::kucoin_spot::KucoinSpot;
-use crate::okx_swap::OkxSwap;
+// use crate::kucoin_swap::KucoinSwap;
+// use crate::bitget_spot::BitgetSpot;
+// use crate::bybit_swap::BybitSwap;
+// use crate::kucoin_spot::KucoinSpot;
+// use crate::okx_swap::OkxSwap;
 
 /// 交易所交易模式枚举
 /// - `BinanceSwap`: Binance交易所期货;
@@ -21,14 +21,14 @@ use crate::okx_swap::OkxSwap;
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ExchangeEnum {
     BinanceSwap,
-    BinanceSpot,
+    // BinanceSpot,
     GateSwap,
-    GateSpot,
-    KucoinSwap,
-    KucoinSpot,
-    OkxSwap,
-    BitgetSpot,
-    BybitSwap
+    // GateSpot,
+    // KucoinSwap,
+    // KucoinSpot,
+    // OkxSwap,
+    // BitgetSpot,
+    // BybitSwap
 }
 
 /// Exchange结构体
@@ -66,7 +66,7 @@ pub enum ExchangeEnum {
 /// 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 exchange = Exchange::new(ExchangeEnum::BinanceSwap, "BTC_USDT".to_string(), false, params, order_sender, error_sender);
+/// let exchange = Exchange::new(ExchangeEnum::GateSwap, "BTC_USDT".to_string(), false, params, order_sender, error_sender);
 #[derive(Debug, Clone)]
 pub struct Exchange;
 
@@ -79,28 +79,24 @@ impl Exchange {
             ExchangeEnum::GateSwap => {
                 Box::new(GateSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
             }
-            ExchangeEnum::GateSpot => {
-                Box::new(GateSpot::new(symbol, is_colo, params))
-            }
-            ExchangeEnum::KucoinSwap => {
-                Box::new(KucoinSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            ExchangeEnum::KucoinSpot =>{
-                Box::new(KucoinSpot::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            ExchangeEnum::OkxSwap => {
-                Box::new(OkxSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            ExchangeEnum::BitgetSpot => {
-                Box::new(BitgetSpot::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            ExchangeEnum::BybitSwap => {
-                Box::new(BybitSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            _ => {
-                // BinanceSpot
-                Box::new(BinanceSpot::new(symbol, is_colo, params))
-            }
+            // ExchangeEnum::GateSpot => {
+            //     Box::new(GateSpot::new(symbol, is_colo, params))
+            // }
+            // ExchangeEnum::KucoinSwap => {
+            //     Box::new(KucoinSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
+            // }
+            // ExchangeEnum::KucoinSpot =>{
+            //     Box::new(KucoinSpot::new(symbol, is_colo, params, order_sender, error_sender).await)
+            // }
+            // ExchangeEnum::OkxSwap => {
+            //     Box::new(OkxSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
+            // }
+            // ExchangeEnum::BitgetSpot => {
+            //     Box::new(BitgetSpot::new(symbol, is_colo, params, order_sender, error_sender).await)
+            // }
+            // ExchangeEnum::BybitSwap => {
+            //     Box::new(BybitSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
+            // }
         }
     }
 }

+ 7 - 11
standard/src/gate_handle.rs

@@ -2,6 +2,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::{debug, error};
 use exchanges::response_base::ResponseData;
@@ -12,12 +13,11 @@ use crate::handle_info::HandleSwapInfo;
 
 // 处理账号信息
 pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
+    let res_data_json = res_data.data.as_array().unwrap();
     format_account_info(res_data_json, symbol)
 }
 
-pub fn format_account_info(data: Vec<serde_json::Value>, symbol: String) -> Account {
+pub fn format_account_info(data: &Vec<Value>, symbol: String) -> Account {
     let symbol_upper = symbol.to_uppercase();
     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
     let balance_info = data.iter().find(|&item| item["text"].as_str().unwrap().contains(&symbol_upper));
@@ -43,8 +43,7 @@ pub fn format_account_info(data: Vec<serde_json::Value>, symbol: String) -> Acco
 
 // 处理position信息
 pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
+    let res_data_json = res_data.data.as_array().unwrap();
     res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect()
 }
 
@@ -84,8 +83,7 @@ pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Po
 
 // 处理order信息
 pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
+    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));
@@ -129,12 +127,10 @@ pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
 }
 // 处理特殊Ticket信息
 pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-    format_special_ticker(res_data_json, res_data.label)
+    format_special_ticker(res_data.data, res_data.label)
 }
 
-pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
+pub fn format_special_ticker(data: Value, label: String) -> SpecialDepth {
     let depth_asks = format_depth_items(data["asks"].clone());
     let depth_bids = format_depth_items(data["bids"].clone());
     let t = Decimal::from_str(&data["t"].to_string()).unwrap();

+ 113 - 113
standard/src/gate_spot.rs

@@ -1,113 +1,113 @@
-use std::collections::BTreeMap;
-use std::io::{Error, ErrorKind};
-use async_trait::async_trait;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use tracing::warn;
-use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand};
-use exchanges::gate_spot_rest::GateSpotRest;
-use global::trace_stack::TraceStack;
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct GateSpot {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: GateSpotRest,
-}
-
-impl GateSpot {
-    pub fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>) -> GateSpot {
-        GateSpot {
-            exchange: ExchangeEnum::GateSpot,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: GateSpotRest::new(is_colo, params.clone()),
-        }
-    }
-}
-
-#[async_trait]
-impl Platform for GateSpot {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    // 获取交易所模式
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::GateSpot
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-
-    fn get_self_market(&self) -> Market {
-        warn!("gate_spot:该交易所方法未实现");
-        return Market::new();
-    }
-
-    fn get_request_delays(&self) -> Vec<i64> {
-        warn!("gate_spot:该交易所方法未实现");
-        return vec![];
-    }
-
-    fn get_request_avg_delay(&self) -> Decimal {
-        warn!("gate_spot:该交易所方法未实现");
-        return dec!(0);
-    }
-
-    fn get_request_max_delay(&self) -> i64 {
-        warn!("gate_spot:该交易所方法未实现");
-        return 0;
-    }
-
-    async fn get_server_time(&mut self) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_account(&mut self) -> Result<Account, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_ticker_symbol(&mut self, _symbol: String) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_market(&mut self) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_market_symbol(&mut self, _symbol: String) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_order_detail(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
-
-    async fn command_order(&mut self, _order_command: OrderCommand, _trace_stack: TraceStack) { warn!("gate_spot:该交易所方法未实现"); }
-}
+// use std::collections::BTreeMap;
+// use std::io::{Error, ErrorKind};
+// use async_trait::async_trait;
+// use rust_decimal::Decimal;
+// use rust_decimal_macros::dec;
+// use tracing::warn;
+// use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand};
+// use exchanges::gate_spot_rest::GateSpotRest;
+// use global::trace_stack::TraceStack;
+//
+// #[allow(dead_code)]
+// #[derive(Clone)]
+// pub struct GateSpot {
+//     exchange: ExchangeEnum,
+//     symbol: String,
+//     is_colo: bool,
+//     params: BTreeMap<String, String>,
+//     request: GateSpotRest,
+// }
+//
+// impl GateSpot {
+//     pub fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>) -> GateSpot {
+//         GateSpot {
+//             exchange: ExchangeEnum::GateSpot,
+//             symbol: symbol.to_uppercase(),
+//             is_colo,
+//             params: params.clone(),
+//             request: GateSpotRest::new(is_colo, params.clone()),
+//         }
+//     }
+// }
+//
+// #[async_trait]
+// impl Platform for GateSpot {
+//     // 克隆方法
+//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
+//     // 获取交易所模式
+//     fn get_self_exchange(&self) -> ExchangeEnum {
+//         ExchangeEnum::GateSpot
+//     }
+//     // 获取交易对
+//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
+//     // 获取是否使用高速通道
+//     fn get_self_is_colo(&self) -> bool {
+//         self.is_colo
+//     }
+//     // 获取params信息
+//     fn get_self_params(&self) -> BTreeMap<String, String> {
+//         self.params.clone()
+//     }
+//
+//     fn get_self_market(&self) -> Market {
+//         warn!("gate_spot:该交易所方法未实现");
+//         return Market::new();
+//     }
+//
+//     fn get_request_delays(&self) -> Vec<i64> {
+//         warn!("gate_spot:该交易所方法未实现");
+//         return vec![];
+//     }
+//
+//     fn get_request_avg_delay(&self) -> Decimal {
+//         warn!("gate_spot:该交易所方法未实现");
+//         return dec!(0);
+//     }
+//
+//     fn get_request_max_delay(&self) -> i64 {
+//         warn!("gate_spot:该交易所方法未实现");
+//         return 0;
+//     }
+//
+//     async fn get_server_time(&mut self) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_account(&mut self) -> Result<Account, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_ticker(&mut self) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_ticker_symbol(&mut self, _symbol: String) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_market(&mut self) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_market_symbol(&mut self, _symbol: String) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_order_detail(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate_spot:该交易所方法未实现".to_string())) }
+//
+//     async fn command_order(&mut self, _order_command: OrderCommand, _trace_stack: TraceStack) { warn!("gate_spot:该交易所方法未实现"); }
+// }

+ 19 - 35
standard/src/gate_swap.rs

@@ -89,8 +89,7 @@ impl Platform for GateSwap {
     async fn get_server_time(&mut self) -> Result<String, Error> {
         let res_data = self.request.get_server_time().await;
         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 res_data_json: serde_json::Value = res_data.data;
             let result = res_data_json["server_time"].to_string();
             Ok(result)
         } else {
@@ -102,8 +101,7 @@ impl Platform for GateSwap {
         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
         let res_data = self.request.get_account(symbol_array[1].to_string().to_lowercase()).await;
         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 res_data_json: serde_json::Value = res_data.data;
             let balance = Decimal::from_str(res_data_json["total"].as_str().unwrap()).unwrap();
             let available_balance = Decimal::from_str(res_data_json["available"].as_str().unwrap()).unwrap();
             let frozen_balance = balance - available_balance;
@@ -132,8 +130,7 @@ impl Platform for GateSwap {
         let ct_val = self.market.ct_val;
         let res_data = self.request.get_position(symbol_array[1].to_string().to_lowercase(), self.symbol.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 res_data_json = res_data.data.as_array().unwrap();
             let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
             Ok(result)
         } else {
@@ -145,8 +142,7 @@ impl Platform for GateSwap {
         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
         let res_data = self.request.get_user_position(symbol_array[1].to_string().to_lowercase()).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 res_data_json = res_data.data.as_array().unwrap();
             let result = res_data_json.iter().map(|item| { format_position_item(item, Decimal::ONE) }).collect();
             Ok(result)
         } else {
@@ -158,8 +154,7 @@ impl Platform for GateSwap {
         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
         let res_data = self.request.get_ticker(symbol_array[1].to_string().to_lowercase()).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 res_data_json = res_data.data.as_array().unwrap();
             let ticker_info = res_data_json.iter().find(|item| item["contract"].as_str().unwrap() == self.symbol);
             match ticker_info {
                 None => {
@@ -189,8 +184,7 @@ impl Platform for GateSwap {
         let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
         let res_data = self.request.get_ticker(symbol_array[1].to_string().to_lowercase()).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 res_data_json = res_data.data.as_array().unwrap();
             let ticker_info = res_data_json.iter().find(|item| item["contract"].as_str().unwrap() == symbol_upper);
             match ticker_info {
                 None => {
@@ -219,8 +213,7 @@ impl Platform for GateSwap {
         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
         let res_data = self.request.get_market_details(symbol_array[1].to_string().to_lowercase()).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 res_data_json = res_data.data.as_array().unwrap();
             let market_info = res_data_json.iter().find(|item| item["name"].as_str().unwrap() == self.symbol);
             match market_info {
                 None => {
@@ -268,8 +261,7 @@ impl Platform for GateSwap {
         let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
         let res_data = self.request.get_market_details(symbol_array[1].to_string().to_lowercase()).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 res_data_json = res_data.data.as_array().unwrap();
             let market_info = res_data_json.iter().find(|item| item["name"].as_str().unwrap() == symbol_upper);
             match market_info {
                 None => {
@@ -319,8 +311,7 @@ impl Platform for GateSwap {
         let id = if order_id.eq("") { format!("t-{}", custom_id) } else { order_id.to_string() };
         let res_data = self.request.get_order_details(symbol_array[1].to_string().to_lowercase(), id).await;
         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 res_data_json: serde_json::Value = res_data.data;
             let result = format_order_item(res_data_json, ct_val);
             Ok(result)
         } else {
@@ -333,8 +324,7 @@ impl Platform for GateSwap {
         let ct_val = self.market.ct_val;
         let res_data = self.request.get_orders(symbol_array[1].to_string().to_lowercase(), status.to_string()).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 res_data_json = res_data.data.as_array().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| format_order_item(item.clone(), ct_val)).collect();
             Ok(result)
@@ -376,8 +366,7 @@ impl Platform for GateSwap {
         };
         let res_data = self.request.swap_order(symbol_array[1].to_string().to_lowercase(), params).await;
         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 res_data_json: serde_json::Value = res_data.data;
             let result = format_order_item(res_data_json, ct_val);
             Ok(result)
         } else {
@@ -418,8 +407,7 @@ impl Platform for GateSwap {
         };
         let res_data = self.request.swap_order(symbol_array[1].to_string().to_lowercase(), params).await;
         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 res_data_json: serde_json::Value = res_data.data;
             let result = format_order_item(res_data_json, ct_val);
             Ok(result)
         } else {
@@ -435,8 +423,7 @@ impl Platform for GateSwap {
         let id = if order_id.eq("") { format!("t-{}", custom_id) } else { order_id.to_string() };
         let res_data = self.request.cancel_order(settle, id.to_string()).await;
         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 res_data_json: serde_json::Value = res_data.data;
             let result = format_order_item(res_data_json, ct_val);
             Ok(result)
         } else {
@@ -449,8 +436,7 @@ impl Platform for GateSwap {
         let ct_val = self.market.ct_val;
         let res_data = self.request.cancel_orders(symbol_array[1].to_string().to_lowercase(), self.symbol.to_string()).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 res_data_json = res_data.data.as_array().unwrap();
             let result = res_data_json.iter().map(|item| format_order_item(item.clone(), ct_val)).collect();
             Ok(result)
         } else {
@@ -464,13 +450,11 @@ impl Platform for GateSwap {
         let orders_res_data = self.request.get_orders(symbol_array[1].to_string().to_lowercase(), "open".to_string()).await;
         if orders_res_data.code == "200" {
             let mut result = vec![];
-            let orders_res_data_str = &orders_res_data.data;
-            let orders_res_data_json: Vec<serde_json::Value> = serde_json::from_str(orders_res_data_str).unwrap();
+            let orders_res_data_json = orders_res_data.data.as_array().unwrap();
             for order in orders_res_data_json {
                 let cancel_res_data = self.request.cancel_orders(symbol_array[1].to_string().to_lowercase(), order["contract"].as_str().unwrap().to_string()).await;
                 if cancel_res_data.code == "200" {
-                    let cancel_res_data_str = &cancel_res_data.data;
-                    let cancel_res_data_json: Vec<serde_json::Value> = serde_json::from_str(cancel_res_data_str).unwrap();
+                    let cancel_res_data_json = cancel_res_data.data.as_array().unwrap();
                     for cancel in cancel_res_data_json {
                         result.push(format_order_item(cancel.clone(), ct_val))
                     };
@@ -491,7 +475,7 @@ impl Platform for GateSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let result = res_data_str.clone();
-            Ok(result)
+            Ok(result.to_string())
         } else {
             Err(Error::new(ErrorKind::Other, res_data.to_string()))
         }
@@ -504,7 +488,7 @@ impl Platform for GateSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let result = res_data_str.clone();
-            Ok(result)
+            Ok(result.to_string())
         } else {
             Err(Error::new(ErrorKind::Other, res_data.to_string()))
         }
@@ -519,7 +503,7 @@ impl Platform for GateSwap {
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
             let result = res_data_str.clone();
-            Ok(result)
+            Ok(result.to_string())
         } else {
             Err(Error::new(ErrorKind::Other, res_data.to_string()))
         }

+ 108 - 125
standard/src/handle_info.rs

@@ -7,7 +7,7 @@ use tracing::{error};
 use exchanges::response_base::ResponseData;
 use global::public_params;
 use crate::exchange::ExchangeEnum;
-use crate::{Account, binance_swap_handle, binance_spot_handle, bitget_spot_handle, gate_handle, kucoin_handle, kucoin_spot_handle, bybit_swap_handle, MarketOrder, okx_handle, Position, SpecialDepth, SpecialOrder, SpecialTicker};
+use crate::{Account, binance_swap_handle, gate_handle, MarketOrder, Position, SpecialDepth, SpecialOrder, SpecialTicker};
 
 #[allow(dead_code)]
 pub struct HandleSwapInfo;
@@ -25,28 +25,28 @@ impl HandleSwapInfo {
     // 处理账号信息
     pub fn handle_account_info(exchange: ExchangeEnum, res_data: ResponseData, symbol: String) -> Account {
         match exchange {
-            ExchangeEnum::BinanceSwap => {
-                error!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
-                panic!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
-            }
+            // ExchangeEnum::BinanceSwap => {
+            //     error!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
+            //     panic!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
+            // }
             ExchangeEnum::GateSwap => {
                 gate_handle::handle_account_info(res_data, symbol)
             }
-            ExchangeEnum::KucoinSwap => {
-                kucoin_handle::handle_account_info(res_data, symbol)
-            }
-            ExchangeEnum::KucoinSpot => {
-                kucoin_spot_handle::handle_account_info(res_data, symbol)
-            }
-            ExchangeEnum::OkxSwap => {
-                okx_handle::handle_account_info(res_data, symbol)
-            }
-            ExchangeEnum::BitgetSpot => {
-                bitget_spot_handle::handle_account_info(res_data, symbol)
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_account_info(res_data, symbol)
-            }
+            // ExchangeEnum::KucoinSwap => {
+            //     kucoin_handle::handle_account_info(res_data, symbol)
+            // }
+            // ExchangeEnum::KucoinSpot => {
+            //     kucoin_spot_handle::handle_account_info(res_data, symbol)
+            // }
+            // ExchangeEnum::OkxSwap => {
+            //     okx_handle::handle_account_info(res_data, symbol)
+            // }
+            // ExchangeEnum::BitgetSpot => {
+            //     bitget_spot_handle::handle_account_info(res_data, symbol)
+            // },
+            // ExchangeEnum::BybitSwap => {
+            //     bybit_swap_handle::handle_account_info(res_data, symbol)
+            // }
             _ => {
                 error!("未找到该交易所!handle_account_info: {:?}",exchange);
                 panic!("未找到该交易所!handle_account_info: {:?}", exchange);
@@ -56,34 +56,30 @@ impl HandleSwapInfo {
     // 处理特殊Ticket信息
     pub fn handle_special_ticker(exchange: ExchangeEnum, res_data: ResponseData) -> SpecialDepth {
         match exchange {
-            ExchangeEnum::BinanceSpot => {
-                binance_spot_handle::handle_special_ticker(res_data)
-            }
+            // ExchangeEnum::BinanceSpot => {
+            //     binance_spot_handle::handle_special_ticker(res_data)
+            // }
             ExchangeEnum::BinanceSwap => {
                 binance_swap_handle::handle_special_ticker(res_data)
             }
             ExchangeEnum::GateSwap => {
                 gate_handle::handle_special_ticker(res_data)
             }
-            ExchangeEnum::KucoinSwap => {
-                kucoin_handle::handle_special_ticker(res_data)
-            }
-            ExchangeEnum::KucoinSpot => {
-                kucoin_spot_handle::handle_special_ticker(res_data)
-            }
-            ExchangeEnum::OkxSwap => {
-                okx_handle::handle_special_ticker(res_data)
-            }
-            ExchangeEnum::BitgetSpot => {
-                bitget_spot_handle::handle_special_ticker(res_data)
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_special_ticker(res_data)
-            }
-            _ => {
-                error!("未找到该交易所!handle_special_ticker: {:?}",exchange);
-                panic!("未找到该交易所!handle_special_ticker: {:?}", exchange);
-            }
+            // ExchangeEnum::KucoinSwap => {
+            //     kucoin_handle::handle_special_ticker(res_data)
+            // }
+            // ExchangeEnum::KucoinSpot => {
+            //     kucoin_spot_handle::handle_special_ticker(res_data)
+            // }
+            // ExchangeEnum::OkxSwap => {
+            //     okx_handle::handle_special_ticker(res_data)
+            // }
+            // ExchangeEnum::BitgetSpot => {
+            //     bitget_spot_handle::handle_special_ticker(res_data)
+            // },
+            // ExchangeEnum::BybitSwap => {
+            //     bybit_swap_handle::handle_special_ticker(res_data)
+            // }
         }
     }
     // 处理position信息
@@ -96,27 +92,23 @@ impl HandleSwapInfo {
             ExchangeEnum::GateSwap => {
                 gate_handle::handle_position(res_data, ct_val)
             }
-            ExchangeEnum::KucoinSwap => {
-                kucoin_handle::handle_position(res_data, ct_val)
-            }
-            ExchangeEnum::KucoinSpot => {
-                error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-                panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-            }
-            ExchangeEnum::OkxSwap => {
-                okx_handle::handle_position(res_data, ct_val)
-            }
-            ExchangeEnum::BitgetSpot => {
-                error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-                panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_position(res_data, ct_val)
-            }
-            _ => {
-                error!("未找到该交易所!handle_position: {:?}",exchange);
-                panic!("未找到该交易所!handle_position: {:?}", exchange);
-            }
+            // ExchangeEnum::KucoinSwap => {
+            //     kucoin_handle::handle_position(res_data, ct_val)
+            // }
+            // ExchangeEnum::KucoinSpot => {
+            //     error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
+            //     panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
+            // }
+            // ExchangeEnum::OkxSwap => {
+            //     okx_handle::handle_position(res_data, ct_val)
+            // }
+            // ExchangeEnum::BitgetSpot => {
+            //     error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
+            //     panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
+            // },
+            // ExchangeEnum::BybitSwap => {
+            //     bybit_swap_handle::handle_position(res_data, ct_val)
+            // }
         }
     }
     // 处理订单信息
@@ -129,25 +121,21 @@ impl HandleSwapInfo {
             ExchangeEnum::GateSwap => {
                 gate_handle::handle_order(res_data, ct_val)
             }
-            ExchangeEnum::KucoinSwap => {
-                kucoin_handle::handle_order(res_data, ct_val)
-            }
-            ExchangeEnum::KucoinSpot => {
-                kucoin_spot_handle::handle_order(res_data, ct_val)
-            }
-            ExchangeEnum::OkxSwap => {
-                okx_handle::handle_order(res_data, ct_val)
-            }
-            ExchangeEnum::BitgetSpot => {
-                bitget_spot_handle::handle_order(res_data, ct_val)
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_order(res_data, ct_val)
-            }
-            _ => {
-                error!("未找到该交易所!handle_order: {:?}",exchange);
-                panic!("未找到该交易所!handle_order: {:?}", exchange);
-            }
+            // ExchangeEnum::KucoinSwap => {
+            //     kucoin_handle::handle_order(res_data, ct_val)
+            // }
+            // ExchangeEnum::KucoinSpot => {
+            //     kucoin_spot_handle::handle_order(res_data, ct_val)
+            // }
+            // ExchangeEnum::OkxSwap => {
+            //     okx_handle::handle_order(res_data, ct_val)
+            // }
+            // ExchangeEnum::BitgetSpot => {
+            //     bitget_spot_handle::handle_order(res_data, ct_val)
+            // },
+            // ExchangeEnum::BybitSwap => {
+            //     bybit_swap_handle::handle_order(res_data, ct_val)
+            // }
         }
     }
 
@@ -227,20 +215,19 @@ pub fn make_special_depth(label: String, depth_asks: &mut Vec<MarketOrder>, dept
     }
 }
 
-pub fn format_depth(exchange: ExchangeEnum, res_data: ResponseData) -> DepthParam{
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+pub fn format_depth(exchange: ExchangeEnum, res_data: ResponseData) -> DepthParam {
+    let res_data_json = res_data.data;
     let depth_asks: Vec<MarketOrder>;
     let depth_bids: Vec<MarketOrder>;
     let t: Decimal;
     let create_at: i64;
     match exchange {
-        ExchangeEnum::BinanceSpot => {
-            depth_asks = binance_swap_handle::format_depth_items(res_data_json["asks"].clone());
-            depth_bids = binance_swap_handle::format_depth_items(res_data_json["bids"].clone());
-            t = Decimal::from_str(&res_data_json["lastUpdateId"].to_string()).unwrap();
-            create_at = 0;
-        }
+        // ExchangeEnum::BinanceSpot => {
+        //     depth_asks = binance_swap_handle::format_depth_items(res_data_json["asks"].clone());
+        //     depth_bids = binance_swap_handle::format_depth_items(res_data_json["bids"].clone());
+        //     t = Decimal::from_str(&res_data_json["lastUpdateId"].to_string()).unwrap();
+        //     create_at = 0;
+        // }
         ExchangeEnum::BinanceSwap => {
             depth_asks = binance_swap_handle::format_depth_items(res_data_json["a"].clone());
             depth_bids = binance_swap_handle::format_depth_items(res_data_json["b"].clone());
@@ -254,40 +241,36 @@ pub fn format_depth(exchange: ExchangeEnum, res_data: ResponseData) -> DepthPara
             t = Decimal::from_str(&res_data_json["t"].to_string()).unwrap();
             create_at = res_data_json["t"].as_i64().unwrap() * 1000;
         }
-        ExchangeEnum::KucoinSwap => {
-            depth_asks = kucoin_handle::format_depth_items(res_data_json["asks"].clone());
-            depth_bids = kucoin_handle::format_depth_items(res_data_json["bids"].clone());
-            t = Decimal::from_str(&res_data_json["sequence"].to_string()).unwrap();
-            create_at = res_data_json["ts"].as_i64().unwrap() * 1000;
-        }
-        ExchangeEnum::KucoinSpot => {
-            depth_asks = kucoin_spot_handle::format_depth_items(res_data_json["asks"].clone());
-            depth_bids = kucoin_spot_handle::format_depth_items(res_data_json["bids"].clone());
-            t = Decimal::from_str(&res_data_json["timestamp"].to_string()).unwrap();
-            create_at = res_data_json["timestamp"].as_i64().unwrap() * 1000;
-        }
-        ExchangeEnum::OkxSwap => {
-            depth_asks = okx_handle::format_depth_items(res_data_json[0]["asks"].clone());
-            depth_bids = okx_handle::format_depth_items(res_data_json[0]["bids"].clone());
-            t = Decimal::from_str(&res_data_json[0]["seqId"].to_string()).unwrap();
-            create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-        }
-        ExchangeEnum::BitgetSpot => {
-            depth_asks = bitget_spot_handle::format_depth_items(res_data_json[0]["asks"].clone());
-            depth_bids = bitget_spot_handle::format_depth_items(res_data_json[0]["bids"].clone());
-            t = Decimal::from_str(res_data_json[0]["ts"].as_str().unwrap()).unwrap();
-            create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-        }
-        ExchangeEnum::BybitSwap => {
-            depth_asks = bybit_swap_handle::format_depth_items(res_data_json["a"].clone());
-            depth_bids = bybit_swap_handle::format_depth_items(res_data_json["b"].clone());
-            t = Decimal::from_i64(res_data.reach_time).unwrap();
-            create_at = res_data.reach_time * 1000;
-        }
-        _ => {
-            error!("未找到该交易所!handle_special_depth: {:?}",exchange);
-            panic!("未找到该交易所!handle_special_depth: {:?}", exchange);
-        }
+        // ExchangeEnum::KucoinSwap => {
+        //     depth_asks = kucoin_handle::format_depth_items(res_data_json["asks"].clone());
+        //     depth_bids = kucoin_handle::format_depth_items(res_data_json["bids"].clone());
+        //     t = Decimal::from_str(&res_data_json["sequence"].to_string()).unwrap();
+        //     create_at = res_data_json["ts"].as_i64().unwrap() * 1000;
+        // }
+        // ExchangeEnum::KucoinSpot => {
+        //     depth_asks = kucoin_spot_handle::format_depth_items(res_data_json["asks"].clone());
+        //     depth_bids = kucoin_spot_handle::format_depth_items(res_data_json["bids"].clone());
+        //     t = Decimal::from_str(&res_data_json["timestamp"].to_string()).unwrap();
+        //     create_at = res_data_json["timestamp"].as_i64().unwrap() * 1000;
+        // }
+        // ExchangeEnum::OkxSwap => {
+        //     depth_asks = okx_handle::format_depth_items(res_data_json[0]["asks"].clone());
+        //     depth_bids = okx_handle::format_depth_items(res_data_json[0]["bids"].clone());
+        //     t = Decimal::from_str(&res_data_json[0]["seqId"].to_string()).unwrap();
+        //     create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
+        // }
+        // ExchangeEnum::BitgetSpot => {
+        //     depth_asks = bitget_spot_handle::format_depth_items(res_data_json[0]["asks"].clone());
+        //     depth_bids = bitget_spot_handle::format_depth_items(res_data_json[0]["bids"].clone());
+        //     t = Decimal::from_str(res_data_json[0]["ts"].as_str().unwrap()).unwrap();
+        //     create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
+        // }
+        // ExchangeEnum::BybitSwap => {
+        //     depth_asks = bybit_swap_handle::format_depth_items(res_data_json["a"].clone());
+        //     depth_bids = bybit_swap_handle::format_depth_items(res_data_json["b"].clone());
+        //     t = Decimal::from_i64(res_data.reach_time).unwrap();
+        //     create_at = res_data.reach_time * 1000;
+        // }
     }
 
     DepthParam{

+ 161 - 161
standard/src/kucoin_handle.rs

@@ -1,161 +1,161 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use tokio::time::Instant;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker, utils};
-use crate::exchange::ExchangeEnum;
-use crate::handle_info::HandleSwapInfo;
-
-// 处理账号信息
-pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-    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)
-}
-
-pub fn format_account_info(data: serde_json::Value, symbol: String) -> Account {
-    let symbol_upper = symbol.to_uppercase();
-    let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-    let available_balance = Decimal::from_str(data["availableBalance"].as_str().unwrap()).unwrap();
-    let frozen_balance = Decimal::from_str(data["holdBalance"].as_str().unwrap()).unwrap();
-    let balance = available_balance + frozen_balance;
-    Account {
-        coin: symbol_array[1].to_string(),
-        balance,
-        available_balance,
-        frozen_balance,
-        stocks: Decimal::ZERO,
-        available_stocks: Decimal::ZERO,
-        frozen_stocks: Decimal::ZERO,
-    }
-}
-
-// 处理特殊Ticket信息
-pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-    format_special_ticker(res_data_json, res_data.label)
-}
-
-pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let bp = Decimal::from_str(&data["bestBidPrice"].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_f64(data["bestBidSize"].as_f64().unwrap()).unwrap();
-    let ap = Decimal::from_str(&data["bestAskPrice"].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_f64(data["bestAskSize"].as_f64().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_str(&data["sequence"].to_string()).unwrap();
-    let create_at = (data["ts"].as_f64().unwrap() / 1000.0).floor() as i64;
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: label,
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
-
-// 处理position信息
-pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
-    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_position_item(&res_data_json, ct_val);
-    return vec![result];
-}
-
-pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Position {
-    let symbol = position["symbol"].as_str().unwrap_or("");
-    let symbol_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, symbol);
-    let real_leverage = Decimal::from_f64(position["realLeverage"].as_f64().unwrap()).unwrap();
-    let currency = position["settleCurrency"].as_str().unwrap_or("");
-    let coin = &symbol_mapper[..symbol_mapper.find(currency).unwrap_or(0)];
-    let avg_entry_price = Decimal::from_f64(position["avgEntryPrice"].as_f64().unwrap()).unwrap();
-    let unrealised_pnl = Decimal::from_f64(position["unrealisedPnl"].as_f64().unwrap()).unwrap();
-    let pos_margin = Decimal::from_f64(position["posMargin"].as_f64().unwrap()).unwrap();
-
-    let current_qty = Decimal::from_f64(position["currentQty"].as_f64().unwrap()).unwrap();
-    let amount = current_qty * ct_val;
-    let position_mode = match amount {
-        amount if amount > Decimal::ZERO => PositionModeEnum::Long,
-        amount if amount < Decimal::ZERO => PositionModeEnum::Short,
-        _ => { PositionModeEnum::Both }
-    };
-    Position {
-        symbol: format!("{}_{}", coin, currency),
-        margin_level: real_leverage,
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: avg_entry_price,
-        profit: unrealised_pnl,
-        position_mode,
-        margin: pos_margin,
-    }
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = vec![serde_json::from_str(&*res_data_str).unwrap()];
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    }
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-// ws处理
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    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 type_ = order["type"].as_str().unwrap_or("");
-    let filled_size = Decimal::from_str(order["filledSize"].as_str().unwrap()).unwrap();
-
-    let avg_price = price;
-
-    let amount = size * ct_val;
-    let deal_amount = filled_size * ct_val;
-    let custom_status;
-    if ["filled", "canceled"].contains(&type_) {
-        custom_status = "REMOVE".to_string();
-    } else if ["open"].contains(&status) {
-        custom_status = "NEW".to_string();
-    } else {
-        custom_status = "NULL".to_string();
-    }
-    Order {
-        id: order["orderId"].as_str().unwrap().to_string(),
-        custom_id: order["clientOid"].as_str().unwrap_or("").to_string(),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["type"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("136 kucoin_handle".to_string()),
-    }
-}
-
-// 处理特殊深度数据
-pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-    HandleSwapInfo::handle_special_depth(ExchangeEnum::KucoinSwap, res_data)
-}
-
-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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_f64(value[1].as_f64().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
+// use std::str::FromStr;
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use rust_decimal_macros::dec;
+// use tokio::time::Instant;
+// use exchanges::response_base::ResponseData;
+// use global::trace_stack::TraceStack;
+// use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker, utils};
+// use crate::exchange::ExchangeEnum;
+// use crate::handle_info::HandleSwapInfo;
+//
+// // 处理账号信息
+// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
+//     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)
+// }
+//
+// pub fn format_account_info(data: serde_json::Value, symbol: String) -> Account {
+//     let symbol_upper = symbol.to_uppercase();
+//     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
+//     let available_balance = Decimal::from_str(data["availableBalance"].as_str().unwrap()).unwrap();
+//     let frozen_balance = Decimal::from_str(data["holdBalance"].as_str().unwrap()).unwrap();
+//     let balance = available_balance + frozen_balance;
+//     Account {
+//         coin: symbol_array[1].to_string(),
+//         balance,
+//         available_balance,
+//         frozen_balance,
+//         stocks: Decimal::ZERO,
+//         available_stocks: Decimal::ZERO,
+//         frozen_stocks: Decimal::ZERO,
+//     }
+// }
+//
+// // 处理特殊Ticket信息
+// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
+//     let res_data_str = res_data.data;
+//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+//     format_special_ticker(res_data_json, res_data.label)
+// }
+//
+// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
+//     let bp = Decimal::from_str(&data["bestBidPrice"].as_str().unwrap()).unwrap();
+//     let bq = Decimal::from_f64(data["bestBidSize"].as_f64().unwrap()).unwrap();
+//     let ap = Decimal::from_str(&data["bestAskPrice"].as_str().unwrap()).unwrap();
+//     let aq = Decimal::from_f64(data["bestAskSize"].as_f64().unwrap()).unwrap();
+//     let mp = (bp + ap) * dec!(0.5);
+//     let t = Decimal::from_str(&data["sequence"].to_string()).unwrap();
+//     let create_at = (data["ts"].as_f64().unwrap() / 1000.0).floor() as i64;
+//
+//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
+//     let depth_info = vec![bp, bq, ap, aq];
+//     SpecialDepth {
+//         name: label,
+//         depth: depth_info,
+//         ticker: ticker_info,
+//         t,
+//         create_at,
+//     }
+// }
+//
+// // 处理position信息
+// pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
+//     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_position_item(&res_data_json, ct_val);
+//     return vec![result];
+// }
+//
+// pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Position {
+//     let symbol = position["symbol"].as_str().unwrap_or("");
+//     let symbol_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, symbol);
+//     let real_leverage = Decimal::from_f64(position["realLeverage"].as_f64().unwrap()).unwrap();
+//     let currency = position["settleCurrency"].as_str().unwrap_or("");
+//     let coin = &symbol_mapper[..symbol_mapper.find(currency).unwrap_or(0)];
+//     let avg_entry_price = Decimal::from_f64(position["avgEntryPrice"].as_f64().unwrap()).unwrap();
+//     let unrealised_pnl = Decimal::from_f64(position["unrealisedPnl"].as_f64().unwrap()).unwrap();
+//     let pos_margin = Decimal::from_f64(position["posMargin"].as_f64().unwrap()).unwrap();
+//
+//     let current_qty = Decimal::from_f64(position["currentQty"].as_f64().unwrap()).unwrap();
+//     let amount = current_qty * ct_val;
+//     let position_mode = match amount {
+//         amount if amount > Decimal::ZERO => PositionModeEnum::Long,
+//         amount if amount < Decimal::ZERO => PositionModeEnum::Short,
+//         _ => { PositionModeEnum::Both }
+//     };
+//     Position {
+//         symbol: format!("{}_{}", coin, currency),
+//         margin_level: real_leverage,
+//         amount,
+//         frozen_amount: Decimal::ZERO,
+//         price: avg_entry_price,
+//         profit: unrealised_pnl,
+//         position_mode,
+//         margin: pos_margin,
+//     }
+// }
+//
+// // 处理order信息
+// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = vec![serde_json::from_str(&*res_data_str).unwrap()];
+//     let mut order_info = Vec::new();
+//     for item in res_data_json.iter() {
+//         order_info.push(format_order_item(item.clone(), ct_val));
+//     }
+//     SpecialOrder {
+//         name: res_data.label,
+//         order: order_info,
+//     }
+// }
+//
+// // ws处理
+// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
+//     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 type_ = order["type"].as_str().unwrap_or("");
+//     let filled_size = Decimal::from_str(order["filledSize"].as_str().unwrap()).unwrap();
+//
+//     let avg_price = price;
+//
+//     let amount = size * ct_val;
+//     let deal_amount = filled_size * ct_val;
+//     let custom_status;
+//     if ["filled", "canceled"].contains(&type_) {
+//         custom_status = "REMOVE".to_string();
+//     } else if ["open"].contains(&status) {
+//         custom_status = "NEW".to_string();
+//     } else {
+//         custom_status = "NULL".to_string();
+//     }
+//     Order {
+//         id: order["orderId"].as_str().unwrap().to_string(),
+//         custom_id: order["clientOid"].as_str().unwrap_or("").to_string(),
+//         price,
+//         amount,
+//         deal_amount,
+//         avg_price,
+//         status: custom_status,
+//         order_type: order["type"].as_str().unwrap().to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("136 kucoin_handle".to_string()),
+//     }
+// }
+//
+// // 处理特殊深度数据
+// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
+//     HandleSwapInfo::handle_special_depth(ExchangeEnum::KucoinSwap, res_data)
+// }
+//
+// 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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
+//             amount: Decimal::from_f64(value[1].as_f64().unwrap()).unwrap(),
+//         })
+//     }
+//     return depth_items;
+// }

+ 738 - 738
standard/src/kucoin_spot.rs

@@ -1,738 +1,738 @@
-use std::collections::{BTreeMap, HashMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use serde::{Deserialize, Serialize};
-use serde_json::json;
-use tokio::time::Instant;
-use tracing::error;
-use exchanges::kucoin_spot_rest::KucoinSpotRest;
-use global::trace_stack::TraceStack;
-use crate::exchange::ExchangeEnum;
-use crate::{Account, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
-
-/// Kucoin交易所账户信息请求数据结构
-/// 接口`"/api/v1/accounts"`;
-///
-/// struct SpotAccount
-/// - `id`: String, accountId
-/// - `currency`: String, 币种
-/// - `account_type`: String, 账户类型,资金(main)账户,现货交易(trade)账户,现货高频交易(trade_hf)账户,杠杆(margin)账户
-/// - `balance`: Decimal, 资金总额
-/// - `available`: Decimal, 可用余额
-/// - `holds`: Decimal, 冻结金额
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SpotAccount {
-    id: String,
-    currency: String,
-    account_type: String,
-    balance: Decimal,
-    available: Decimal,
-    holds: Decimal,
-}
-
-impl SpotAccount {
-    fn new() -> SpotAccount {
-        SpotAccount {
-            id: "".to_string(),
-            currency: "".to_string(),
-            account_type: "".to_string(),
-            balance: Default::default(),
-            available: Default::default(),
-            holds: Default::default(),
-        }
-    }
-}
-
-/// Kucoin交易所Ticker信息请求数据结构
-/// 接口`"/api/v1/market/orderbook/level1"`;
-///
-/// struct SpotTicker
-/// - `sequence`: String, 序列号
-/// - `price`: Decimal, 最新成交价格
-/// - `size`: Decimal, 最新成交数量
-/// - `best_ask`: Decimal, 最佳卖一价
-/// - `best_ask_size`: Decimal, 最佳卖一数量
-/// - `best_bid`: Decimal, 最佳买一价
-/// - `best_bid_size`: Decimal, 最佳买一数量
-/// - `time`: i64, 时间戳
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SpotTicker {
-    sequence: String,
-    price: Decimal,
-    size: Decimal,
-    best_ask: Decimal,
-    best_ask_size: Decimal,
-    best_bid: Decimal,
-    best_bid_size: Decimal,
-    time: i64,
-}
-
-/// Kucoin交易所Market信息请求数据结构
-/// 接口`"/api/v2/symbols"`;
-///
-/// struct SpotTicker
-/// - `symbol: String, 交易对唯一标识码
-/// - `name: String, 交易对名称
-/// - `base_currency: String, 商品货币
-/// - `quote_currency: String, 计价币种
-/// - `fee_currency: String, 交易计算手续费的币种
-/// - `market: String, 交易市场
-/// - `base_min_size: Decimal, 下单时size的最小值
-/// - `quote_min_size: Decimal, 下市价单,funds的最小值
-/// - `base_max_size: Decimal, 下单,size的最大值
-/// - `quote_max_size: Decimal, 下市价单,funds的最大值
-/// - `base_increment: Decimal, 数量增量,下单的size必须为数量增量的正整数倍
-/// - `quote_increment: Decimal, 市价单:资金增量,下单的funds必须为资金增量的正整数倍
-/// - `price_increment: Decimal, 限价单:价格增量,下单的price必须为价格增量的正整数倍
-/// - `price_limit_rate: Decimal, 价格保护阈值
-/// - `min_funds: Option<Decimal>, 最小交易金额
-/// - `is_margin_enabled: bool, 是否支持杠杆
-/// - `enable_trading: bool, 是否可以用于交易
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SpotMarket {
-    symbol: String,
-    name: String,
-    base_currency: String,
-    quote_currency: String,
-    fee_currency: String,
-    market: String,
-    base_min_size: Decimal,
-    quote_min_size: Decimal,
-    base_max_size: Decimal,
-    quote_max_size: Decimal,
-    base_increment: Decimal,
-    quote_increment: Decimal,
-    price_increment: Decimal,
-    price_limit_rate: Decimal,
-    min_funds: Option<Decimal>,
-    is_margin_enabled: bool,
-    enable_trading: bool,
-}
-
-/// Kucoin交易所Order信息请求数据结构
-/// 接口`"/api/v1/orders/{orderId}"`;
-///
-/// struct SpotOrder
-/// - `id`: String,
-/// - `symbol`: String,
-/// - `op_type`: String,
-/// - `order_type`: String,
-/// - `side`: String,
-/// - `price`: Decimal,
-/// - `size`: Decimal,
-/// - `funds`: Decimal,
-/// - `deal_funds`: Decimal,
-/// - `deal_size`: Decimal,
-/// - `fee`: Decimal,
-/// - `fee_currency`: String,
-/// - `stp`: String,
-/// - `stop`: String,
-/// - `stop_triggered`: bool,
-/// - `stop_price`: Decimal,
-/// - `time_in_force`: String,
-/// - `post_only`: bool,
-/// - `hidden`: bool,
-/// - `iceberg`: bool,
-/// - `visible_size`: Decimal,
-/// - `cancel_after`: i64,
-/// - `channel`: String,
-/// - `client_oid`: String,
-/// - `remark`: String,
-/// - `tags`: String,
-/// - `is_active`: bool,
-/// - `cancel_exist`: bool,
-/// - `created_at`: i64,
-/// - `trade_type`: String,
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SpotOrder {
-    id: String,
-    symbol: String,
-    op_type: String,
-    #[serde(rename = "type")]
-    order_type: String,
-    side: String,
-    price: Decimal,
-    size: Decimal,
-    funds: Decimal,
-    deal_funds: Decimal,
-    deal_size: Decimal,
-    fee: Decimal,
-    fee_currency: String,
-    stp: String,
-    stop: String,
-    stop_triggered: bool,
-    stop_price: Decimal,
-    time_in_force: String,
-    post_only: bool,
-    hidden: bool,
-    iceberg: bool,
-    visible_size: Decimal,
-    cancel_after: i64,
-    channel: String,
-    client_oid: String,
-    remark: String,
-    tags: String,
-    is_active: bool,
-    cancel_exist: bool,
-    created_at: i64,
-    trade_type: String,
-}
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct KucoinSpot {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: KucoinSpotRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl KucoinSpot {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> KucoinSpot {
-        let market = Market::new();
-        let mut kucoin_spot = KucoinSpot {
-            exchange: ExchangeEnum::KucoinSpot,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: KucoinSpotRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        kucoin_spot.market = KucoinSpot::get_market(&mut kucoin_spot).await.unwrap_or(kucoin_spot.market);
-
-        return kucoin_spot;
-    }
-}
-
-#[async_trait]
-impl Platform for KucoinSpot {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::KucoinSpot }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-    // 获取market信息
-    fn get_self_market(&self) -> Market { self.market.clone() }
-    // 获取请求时间
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-    // 获取请求平均时间
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-    // 获取请求最大时间
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-    // 获取服务器时间
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        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();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let coin_array: Vec<&str> = self.symbol.split("_").collect();
-        let res_data = self.request.get_accounts(coin_array[1].to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let balance_info_list: Vec<SpotAccount> = serde_json::from_str(res_data_str).unwrap();
-            let mut balance_info_default = SpotAccount::new();
-            balance_info_default.currency = coin_array[1].to_string();
-            let balance_info = balance_info_list.iter().find(|&item| item.currency == coin_array[1].to_string()).unwrap_or(&balance_info_default);
-            let mut stocks_info_default = SpotAccount::new();
-            stocks_info_default.currency = coin_array[0].to_string();
-            let stocks_info = balance_info_list.iter().find(|&item| item.currency == coin_array[0].to_string()).unwrap_or(&balance_info_default);
-            let result = Account {
-                coin: format!("{}_{}", balance_info.currency, stocks_info.currency),
-                balance: balance_info.available + balance_info.holds,
-                available_balance: balance_info.available,
-                frozen_balance: balance_info.holds,
-                stocks: stocks_info.available + stocks_info.holds,
-                available_stocks: stocks_info.available,
-                frozen_stocks: stocks_info.holds,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        let res_data = self.request.get_accounts("".to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let balance_info_list: Vec<SpotAccount> = serde_json::from_str(res_data_str).unwrap();
-            let result = balance_info_list.iter().map(|item| {
-                Account {
-                    coin: item.currency.to_string(),
-                    balance: item.available + item.holds,
-                    available_balance: item.available,
-                    frozen_balance: item.holds,
-                    stocks: Decimal::ZERO,
-                    available_stocks: Decimal::ZERO,
-                    frozen_stocks: Decimal::ZERO,
-                }
-            }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let res_data = self.request.get_level1(symbol_format).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let ticker_info: SpotTicker = serde_json::from_str(res_data_str).unwrap();
-            let result = Ticker {
-                time: ticker_info.time,
-                high: ticker_info.best_ask,
-                low: ticker_info.best_bid,
-                sell: ticker_info.best_ask,
-                buy: ticker_info.best_bid,
-                last: ticker_info.price,
-                volume: ticker_info.size,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "-");
-        let res_data = self.request.get_level1(symbol_format).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let ticker_info: SpotTicker = serde_json::from_str(res_data_str).unwrap();
-            let result = Ticker {
-                time: ticker_info.time,
-                high: ticker_info.best_ask,
-                low: ticker_info.best_bid,
-                sell: ticker_info.best_ask,
-                buy: ticker_info.best_bid,
-                last: ticker_info.price,
-                volume: ticker_info.size,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let res_data = self.request.get_symbols().await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let market_info_list: Vec<SpotMarket> = serde_json::from_str(res_data_str).unwrap();
-            let market_info = market_info_list.iter().find(|&item| item.symbol == symbol_format).unwrap();
-            let result = Market {
-                symbol: market_info.symbol.replace("-", "_"),
-                base_asset: market_info.base_currency.clone(),
-                quote_asset: market_info.quote_currency.clone(),
-                tick_size: market_info.price_increment,
-                amount_size: market_info.base_increment,
-                price_precision: Decimal::from_u32(market_info.price_increment.scale()).unwrap(),
-                amount_precision: Decimal::from_u32(market_info.base_increment.scale()).unwrap(),
-                min_qty: market_info.base_min_size,
-                max_qty: market_info.base_max_size,
-                min_notional: market_info.price_increment * market_info.base_min_size,
-                max_notional: market_info.price_increment * market_info.base_max_size,
-                ct_val: Decimal::ONE,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "-");
-        let res_data = self.request.get_symbols().await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let market_info_list: Vec<SpotMarket> = serde_json::from_str(res_data_str).unwrap();
-            let market_info = market_info_list.iter().find(|&item| item.symbol == symbol_format).unwrap();
-            let result = Market {
-                symbol: market_info.symbol.replace("-", "_"),
-                base_asset: market_info.base_currency.clone(),
-                quote_asset: market_info.quote_currency.clone(),
-                tick_size: market_info.price_increment,
-                amount_size: market_info.base_increment,
-                price_precision: Decimal::from_u32(market_info.price_increment.scale()).unwrap(),
-                amount_precision: Decimal::from_u32(market_info.base_increment.scale()).unwrap(),
-                min_qty: market_info.base_min_size,
-                max_qty: market_info.base_max_size,
-                min_notional: market_info.price_increment * market_info.base_min_size,
-                max_notional: market_info.price_increment * market_info.base_max_size,
-                ct_val: Decimal::ONE,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let res_data = if order_id != "" { self.request.get_order_by_order_id(order_id.to_string()).await } else { self.request.get_order_by_client_id(custom_id.to_string()).await };
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let result = format_order_item(res_data_str.clone());
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-        let res_data = self.request.get_order().await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let order_info_list: Vec<String> = serde_json::from_str(res_data_str).unwrap();
-            let result = order_info_list.iter().map(|item| format_order_item(item.clone())).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let mut params = json!({
-            "symbol": symbol_format.to_string(),
-            "clientOid": custom_id,
-            "price": price.to_string(),
-            "size": amount.to_string()
-        });
-        if price.eq(&Decimal::ZERO) {
-            params["type"] = json!("market");
-        } else {
-            params["type"] = json!("limit");
-        };
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.spot_order(params).await;
-        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 = Order {
-                id: res_data_json["orderId"].as_str().unwrap().to_string(),
-                custom_id: custom_id.to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("550 kucoin_spot".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "-");
-        let mut params = json!({
-            "symbol": symbol_format.to_string(),
-            "clientOid": custom_id,
-            "price": price.to_string(),
-            "size": amount * ct_val,
-        });
-        if price.eq(&Decimal::ZERO) {
-            params["type"] = json!("market");
-        } else {
-            params["type"] = json!("limit");
-        };
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.spot_order(params).await;
-        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 = Order {
-                id: res_data_json["orderId"].as_str().unwrap().to_string(),
-                custom_id: custom_id.to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("599 kucoin_spot".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let res_data = if order_id != "" { self.request.cancel_order_by_order_id(order_id.to_string()).await } else { self.request.cancel_order_by_client_id(custom_id.to_string()).await };
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-            let id = if order_id != "" { order_info["cancelledOrderIds"][0].as_str().unwrap().to_string() } else { order_info["cancelledOrderId"].as_str().unwrap().to_string() };
-            let custom_id = if order_id != "" { "".to_string() } else { order_info["clientOid"].as_str().unwrap().to_string() };
-            let result = Order {
-                id,
-                custom_id,
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "REMOVE".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("623 kucoin_spot".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let res_data = self.request.cancel_order_all(symbol_format).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-            let id_list = order_info["cancelledOrderIds"].as_array().unwrap();
-            let result = id_list.iter().map(|item| Order {
-                id: item["id"].as_str().unwrap().to_string(),
-                custom_id: "".to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "REMOVE".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("647 kucoin_spot".to_string()),
-            }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let res_data = self.request.cancel_order_all("".to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-            let id_list = order_info["cancelledOrderIds"].as_array().unwrap();
-            let result = id_list.iter().map(|item| Order {
-                id: item["id"].as_str().unwrap().to_string(),
-                custom_id: "".to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "REMOVE".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("670 kucoin_spot".to_string()),
-            }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-    }
-
-    async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-        let mut handles = vec![];
-        // 撤销订单
-        let cancel = order_command.cancel;
-        for item in cancel.keys() {
-            let mut self_clone = self.clone();
-            let cancel_clone = cancel.clone();
-            let item_clone = item.clone();
-            let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                match result {
-                    Ok(_) => {
-                        // result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        // 取消失败去查订单。
-                        let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                        match query_rst {
-                            Ok(order) => {
-                                result_sd.send(order).await.unwrap();
-                            }
-                            Err(_query_err) => {
-                                // error!(?_query_err);
-                                // error!("撤单失败,而且查单也失败了,bitget_spot,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                            }
-                        }
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 下单指令
-        let mut limits = HashMap::new();
-        limits.extend(order_command.limits_open);
-        limits.extend(order_command.limits_close);
-        for item in limits.keys() {
-            let mut self_clone = self.clone();
-            let limits_clone = limits.clone();
-            let item_clone = item.clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let ts = trace_stack.clone();
-
-            let handle = tokio::spawn(async move {
-                let value = limits_clone[&item_clone].clone();
-                let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-                let side = value.get(1).unwrap();
-                let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-                let cid = value.get(3).unwrap();
-
-                //  order_name: [数量,方向,价格,c_id]
-                let result = self_clone.take_order(cid, side, price, amount).await;
-                match result {
-                    Ok(mut result) => {
-                        // 记录此订单完成时间
-                        // ts.on_after_send();
-                        result.trace_stack = ts;
-
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        result_sd.send(err_order).await.unwrap();
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 检查订单指令
-        let check = order_command.check;
-        for item in check.keys() {
-            let mut self_clone = self.clone();
-            let check_clone = check.clone();
-            let item_clone = item.clone();
-            let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_order_item(data: String) -> Order {
-    let order_info: SpotOrder = serde_json::from_str(&data).unwrap();
-    Order {
-        id: order_info.id,
-        custom_id: order_info.client_oid,
-        price: order_info.price,
-        amount: order_info.size,
-        deal_amount: order_info.deal_size,
-        avg_price: order_info.deal_funds / order_info.deal_size,
-        status: if order_info.is_active { "NEW".to_string() } else { "REMOVE".to_string() },
-        order_type: order_info.order_type,
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("811 kucoin_spot".to_string()),
-    }
-}
+// use std::collections::{BTreeMap, HashMap};
+// use std::io::{Error, ErrorKind};
+// use std::str::FromStr;
+// use tokio::sync::mpsc::Sender;
+// use async_trait::async_trait;
+// use futures::stream::FuturesUnordered;
+// use futures::TryStreamExt;
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use serde::{Deserialize, Serialize};
+// use serde_json::json;
+// use tokio::time::Instant;
+// use tracing::error;
+// use exchanges::kucoin_spot_rest::KucoinSpotRest;
+// use global::trace_stack::TraceStack;
+// use crate::exchange::ExchangeEnum;
+// use crate::{Account, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
+//
+// /// Kucoin交易所账户信息请求数据结构
+// /// 接口`"/api/v1/accounts"`;
+// ///
+// /// struct SpotAccount
+// /// - `id`: String, accountId
+// /// - `currency`: String, 币种
+// /// - `account_type`: String, 账户类型,资金(main)账户,现货交易(trade)账户,现货高频交易(trade_hf)账户,杠杆(margin)账户
+// /// - `balance`: Decimal, 资金总额
+// /// - `available`: Decimal, 可用余额
+// /// - `holds`: Decimal, 冻结金额
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SpotAccount {
+//     id: String,
+//     currency: String,
+//     account_type: String,
+//     balance: Decimal,
+//     available: Decimal,
+//     holds: Decimal,
+// }
+//
+// impl SpotAccount {
+//     fn new() -> SpotAccount {
+//         SpotAccount {
+//             id: "".to_string(),
+//             currency: "".to_string(),
+//             account_type: "".to_string(),
+//             balance: Default::default(),
+//             available: Default::default(),
+//             holds: Default::default(),
+//         }
+//     }
+// }
+//
+// /// Kucoin交易所Ticker信息请求数据结构
+// /// 接口`"/api/v1/market/orderbook/level1"`;
+// ///
+// /// struct SpotTicker
+// /// - `sequence`: String, 序列号
+// /// - `price`: Decimal, 最新成交价格
+// /// - `size`: Decimal, 最新成交数量
+// /// - `best_ask`: Decimal, 最佳卖一价
+// /// - `best_ask_size`: Decimal, 最佳卖一数量
+// /// - `best_bid`: Decimal, 最佳买一价
+// /// - `best_bid_size`: Decimal, 最佳买一数量
+// /// - `time`: i64, 时间戳
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SpotTicker {
+//     sequence: String,
+//     price: Decimal,
+//     size: Decimal,
+//     best_ask: Decimal,
+//     best_ask_size: Decimal,
+//     best_bid: Decimal,
+//     best_bid_size: Decimal,
+//     time: i64,
+// }
+//
+// /// Kucoin交易所Market信息请求数据结构
+// /// 接口`"/api/v2/symbols"`;
+// ///
+// /// struct SpotTicker
+// /// - `symbol: String, 交易对唯一标识码
+// /// - `name: String, 交易对名称
+// /// - `base_currency: String, 商品货币
+// /// - `quote_currency: String, 计价币种
+// /// - `fee_currency: String, 交易计算手续费的币种
+// /// - `market: String, 交易市场
+// /// - `base_min_size: Decimal, 下单时size的最小值
+// /// - `quote_min_size: Decimal, 下市价单,funds的最小值
+// /// - `base_max_size: Decimal, 下单,size的最大值
+// /// - `quote_max_size: Decimal, 下市价单,funds的最大值
+// /// - `base_increment: Decimal, 数量增量,下单的size必须为数量增量的正整数倍
+// /// - `quote_increment: Decimal, 市价单:资金增量,下单的funds必须为资金增量的正整数倍
+// /// - `price_increment: Decimal, 限价单:价格增量,下单的price必须为价格增量的正整数倍
+// /// - `price_limit_rate: Decimal, 价格保护阈值
+// /// - `min_funds: Option<Decimal>, 最小交易金额
+// /// - `is_margin_enabled: bool, 是否支持杠杆
+// /// - `enable_trading: bool, 是否可以用于交易
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SpotMarket {
+//     symbol: String,
+//     name: String,
+//     base_currency: String,
+//     quote_currency: String,
+//     fee_currency: String,
+//     market: String,
+//     base_min_size: Decimal,
+//     quote_min_size: Decimal,
+//     base_max_size: Decimal,
+//     quote_max_size: Decimal,
+//     base_increment: Decimal,
+//     quote_increment: Decimal,
+//     price_increment: Decimal,
+//     price_limit_rate: Decimal,
+//     min_funds: Option<Decimal>,
+//     is_margin_enabled: bool,
+//     enable_trading: bool,
+// }
+//
+// /// Kucoin交易所Order信息请求数据结构
+// /// 接口`"/api/v1/orders/{orderId}"`;
+// ///
+// /// struct SpotOrder
+// /// - `id`: String,
+// /// - `symbol`: String,
+// /// - `op_type`: String,
+// /// - `order_type`: String,
+// /// - `side`: String,
+// /// - `price`: Decimal,
+// /// - `size`: Decimal,
+// /// - `funds`: Decimal,
+// /// - `deal_funds`: Decimal,
+// /// - `deal_size`: Decimal,
+// /// - `fee`: Decimal,
+// /// - `fee_currency`: String,
+// /// - `stp`: String,
+// /// - `stop`: String,
+// /// - `stop_triggered`: bool,
+// /// - `stop_price`: Decimal,
+// /// - `time_in_force`: String,
+// /// - `post_only`: bool,
+// /// - `hidden`: bool,
+// /// - `iceberg`: bool,
+// /// - `visible_size`: Decimal,
+// /// - `cancel_after`: i64,
+// /// - `channel`: String,
+// /// - `client_oid`: String,
+// /// - `remark`: String,
+// /// - `tags`: String,
+// /// - `is_active`: bool,
+// /// - `cancel_exist`: bool,
+// /// - `created_at`: i64,
+// /// - `trade_type`: String,
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SpotOrder {
+//     id: String,
+//     symbol: String,
+//     op_type: String,
+//     #[serde(rename = "type")]
+//     order_type: String,
+//     side: String,
+//     price: Decimal,
+//     size: Decimal,
+//     funds: Decimal,
+//     deal_funds: Decimal,
+//     deal_size: Decimal,
+//     fee: Decimal,
+//     fee_currency: String,
+//     stp: String,
+//     stop: String,
+//     stop_triggered: bool,
+//     stop_price: Decimal,
+//     time_in_force: String,
+//     post_only: bool,
+//     hidden: bool,
+//     iceberg: bool,
+//     visible_size: Decimal,
+//     cancel_after: i64,
+//     channel: String,
+//     client_oid: String,
+//     remark: String,
+//     tags: String,
+//     is_active: bool,
+//     cancel_exist: bool,
+//     created_at: i64,
+//     trade_type: String,
+// }
+//
+// #[allow(dead_code)]
+// #[derive(Clone)]
+// pub struct KucoinSpot {
+//     exchange: ExchangeEnum,
+//     symbol: String,
+//     is_colo: bool,
+//     params: BTreeMap<String, String>,
+//     request: KucoinSpotRest,
+//     market: Market,
+//     order_sender: Sender<Order>,
+//     error_sender: Sender<Error>,
+// }
+//
+// impl KucoinSpot {
+//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> KucoinSpot {
+//         let market = Market::new();
+//         let mut kucoin_spot = KucoinSpot {
+//             exchange: ExchangeEnum::KucoinSpot,
+//             symbol: symbol.to_uppercase(),
+//             is_colo,
+//             params: params.clone(),
+//             request: KucoinSpotRest::new(is_colo, params.clone()),
+//             market,
+//             order_sender,
+//             error_sender,
+//         };
+//         kucoin_spot.market = KucoinSpot::get_market(&mut kucoin_spot).await.unwrap_or(kucoin_spot.market);
+//
+//         return kucoin_spot;
+//     }
+// }
+//
+// #[async_trait]
+// impl Platform for KucoinSpot {
+//     // 克隆方法
+//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
+//     fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::KucoinSpot }
+//     // 获取交易对
+//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
+//     // 获取是否使用高速通道
+//     fn get_self_is_colo(&self) -> bool {
+//         self.is_colo
+//     }
+//     // 获取params信息
+//     fn get_self_params(&self) -> BTreeMap<String, String> {
+//         self.params.clone()
+//     }
+//     // 获取market信息
+//     fn get_self_market(&self) -> Market { self.market.clone() }
+//     // 获取请求时间
+//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
+//     // 获取请求平均时间
+//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
+//     // 获取请求最大时间
+//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
+//     // 获取服务器时间
+//     async fn get_server_time(&mut self) -> Result<String, Error> {
+//         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();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_account(&mut self) -> Result<Account, Error> {
+//         let coin_array: Vec<&str> = self.symbol.split("_").collect();
+//         let res_data = self.request.get_accounts(coin_array[1].to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let balance_info_list: Vec<SpotAccount> = serde_json::from_str(res_data_str).unwrap();
+//             let mut balance_info_default = SpotAccount::new();
+//             balance_info_default.currency = coin_array[1].to_string();
+//             let balance_info = balance_info_list.iter().find(|&item| item.currency == coin_array[1].to_string()).unwrap_or(&balance_info_default);
+//             let mut stocks_info_default = SpotAccount::new();
+//             stocks_info_default.currency = coin_array[0].to_string();
+//             let stocks_info = balance_info_list.iter().find(|&item| item.currency == coin_array[0].to_string()).unwrap_or(&balance_info_default);
+//             let result = Account {
+//                 coin: format!("{}_{}", balance_info.currency, stocks_info.currency),
+//                 balance: balance_info.available + balance_info.holds,
+//                 available_balance: balance_info.available,
+//                 frozen_balance: balance_info.holds,
+//                 stocks: stocks_info.available + stocks_info.holds,
+//                 available_stocks: stocks_info.available,
+//                 frozen_stocks: stocks_info.holds,
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
+//         let res_data = self.request.get_accounts("".to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let balance_info_list: Vec<SpotAccount> = serde_json::from_str(res_data_str).unwrap();
+//             let result = balance_info_list.iter().map(|item| {
+//                 Account {
+//                     coin: item.currency.to_string(),
+//                     balance: item.available + item.holds,
+//                     available_balance: item.available,
+//                     frozen_balance: item.holds,
+//                     stocks: Decimal::ZERO,
+//                     available_stocks: Decimal::ZERO,
+//                     frozen_stocks: Decimal::ZERO,
+//                 }
+//             }).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
+//         let res_data = self.request.get_level1(symbol_format).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let ticker_info: SpotTicker = serde_json::from_str(res_data_str).unwrap();
+//             let result = Ticker {
+//                 time: ticker_info.time,
+//                 high: ticker_info.best_ask,
+//                 low: ticker_info.best_bid,
+//                 sell: ticker_info.best_ask,
+//                 buy: ticker_info.best_bid,
+//                 last: ticker_info.price,
+//                 volume: ticker_info.size,
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
+//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
+//         let res_data = self.request.get_level1(symbol_format).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let ticker_info: SpotTicker = serde_json::from_str(res_data_str).unwrap();
+//             let result = Ticker {
+//                 time: ticker_info.time,
+//                 high: ticker_info.best_ask,
+//                 low: ticker_info.best_bid,
+//                 sell: ticker_info.best_ask,
+//                 buy: ticker_info.best_bid,
+//                 last: ticker_info.price,
+//                 volume: ticker_info.size,
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market(&mut self) -> Result<Market, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
+//         let res_data = self.request.get_symbols().await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let market_info_list: Vec<SpotMarket> = serde_json::from_str(res_data_str).unwrap();
+//             let market_info = market_info_list.iter().find(|&item| item.symbol == symbol_format).unwrap();
+//             let result = Market {
+//                 symbol: market_info.symbol.replace("-", "_"),
+//                 base_asset: market_info.base_currency.clone(),
+//                 quote_asset: market_info.quote_currency.clone(),
+//                 tick_size: market_info.price_increment,
+//                 amount_size: market_info.base_increment,
+//                 price_precision: Decimal::from_u32(market_info.price_increment.scale()).unwrap(),
+//                 amount_precision: Decimal::from_u32(market_info.base_increment.scale()).unwrap(),
+//                 min_qty: market_info.base_min_size,
+//                 max_qty: market_info.base_max_size,
+//                 min_notional: market_info.price_increment * market_info.base_min_size,
+//                 max_notional: market_info.price_increment * market_info.base_max_size,
+//                 ct_val: Decimal::ONE,
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
+//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
+//         let res_data = self.request.get_symbols().await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let market_info_list: Vec<SpotMarket> = serde_json::from_str(res_data_str).unwrap();
+//             let market_info = market_info_list.iter().find(|&item| item.symbol == symbol_format).unwrap();
+//             let result = Market {
+//                 symbol: market_info.symbol.replace("-", "_"),
+//                 base_asset: market_info.base_currency.clone(),
+//                 quote_asset: market_info.quote_currency.clone(),
+//                 tick_size: market_info.price_increment,
+//                 amount_size: market_info.base_increment,
+//                 price_precision: Decimal::from_u32(market_info.price_increment.scale()).unwrap(),
+//                 amount_precision: Decimal::from_u32(market_info.base_increment.scale()).unwrap(),
+//                 min_qty: market_info.base_min_size,
+//                 max_qty: market_info.base_max_size,
+//                 min_notional: market_info.price_increment * market_info.base_min_size,
+//                 max_notional: market_info.price_increment * market_info.base_max_size,
+//                 ct_val: Decimal::ONE,
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let res_data = if order_id != "" { self.request.get_order_by_order_id(order_id.to_string()).await } else { self.request.get_order_by_client_id(custom_id.to_string()).await };
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let result = format_order_item(res_data_str.clone());
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
+//         let res_data = self.request.get_order().await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let order_info_list: Vec<String> = serde_json::from_str(res_data_str).unwrap();
+//             let result = order_info_list.iter().map(|item| format_order_item(item.clone())).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
+//         let mut params = json!({
+//             "symbol": symbol_format.to_string(),
+//             "clientOid": custom_id,
+//             "price": price.to_string(),
+//             "size": amount.to_string()
+//         });
+//         if price.eq(&Decimal::ZERO) {
+//             params["type"] = json!("market");
+//         } else {
+//             params["type"] = json!("limit");
+//         };
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.spot_order(params).await;
+//         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 = Order {
+//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
+//                 custom_id: custom_id.to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("550 kucoin_spot".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
+//         let mut params = json!({
+//             "symbol": symbol_format.to_string(),
+//             "clientOid": custom_id,
+//             "price": price.to_string(),
+//             "size": amount * ct_val,
+//         });
+//         if price.eq(&Decimal::ZERO) {
+//             params["type"] = json!("market");
+//         } else {
+//             params["type"] = json!("limit");
+//         };
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.spot_order(params).await;
+//         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 = Order {
+//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
+//                 custom_id: custom_id.to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("599 kucoin_spot".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let res_data = if order_id != "" { self.request.cancel_order_by_order_id(order_id.to_string()).await } else { self.request.cancel_order_by_client_id(custom_id.to_string()).await };
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
+//             let id = if order_id != "" { order_info["cancelledOrderIds"][0].as_str().unwrap().to_string() } else { order_info["cancelledOrderId"].as_str().unwrap().to_string() };
+//             let custom_id = if order_id != "" { "".to_string() } else { order_info["clientOid"].as_str().unwrap().to_string() };
+//             let result = Order {
+//                 id,
+//                 custom_id,
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "REMOVE".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("623 kucoin_spot".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
+//         let res_data = self.request.cancel_order_all(symbol_format).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
+//             let id_list = order_info["cancelledOrderIds"].as_array().unwrap();
+//             let result = id_list.iter().map(|item| Order {
+//                 id: item["id"].as_str().unwrap().to_string(),
+//                 custom_id: "".to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "REMOVE".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("647 kucoin_spot".to_string()),
+//             }).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
+//         let res_data = self.request.cancel_order_all("".to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
+//             let id_list = order_info["cancelledOrderIds"].as_array().unwrap();
+//             let result = id_list.iter().map(|item| Order {
+//                 id: item["id"].as_str().unwrap().to_string(),
+//                 custom_id: "".to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "REMOVE".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("670 kucoin_spot".to_string()),
+//             }).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
+//         let mut handles = vec![];
+//         // 撤销订单
+//         let cancel = order_command.cancel;
+//         for item in cancel.keys() {
+//             let mut self_clone = self.clone();
+//             let cancel_clone = cancel.clone();
+//             let item_clone = item.clone();
+//             let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.cancel_order(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(_) => {
+//                         // result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         // 取消失败去查订单。
+//                         let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                         match query_rst {
+//                             Ok(order) => {
+//                                 result_sd.send(order).await.unwrap();
+//                             }
+//                             Err(_query_err) => {
+//                                 // error!(?_query_err);
+//                                 // error!("撤单失败,而且查单也失败了,bitget_spot,oid={}, cid={}。", order_id.clone(), custom_id.clone());
+//                             }
+//                         }
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 下单指令
+//         let mut limits = HashMap::new();
+//         limits.extend(order_command.limits_open);
+//         limits.extend(order_command.limits_close);
+//         for item in limits.keys() {
+//             let mut self_clone = self.clone();
+//             let limits_clone = limits.clone();
+//             let item_clone = item.clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let ts = trace_stack.clone();
+//
+//             let handle = tokio::spawn(async move {
+//                 let value = limits_clone[&item_clone].clone();
+//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
+//                 let side = value.get(1).unwrap();
+//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
+//                 let cid = value.get(3).unwrap();
+//
+//                 //  order_name: [数量,方向,价格,c_id]
+//                 let result = self_clone.take_order(cid, side, price, amount).await;
+//                 match result {
+//                     Ok(mut result) => {
+//                         // 记录此订单完成时间
+//                         // ts.on_after_send();
+//                         result.trace_stack = ts;
+//
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         let mut err_order = Order::new();
+//                         err_order.custom_id = cid.clone();
+//                         err_order.status = "REMOVE".to_string();
+//
+//                         result_sd.send(err_order).await.unwrap();
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 检查订单指令
+//         let check = order_command.check;
+//         for item in check.keys() {
+//             let mut self_clone = self.clone();
+//             let check_clone = check.clone();
+//             let item_clone = item.clone();
+//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(result) => {
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//
+//         let futures = FuturesUnordered::from_iter(handles);
+//         let _: Result<Vec<_>, _> = futures.try_collect().await;
+//     }
+// }
+//
+// pub fn format_order_item(data: String) -> Order {
+//     let order_info: SpotOrder = serde_json::from_str(&data).unwrap();
+//     Order {
+//         id: order_info.id,
+//         custom_id: order_info.client_oid,
+//         price: order_info.price,
+//         amount: order_info.size,
+//         deal_amount: order_info.deal_size,
+//         avg_price: order_info.deal_funds / order_info.deal_size,
+//         status: if order_info.is_active { "NEW".to_string() } else { "REMOVE".to_string() },
+//         order_type: order_info.order_type,
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("811 kucoin_spot".to_string()),
+//     }
+// }

+ 136 - 136
standard/src/kucoin_spot_handle.rs

@@ -1,136 +1,136 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use serde_json::json;
-use tokio::time::Instant;
-use tracing::trace;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, SpecialDepth, SpecialOrder, SpecialTicker};
-use crate::exchange::ExchangeEnum;
-use crate::handle_info::HandleSwapInfo;
-
-// 处理账号信息
-pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-    let symbol_upper = symbol.to_uppercase();
-    let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
-    let balance_info_default = json!({"available":"0","currency": symbol_array[1],"hold":"0"});
-    let balance_info = res_data_json.iter().find(|&item| item["currency"].as_str().unwrap() == symbol_array[1]).unwrap_or(&balance_info_default);
-    let stocks_info_default = json!({"available":"0","currency": symbol_array[0],"hold":"0"});
-    let stocks_info = res_data_json.iter().find(|&item| item["currency"].as_str().unwrap() == symbol_array[0]).unwrap_or(&stocks_info_default);
-    format_account_info(balance_info.clone(), stocks_info.clone())
-}
-
-pub fn format_account_info(balance_data: serde_json::Value, stocks_data: serde_json::Value) -> Account {
-    let balance_coin = balance_data["currency"].as_str().unwrap().to_string().to_uppercase();
-    let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-    let frozen_balance = Decimal::from_str(balance_data["hold"].as_str().unwrap()).unwrap();
-    let balance = available_balance + frozen_balance;
-
-    let stocks_coin = stocks_data["currency"].as_str().unwrap().to_string().to_uppercase();
-    let available_stocks = Decimal::from_str(stocks_data["available"].as_str().unwrap()).unwrap();
-    let frozen_stocks = Decimal::from_str(stocks_data["hold"].as_str().unwrap()).unwrap();
-    let stocks = available_stocks + frozen_stocks;
-
-    Account {
-        coin: format!("{}_{}", stocks_coin, balance_coin),
-        balance,
-        available_balance,
-        frozen_balance,
-        stocks,
-        available_stocks,
-        frozen_stocks,
-    }
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    }
-    trace!(?order_info);
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-// 处理订单信息
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    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 = Decimal::from_str(order["filledSize"].as_str().unwrap()).unwrap();
-
-    let avg_price = price;
-
-    let amount = size * ct_val;
-    let deal_amount = filled_size * ct_val;
-    let custom_status = if ["done"].contains(&status) {
-        "REMOVE".to_string()
-    } else if ["open", "match", "update"].contains(&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id: order["orderId"].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["orderType"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("89 bitget_spot_handle".to_string()),
-    }
-}
-
-// 处理特殊深度数据
-pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-    HandleSwapInfo::handle_special_depth(ExchangeEnum::KucoinSpot, res_data)
-}
-
-// 格式化深度信息
-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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
-
-// 处理特殊Ticker信息
-pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-    format_special_ticker(res_data_json, res_data.label)
-}
-
-pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let bp = Decimal::from_str(data["bestBid"].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_str(data["bestBidSize"].as_str().unwrap()).unwrap();
-    let ap = Decimal::from_str(data["bestAsk"].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_str(data["bestAskSize"].as_str().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_str(data["sequence"].as_str().unwrap()).unwrap();
-    let create_at = data["time"].as_i64().unwrap() * 1000;
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: label,
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
+// use std::str::FromStr;
+// use rust_decimal::Decimal;
+// use rust_decimal_macros::dec;
+// use serde_json::json;
+// use tokio::time::Instant;
+// use tracing::trace;
+// use exchanges::response_base::ResponseData;
+// use global::trace_stack::TraceStack;
+// use crate::{Account, MarketOrder, Order, SpecialDepth, SpecialOrder, SpecialTicker};
+// use crate::exchange::ExchangeEnum;
+// use crate::handle_info::HandleSwapInfo;
+//
+// // 处理账号信息
+// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
+//     let symbol_upper = symbol.to_uppercase();
+//     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
+//     let balance_info_default = json!({"available":"0","currency": symbol_array[1],"hold":"0"});
+//     let balance_info = res_data_json.iter().find(|&item| item["currency"].as_str().unwrap() == symbol_array[1]).unwrap_or(&balance_info_default);
+//     let stocks_info_default = json!({"available":"0","currency": symbol_array[0],"hold":"0"});
+//     let stocks_info = res_data_json.iter().find(|&item| item["currency"].as_str().unwrap() == symbol_array[0]).unwrap_or(&stocks_info_default);
+//     format_account_info(balance_info.clone(), stocks_info.clone())
+// }
+//
+// pub fn format_account_info(balance_data: serde_json::Value, stocks_data: serde_json::Value) -> Account {
+//     let balance_coin = balance_data["currency"].as_str().unwrap().to_string().to_uppercase();
+//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
+//     let frozen_balance = Decimal::from_str(balance_data["hold"].as_str().unwrap()).unwrap();
+//     let balance = available_balance + frozen_balance;
+//
+//     let stocks_coin = stocks_data["currency"].as_str().unwrap().to_string().to_uppercase();
+//     let available_stocks = Decimal::from_str(stocks_data["available"].as_str().unwrap()).unwrap();
+//     let frozen_stocks = Decimal::from_str(stocks_data["hold"].as_str().unwrap()).unwrap();
+//     let stocks = available_stocks + frozen_stocks;
+//
+//     Account {
+//         coin: format!("{}_{}", stocks_coin, balance_coin),
+//         balance,
+//         available_balance,
+//         frozen_balance,
+//         stocks,
+//         available_stocks,
+//         frozen_stocks,
+//     }
+// }
+//
+// // 处理order信息
+// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
+//     let mut order_info = Vec::new();
+//     for item in res_data_json.iter() {
+//         order_info.push(format_order_item(item.clone(), ct_val));
+//     }
+//     trace!(?order_info);
+//     SpecialOrder {
+//         name: res_data.label,
+//         order: order_info,
+//     }
+// }
+//
+// // 处理订单信息
+// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
+//     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 = Decimal::from_str(order["filledSize"].as_str().unwrap()).unwrap();
+//
+//     let avg_price = price;
+//
+//     let amount = size * ct_val;
+//     let deal_amount = filled_size * ct_val;
+//     let custom_status = if ["done"].contains(&status) {
+//         "REMOVE".to_string()
+//     } else if ["open", "match", "update"].contains(&status) {
+//         "NEW".to_string()
+//     } else {
+//         "NULL".to_string()
+//     };
+//     Order {
+//         id: order["orderId"].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["orderType"].as_str().unwrap().to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("89 bitget_spot_handle".to_string()),
+//     }
+// }
+//
+// // 处理特殊深度数据
+// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
+//     HandleSwapInfo::handle_special_depth(ExchangeEnum::KucoinSpot, res_data)
+// }
+//
+// // 格式化深度信息
+// 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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
+//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
+//         })
+//     }
+//     return depth_items;
+// }
+//
+// // 处理特殊Ticker信息
+// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
+//     let res_data_str = res_data.data;
+//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+//     format_special_ticker(res_data_json, res_data.label)
+// }
+//
+// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
+//     let bp = Decimal::from_str(data["bestBid"].as_str().unwrap()).unwrap();
+//     let bq = Decimal::from_str(data["bestBidSize"].as_str().unwrap()).unwrap();
+//     let ap = Decimal::from_str(data["bestAsk"].as_str().unwrap()).unwrap();
+//     let aq = Decimal::from_str(data["bestAskSize"].as_str().unwrap()).unwrap();
+//     let mp = (bp + ap) * dec!(0.5);
+//     let t = Decimal::from_str(data["sequence"].as_str().unwrap()).unwrap();
+//     let create_at = data["time"].as_i64().unwrap() * 1000;
+//
+//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
+//     let depth_info = vec![bp, bq, ap, aq];
+//     SpecialDepth {
+//         name: label,
+//         depth: depth_info,
+//         ticker: ticker_info,
+//         t,
+//         create_at,
+//     }
+// }

+ 685 - 685
standard/src/kucoin_swap.rs

@@ -1,685 +1,685 @@
-use std::collections::{BTreeMap, HashMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
-use rust_decimal_macros::dec;
-use serde_json::json;
-use tokio::time::Instant;
-use tracing::{error, info};
-use exchanges::kucoin_swap_rest::KucoinSwapRest;
-use global::trace_stack::TraceStack;
-use crate::exchange::ExchangeEnum;
-use crate::{Account, kucoin_handle, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct KucoinSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: KucoinSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl KucoinSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> KucoinSwap {
-        let market = Market::new();
-        let mut kucoin_swap = KucoinSwap {
-            exchange: ExchangeEnum::KucoinSwap,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: KucoinSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        kucoin_swap.market = KucoinSwap::get_market(&mut kucoin_swap).await.unwrap_or(kucoin_swap.market);
-
-        // 开启自动追加保证金
-        let append_rst = kucoin_swap.set_auto_deposit_status(true).await;
-
-        info!("设置自动追加保证金:{:?}", append_rst.unwrap());
-
-        return kucoin_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for KucoinSwap {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::KucoinSwap
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-    // 获取market信息
-    fn get_self_market(&self) -> Market { self.market.clone() }
-    // 获取请求时间
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-    // 获取请求平均时间
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-    // 获取请求最大时间
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-    // 获取服务器时间
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        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();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取账号信息
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
-        let res_data = self.request.get_account(symbol_array[1].to_string()).await;
-        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 = Decimal::from_f64(res_data_json["marginBalance"].as_f64().unwrap()).unwrap();
-            let available_balance = Decimal::from_f64(res_data_json["availableBalance"].as_f64().unwrap()).unwrap();
-            let frozen_balance = balance - available_balance;
-            let result = Account {
-                coin: symbol_array[1].to_string(),
-                balance,
-                available_balance,
-                frozen_balance,
-                stocks: Decimal::ZERO,
-                available_stocks: Decimal::ZERO,
-                frozen_stocks: Decimal::ZERO,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_position(symbol_format).await;
-        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_position_item(&res_data_json, ct_val);
-            Ok(vec![result])
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
-        let res_data = self.request.get_positions(symbol_array[1].to_string()).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 mut result = Vec::new();
-            for item in res_data_json.iter() {
-                result.push(kucoin_handle::format_position_item(item, Decimal::ONE))
-            }
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.get_ticker(symbol_format).await;
-        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 ticker_info = res_data_json;
-            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(),
-                volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper, ""));
-        let res_data = self.request.get_ticker(symbol_format).await;
-        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 ticker_info = res_data_json;
-            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(),
-                volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.get_market_details().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 market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
-            match market_info {
-                None => {
-                    error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
-                    let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
-                    let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
-                    let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
-                    let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
-                    let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
-                    let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
-                        base_asset: base_asset_mapper,
-                        quote_asset: quote_asset_mapper,
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
-                        min_notional,
-                        max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.get_market_details().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 market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
-            match market_info {
-                None => {
-                    error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
-                    let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
-                    let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
-                    let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
-                    let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
-                    let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
-                    let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
-                        base_asset: base_asset_mapper,
-                        quote_asset: quote_asset_mapper,
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
-                        min_notional,
-                        max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_orders_details(order_id.to_string(), custom_id.to_string()).await;
-        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 = format_order_item(res_data_json, ct_val);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let ct_val = self.market.ct_val;
-        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: 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(), ct_val)).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let ct_val = self.market.ct_val;
-        let mut params = json!({
-            "clientOid": custom_id,
-            "symbol": symbol_format,
-            "leverage": "10",
-            "reduceOnly":false,
-            "price": price.to_string(),
-        });
-        params["type"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
-        let size = (amount / ct_val).floor();
-        params["size"] = json!(size);
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-
-        let res_data = self.request.swap_order(params).await;
-        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 id = res_data_json["orderId"].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id: custom_id.to_string(),
-                price,
-                amount,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("359 kucoin_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let mut params = json!({
-            "clientOid": custom_id,
-            "symbol": symbol_format,
-            "leverage": "10",
-            "reduceOnly":false,
-            "price": price.to_string(),
-        });
-        let size = (amount / ct_val).floor();
-        params["size"] = json!(size);
-        if price.eq(&Decimal::ZERO){
-            params["type"] = json!("market");
-        }
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-
-        let res_data = self.request.swap_order(params).await;
-        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 id = res_data_json["orderId"].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id: custom_id.to_string(),
-                price,
-                amount,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("408 kucoin_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let res_data = self.request.cancel_order(order_id.to_string(), custom_id.to_string()).await;
-        if order_id == "" {
-            error!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id);
-            panic!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id)
-        }
-        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 cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
-            let id = cancel_ids[0].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id: custom_id.to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "REMOVE".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("436 kucoin_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.cancel_orders(symbol_format).await;
-        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 cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
-            let result = cancel_ids.iter().map(|item|
-                Order {
-                    id: item.as_str().unwrap().to_string(),
-                    custom_id: "".to_string(),
-                    price: Decimal::ZERO,
-                    amount: Decimal::ZERO,
-                    deal_amount: Decimal::ZERO,
-                    avg_price: Decimal::ZERO,
-                    status: "REMOVE".to_string(),
-                    order_type: "".to_string(),
-                    trace_stack: TraceStack::new(0, Instant::now()).on_special("461 kucoin_swap".to_string()),
-                }
-            ).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let res_data = self.request.cancel_order_all().await;
-        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 cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
-            let result = cancel_ids.iter().map(|item|
-                Order {
-                    id: item.as_str().unwrap().to_string(),
-                    custom_id: "".to_string(),
-                    price: Decimal::ZERO,
-                    amount: Decimal::ZERO,
-                    deal_amount: Decimal::ZERO,
-                    avg_price: Decimal::ZERO,
-                    status: "REMOVE".to_string(),
-                    order_type: "".to_string(),
-                    trace_stack: TraceStack::new(0, Instant::now()).on_special("486 kucoin_swap".to_string()),
-                }
-            ).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_auto_deposit_status(&mut self, status: bool) -> Result<String, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.auto_deposit_status(symbol_format, status).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.to_string()))
-        }
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    // 指令下单
-    async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-        let mut handles = vec![];
-        // 撤销订单
-        let cancel = order_command.cancel;
-        for item in cancel.keys() {
-            let mut self_clone = self.clone();
-            let cancel_clone = cancel.clone();
-            let item_clone = item.clone();
-            let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                if order_id != "" {
-                    let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                    match result {
-                        Ok(_) => {
-                            // result_sd.send(result).await.unwrap();
-                        }
-                        Err(error) => {
-                            // 取消失败去查订单。
-                            let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                            match query_rst {
-                                Ok(order) => {
-                                    result_sd.send(order).await.unwrap();
-                                }
-                                Err(_query_err) => {
-                                    // error!(?_query_err);
-                                    // error!("撤单失败,而且查单也失败了,kucoin_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                                }
-                            }
-                            err_sd.send(error).await.unwrap();
-                        }
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 下单指令
-        let mut limits = HashMap::new();
-        limits.extend(order_command.limits_open);
-        limits.extend(order_command.limits_close);
-        for item in limits.keys() {
-            let mut self_clone = self.clone();
-            let limits_clone = limits.clone();
-            let item_clone = item.clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let ts = trace_stack.clone();
-
-            let handle = tokio::spawn(async move {
-                let value = limits_clone[&item_clone].clone();
-                // info!(?value);
-                // info!("{}", ts.to_string());
-                let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-                let side = value.get(1).unwrap();
-                let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-                let cid = value.get(3).unwrap();
-
-                //  order_name: [数量,方向,价格,c_id]
-                let result = self_clone.take_order(cid, side, price, amount).await;
-                match result {
-                    Ok(mut result) => {
-                        // ts.on_after_send();
-                        result.trace_stack = ts.clone();
-
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        result_sd.send(err_order).await.unwrap();
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // if limits.len() > 0 {
-        //     info!("");
-        // }
-        // 检查订单指令
-        let check = order_command.check;
-        for item in check.keys() {
-            let mut self_clone = self.clone();
-            let check_clone = check.clone();
-            let item_clone = item.clone();
-            let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
-    let size = Decimal::from_f64(order["size"].as_f64().unwrap()).unwrap();
-    let status = order["status"].as_str().unwrap_or("");
-    let filled_size = Decimal::from_f64(order["filledSize"].as_f64().unwrap()).unwrap();
-    let filled_value = Decimal::from_str(order["filledValue"].as_str().unwrap()).unwrap();
-
-    let amount = size * ct_val;
-    let deal_amount = filled_size * ct_val;
-    let avg_price = if deal_amount.is_zero() { Decimal::ZERO } else { filled_value / deal_amount };
-    let custom_status;
-    if ["cancelled", "closed", "finished"].contains(&status) {
-        custom_status = "REMOVE".to_string();
-    } else if status == "open" {
-        custom_status = "NEW".to_string();
-    } else {
-        custom_status = "NULL".to_string();
-    };
-    Order {
-        id: order["id"].as_str().unwrap().to_string(),
-        custom_id: order["clientOid"].as_str().unwrap_or("").to_string(),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["type"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("655 kucoin_swap".to_string()),
-    }
-}
+// use std::collections::{BTreeMap, HashMap};
+// use std::io::{Error, ErrorKind};
+// use std::str::FromStr;
+// use tokio::sync::mpsc::Sender;
+// use async_trait::async_trait;
+// use futures::stream::FuturesUnordered;
+// use futures::TryStreamExt;
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
+// use rust_decimal_macros::dec;
+// use serde_json::json;
+// use tokio::time::Instant;
+// use tracing::{error, info};
+// use exchanges::kucoin_swap_rest::KucoinSwapRest;
+// use global::trace_stack::TraceStack;
+// use crate::exchange::ExchangeEnum;
+// use crate::{Account, kucoin_handle, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
+//
+// #[allow(dead_code)]
+// #[derive(Clone)]
+// pub struct KucoinSwap {
+//     exchange: ExchangeEnum,
+//     symbol: String,
+//     is_colo: bool,
+//     params: BTreeMap<String, String>,
+//     request: KucoinSwapRest,
+//     market: Market,
+//     order_sender: Sender<Order>,
+//     error_sender: Sender<Error>,
+// }
+//
+// impl KucoinSwap {
+//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> KucoinSwap {
+//         let market = Market::new();
+//         let mut kucoin_swap = KucoinSwap {
+//             exchange: ExchangeEnum::KucoinSwap,
+//             symbol: symbol.to_uppercase(),
+//             is_colo,
+//             params: params.clone(),
+//             request: KucoinSwapRest::new(is_colo, params.clone()),
+//             market,
+//             order_sender,
+//             error_sender,
+//         };
+//         kucoin_swap.market = KucoinSwap::get_market(&mut kucoin_swap).await.unwrap_or(kucoin_swap.market);
+//
+//         // 开启自动追加保证金
+//         let append_rst = kucoin_swap.set_auto_deposit_status(true).await;
+//
+//         info!("设置自动追加保证金:{:?}", append_rst.unwrap());
+//
+//         return kucoin_swap;
+//     }
+// }
+//
+// #[async_trait]
+// impl Platform for KucoinSwap {
+//     // 克隆方法
+//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
+//     fn get_self_exchange(&self) -> ExchangeEnum {
+//         ExchangeEnum::KucoinSwap
+//     }
+//     // 获取交易对
+//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
+//     // 获取是否使用高速通道
+//     fn get_self_is_colo(&self) -> bool {
+//         self.is_colo
+//     }
+//     // 获取params信息
+//     fn get_self_params(&self) -> BTreeMap<String, String> {
+//         self.params.clone()
+//     }
+//     // 获取market信息
+//     fn get_self_market(&self) -> Market { self.market.clone() }
+//     // 获取请求时间
+//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
+//     // 获取请求平均时间
+//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
+//     // 获取请求最大时间
+//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
+//     // 获取服务器时间
+//     async fn get_server_time(&mut self) -> Result<String, Error> {
+//         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();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//     // 获取账号信息
+//     async fn get_account(&mut self) -> Result<Account, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
+//         let res_data = self.request.get_account(symbol_array[1].to_string()).await;
+//         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 = Decimal::from_f64(res_data_json["marginBalance"].as_f64().unwrap()).unwrap();
+//             let available_balance = Decimal::from_f64(res_data_json["availableBalance"].as_f64().unwrap()).unwrap();
+//             let frozen_balance = balance - available_balance;
+//             let result = Account {
+//                 coin: symbol_array[1].to_string(),
+//                 balance,
+//                 available_balance,
+//                 frozen_balance,
+//                 stocks: Decimal::ZERO,
+//                 available_stocks: Decimal::ZERO,
+//                 frozen_stocks: Decimal::ZERO,
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_position(symbol_format).await;
+//         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_position_item(&res_data_json, ct_val);
+//             Ok(vec![result])
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
+//         let res_data = self.request.get_positions(symbol_array[1].to_string()).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 mut result = Vec::new();
+//             for item in res_data_json.iter() {
+//                 result.push(kucoin_handle::format_position_item(item, Decimal::ONE))
+//             }
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let res_data = self.request.get_ticker(symbol_format).await;
+//         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 ticker_info = res_data_json;
+//             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(),
+//                 volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper, ""));
+//         let res_data = self.request.get_ticker(symbol_format).await;
+//         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 ticker_info = res_data_json;
+//             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(),
+//                 volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market(&mut self) -> Result<Market, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let res_data = self.request.get_market_details().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 market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
+//             match market_info {
+//                 None => {
+//                     error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
+//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//                 }
+//                 Some(value) => {
+//                     let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
+//                     let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
+//                     let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
+//                     let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
+//                     let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
+//                     let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
+//                     let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
+//
+//                     let amount_size = min_qty * ct_val;
+//                     let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
+//                     let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
+//                     let min_notional = min_qty * ct_val;
+//
+//                     let result = Market {
+//                         symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
+//                         base_asset: base_asset_mapper,
+//                         quote_asset: quote_asset_mapper,
+//                         tick_size,
+//                         amount_size,
+//                         price_precision,
+//                         amount_precision,
+//                         min_qty,
+//                         max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
+//                         min_notional,
+//                         max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
+//                         ct_val,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let res_data = self.request.get_market_details().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 market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
+//             match market_info {
+//                 None => {
+//                     error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
+//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//                 }
+//                 Some(value) => {
+//                     let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
+//                     let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
+//                     let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
+//                     let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
+//                     let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
+//                     let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
+//                     let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
+//
+//                     let amount_size = min_qty * ct_val;
+//                     let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
+//                     let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
+//                     let min_notional = min_qty * ct_val;
+//
+//                     let result = Market {
+//                         symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
+//                         base_asset: base_asset_mapper,
+//                         quote_asset: quote_asset_mapper,
+//                         tick_size,
+//                         amount_size,
+//                         price_precision,
+//                         amount_precision,
+//                         min_qty,
+//                         max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
+//                         min_notional,
+//                         max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
+//                         ct_val,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_orders_details(order_id.to_string(), custom_id.to_string()).await;
+//         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 = format_order_item(res_data_json, ct_val);
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let ct_val = self.market.ct_val;
+//         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: 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(), ct_val)).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let ct_val = self.market.ct_val;
+//         let mut params = json!({
+//             "clientOid": custom_id,
+//             "symbol": symbol_format,
+//             "leverage": "10",
+//             "reduceOnly":false,
+//             "price": price.to_string(),
+//         });
+//         params["type"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
+//         let size = (amount / ct_val).floor();
+//         params["size"] = json!(size);
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//
+//         let res_data = self.request.swap_order(params).await;
+//         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 id = res_data_json["orderId"].as_str().unwrap().to_string();
+//             let result = Order {
+//                 id,
+//                 custom_id: custom_id.to_string(),
+//                 price,
+//                 amount,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("359 kucoin_swap".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let mut params = json!({
+//             "clientOid": custom_id,
+//             "symbol": symbol_format,
+//             "leverage": "10",
+//             "reduceOnly":false,
+//             "price": price.to_string(),
+//         });
+//         let size = (amount / ct_val).floor();
+//         params["size"] = json!(size);
+//         if price.eq(&Decimal::ZERO){
+//             params["type"] = json!("market");
+//         }
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//
+//         let res_data = self.request.swap_order(params).await;
+//         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 id = res_data_json["orderId"].as_str().unwrap().to_string();
+//             let result = Order {
+//                 id,
+//                 custom_id: custom_id.to_string(),
+//                 price,
+//                 amount,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("408 kucoin_swap".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let res_data = self.request.cancel_order(order_id.to_string(), custom_id.to_string()).await;
+//         if order_id == "" {
+//             error!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id);
+//             panic!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id)
+//         }
+//         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 cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
+//             let id = cancel_ids[0].as_str().unwrap().to_string();
+//             let result = Order {
+//                 id,
+//                 custom_id: custom_id.to_string(),
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "REMOVE".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("436 kucoin_swap".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let res_data = self.request.cancel_orders(symbol_format).await;
+//         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 cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
+//             let result = cancel_ids.iter().map(|item|
+//                 Order {
+//                     id: item.as_str().unwrap().to_string(),
+//                     custom_id: "".to_string(),
+//                     price: Decimal::ZERO,
+//                     amount: Decimal::ZERO,
+//                     deal_amount: Decimal::ZERO,
+//                     avg_price: Decimal::ZERO,
+//                     status: "REMOVE".to_string(),
+//                     order_type: "".to_string(),
+//                     trace_stack: TraceStack::new(0, Instant::now()).on_special("461 kucoin_swap".to_string()),
+//                 }
+//             ).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
+//         let res_data = self.request.cancel_order_all().await;
+//         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 cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
+//             let result = cancel_ids.iter().map(|item|
+//                 Order {
+//                     id: item.as_str().unwrap().to_string(),
+//                     custom_id: "".to_string(),
+//                     price: Decimal::ZERO,
+//                     amount: Decimal::ZERO,
+//                     deal_amount: Decimal::ZERO,
+//                     avg_price: Decimal::ZERO,
+//                     status: "REMOVE".to_string(),
+//                     order_type: "".to_string(),
+//                     trace_stack: TraceStack::new(0, Instant::now()).on_special("486 kucoin_swap".to_string()),
+//                 }
+//             ).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_auto_deposit_status(&mut self, status: bool) -> Result<String, Error> {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let res_data = self.request.auto_deposit_status(symbol_format, status).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.to_string()))
+//         }
+//     }
+//
+//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     // 指令下单
+//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
+//         let mut handles = vec![];
+//         // 撤销订单
+//         let cancel = order_command.cancel;
+//         for item in cancel.keys() {
+//             let mut self_clone = self.clone();
+//             let cancel_clone = cancel.clone();
+//             let item_clone = item.clone();
+//             let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 if order_id != "" {
+//                     let result = self_clone.cancel_order(&order_id, &custom_id).await;
+//                     match result {
+//                         Ok(_) => {
+//                             // result_sd.send(result).await.unwrap();
+//                         }
+//                         Err(error) => {
+//                             // 取消失败去查订单。
+//                             let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                             match query_rst {
+//                                 Ok(order) => {
+//                                     result_sd.send(order).await.unwrap();
+//                                 }
+//                                 Err(_query_err) => {
+//                                     // error!(?_query_err);
+//                                     // error!("撤单失败,而且查单也失败了,kucoin_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
+//                                 }
+//                             }
+//                             err_sd.send(error).await.unwrap();
+//                         }
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 下单指令
+//         let mut limits = HashMap::new();
+//         limits.extend(order_command.limits_open);
+//         limits.extend(order_command.limits_close);
+//         for item in limits.keys() {
+//             let mut self_clone = self.clone();
+//             let limits_clone = limits.clone();
+//             let item_clone = item.clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let ts = trace_stack.clone();
+//
+//             let handle = tokio::spawn(async move {
+//                 let value = limits_clone[&item_clone].clone();
+//                 // info!(?value);
+//                 // info!("{}", ts.to_string());
+//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
+//                 let side = value.get(1).unwrap();
+//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
+//                 let cid = value.get(3).unwrap();
+//
+//                 //  order_name: [数量,方向,价格,c_id]
+//                 let result = self_clone.take_order(cid, side, price, amount).await;
+//                 match result {
+//                     Ok(mut result) => {
+//                         // ts.on_after_send();
+//                         result.trace_stack = ts.clone();
+//
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         let mut err_order = Order::new();
+//                         err_order.custom_id = cid.clone();
+//                         err_order.status = "REMOVE".to_string();
+//
+//                         result_sd.send(err_order).await.unwrap();
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // if limits.len() > 0 {
+//         //     info!("");
+//         // }
+//         // 检查订单指令
+//         let check = order_command.check;
+//         for item in check.keys() {
+//             let mut self_clone = self.clone();
+//             let check_clone = check.clone();
+//             let item_clone = item.clone();
+//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(result) => {
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//
+//         let futures = FuturesUnordered::from_iter(handles);
+//         let _: Result<Vec<_>, _> = futures.try_collect().await;
+//     }
+// }
+//
+// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
+//     let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
+//     let size = Decimal::from_f64(order["size"].as_f64().unwrap()).unwrap();
+//     let status = order["status"].as_str().unwrap_or("");
+//     let filled_size = Decimal::from_f64(order["filledSize"].as_f64().unwrap()).unwrap();
+//     let filled_value = Decimal::from_str(order["filledValue"].as_str().unwrap()).unwrap();
+//
+//     let amount = size * ct_val;
+//     let deal_amount = filled_size * ct_val;
+//     let avg_price = if deal_amount.is_zero() { Decimal::ZERO } else { filled_value / deal_amount };
+//     let custom_status;
+//     if ["cancelled", "closed", "finished"].contains(&status) {
+//         custom_status = "REMOVE".to_string();
+//     } else if status == "open" {
+//         custom_status = "NEW".to_string();
+//     } else {
+//         custom_status = "NULL".to_string();
+//     };
+//     Order {
+//         id: order["id"].as_str().unwrap().to_string(),
+//         custom_id: order["clientOid"].as_str().unwrap_or("").to_string(),
+//         price,
+//         amount,
+//         deal_amount,
+//         avg_price,
+//         status: custom_status,
+//         order_type: order["type"].as_str().unwrap().to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("655 kucoin_swap".to_string()),
+//     }
+// }

+ 198 - 198
standard/src/okx_handle.rs

@@ -1,198 +1,198 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use serde::{Deserialize, Serialize};
-use tokio::time::Instant;
-use tracing::trace;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
-use crate::exchange::ExchangeEnum;
-use crate::handle_info::HandleSwapInfo;
-use crate::okx_swap::SwapPosition;
-
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SwapBalanceAndPositionSubscribe {
-    pos_data: Vec<SwapBalanceAndPositionPosDataSubscribe>,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SwapBalanceAndPositionPosDataSubscribe {
-    pos_id: String,
-    trade_id: String,
-    inst_id: String,
-    inst_type: String,
-    mgn_mode: String,
-    pos_side: String,
-    pos: Decimal,
-    ccy: String,
-    pos_ccy: String,
-    avg_px: Decimal,
-    u_time: String,
-}
-
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapPositionSubscribe {
-    arg: SwapPositionSubscribeArg,
-    data: Vec<SwapPosition>,
-}
-
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapPositionSubscribeArg {
-    channel: String,
-    uid: String,
-    inst_type: String,
-}
-
-// 处理账号信息
-pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&res_data_str).unwrap();
-    let account_info = res_data_json[0]["details"].clone();
-    let details = account_info[0].clone();
-    format_account_info(details, symbol)
-}
-
-pub fn format_account_info(data: serde_json::Value, symbol: String) -> Account {
-    let symbol_upper = symbol.to_uppercase();
-    let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-    Account {
-        coin: symbol_array[1].to_string(),
-        balance: Decimal::from_str(data["cashBal"].as_str().unwrap()).unwrap(),
-        available_balance: Decimal::from_str(data["availBal"].as_str().unwrap()).unwrap(),
-        frozen_balance: Decimal::from_str(data["fixedBal"].as_str().unwrap()).unwrap(),
-        stocks: Decimal::ZERO,
-        available_stocks: Decimal::ZERO,
-        frozen_stocks: Decimal::ZERO,
-    }
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_str = res_data.data;
-    let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-    trace!(?res_data_json);
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    }
-    trace!(?order_info);
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-// 处理订单信息
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["px"].as_str().unwrap()).unwrap();
-    let size = Decimal::from_str(order["sz"].as_str().unwrap()).unwrap();
-    let status = order["state"].as_str().unwrap_or("");
-    let filled_size = Decimal::from_str(order["accFillSz"].as_str().unwrap()).unwrap();
-
-    let avg_price = Decimal::from_str(order["avgPx"].as_str().unwrap()).unwrap();
-
-    let amount = size * ct_val;
-    let deal_amount = filled_size * ct_val;
-    let custom_status = if ["canceled", "filled", "mmp_canceled"].contains(&status) {
-        "REMOVE".to_string()
-    } else if ["live", "partially_filled"].contains(&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id: order["ordId"].as_str().unwrap().to_string(),
-        custom_id: order["clOrdId"].as_str().unwrap().to_string(),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["ordType"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("77 okx_handle".to_string()),
-    }
-}
-
-// 处理特殊深度数据
-pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-    HandleSwapInfo::handle_special_depth(ExchangeEnum::OkxSwap, res_data)
-}
-
-// 格式化深度信息
-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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
-
-// 处理特殊Ticker信息
-pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-    let res_data_str = res_data.data;
-    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-    format_special_ticker(res_data_json[0].clone(), res_data.label)
-}
-
-pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-    let bids = data["bids"][0].as_array().unwrap();
-    let asks = data["asks"][0].as_array().unwrap();
-    let bp = Decimal::from_str(bids[0].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_str(bids[1].as_str().unwrap()).unwrap();
-    let ap = Decimal::from_str(asks[0].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_str(asks[1].as_str().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_str(&data["seqId"].to_string()).unwrap();
-    let create_at = data["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: label,
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
-
-
-// 处理position信息
-pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
-    let res_data_str = res_data.data;
-    let data_list: Vec<SwapBalanceAndPositionSubscribe> = serde_json::from_str(&res_data_str).unwrap();
-
-    let position_data = data_list[0].pos_data.clone();
-    if position_data.len() > 0 {
-        position_data.iter().map(|item| format_position_item(item, ct_val)).collect()
-    } else {
-        vec![]
-    }
-}
-
-pub fn format_position_item(value: &SwapBalanceAndPositionPosDataSubscribe, ct_val: Decimal) -> Position {
-    let position_mode = match value.pos_side.as_str() {
-        "long" => { PositionModeEnum::Long }
-        "short" => { PositionModeEnum::Short }
-        _ => { PositionModeEnum::Both }
-    };
-    Position {
-        symbol: value.inst_id.replace("-SWAP", ""),
-        margin_level: Decimal::ZERO,
-        amount: value.pos * ct_val,
-        frozen_amount: Decimal::ZERO,
-        price: value.avg_px,
-        profit: Decimal::ZERO,
-        position_mode,
-        margin: Decimal::ZERO,
-    }
-}
+// use std::str::FromStr;
+// use rust_decimal::Decimal;
+// use rust_decimal_macros::dec;
+// use serde::{Deserialize, Serialize};
+// use tokio::time::Instant;
+// use tracing::trace;
+// use exchanges::response_base::ResponseData;
+// use global::trace_stack::TraceStack;
+// use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
+// use crate::exchange::ExchangeEnum;
+// use crate::handle_info::HandleSwapInfo;
+// use crate::okx_swap::SwapPosition;
+//
+//
+// #[derive(Debug, Clone, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// pub struct SwapBalanceAndPositionSubscribe {
+//     pos_data: Vec<SwapBalanceAndPositionPosDataSubscribe>,
+// }
+//
+// #[derive(Debug, Clone, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// pub struct SwapBalanceAndPositionPosDataSubscribe {
+//     pos_id: String,
+//     trade_id: String,
+//     inst_id: String,
+//     inst_type: String,
+//     mgn_mode: String,
+//     pos_side: String,
+//     pos: Decimal,
+//     ccy: String,
+//     pos_ccy: String,
+//     avg_px: Decimal,
+//     u_time: String,
+// }
+//
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SwapPositionSubscribe {
+//     arg: SwapPositionSubscribeArg,
+//     data: Vec<SwapPosition>,
+// }
+//
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SwapPositionSubscribeArg {
+//     channel: String,
+//     uid: String,
+//     inst_type: String,
+// }
+//
+// // 处理账号信息
+// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
+//     let res_data_str = res_data.data;
+//     let res_data_json: serde_json::Value = serde_json::from_str(&res_data_str).unwrap();
+//     let account_info = res_data_json[0]["details"].clone();
+//     let details = account_info[0].clone();
+//     format_account_info(details, symbol)
+// }
+//
+// pub fn format_account_info(data: serde_json::Value, symbol: String) -> Account {
+//     let symbol_upper = symbol.to_uppercase();
+//     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
+//     Account {
+//         coin: symbol_array[1].to_string(),
+//         balance: Decimal::from_str(data["cashBal"].as_str().unwrap()).unwrap(),
+//         available_balance: Decimal::from_str(data["availBal"].as_str().unwrap()).unwrap(),
+//         frozen_balance: Decimal::from_str(data["fixedBal"].as_str().unwrap()).unwrap(),
+//         stocks: Decimal::ZERO,
+//         available_stocks: Decimal::ZERO,
+//         frozen_stocks: Decimal::ZERO,
+//     }
+// }
+//
+// // 处理order信息
+// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
+//     let res_data_str = res_data.data;
+//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
+//     trace!(?res_data_json);
+//     let mut order_info = Vec::new();
+//     for item in res_data_json.iter() {
+//         order_info.push(format_order_item(item.clone(), ct_val));
+//     }
+//     trace!(?order_info);
+//     SpecialOrder {
+//         name: res_data.label,
+//         order: order_info,
+//     }
+// }
+//
+// // 处理订单信息
+// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
+//     let price = Decimal::from_str(order["px"].as_str().unwrap()).unwrap();
+//     let size = Decimal::from_str(order["sz"].as_str().unwrap()).unwrap();
+//     let status = order["state"].as_str().unwrap_or("");
+//     let filled_size = Decimal::from_str(order["accFillSz"].as_str().unwrap()).unwrap();
+//
+//     let avg_price = Decimal::from_str(order["avgPx"].as_str().unwrap()).unwrap();
+//
+//     let amount = size * ct_val;
+//     let deal_amount = filled_size * ct_val;
+//     let custom_status = if ["canceled", "filled", "mmp_canceled"].contains(&status) {
+//         "REMOVE".to_string()
+//     } else if ["live", "partially_filled"].contains(&status) {
+//         "NEW".to_string()
+//     } else {
+//         "NULL".to_string()
+//     };
+//     Order {
+//         id: order["ordId"].as_str().unwrap().to_string(),
+//         custom_id: order["clOrdId"].as_str().unwrap().to_string(),
+//         price,
+//         amount,
+//         deal_amount,
+//         avg_price,
+//         status: custom_status,
+//         order_type: order["ordType"].as_str().unwrap().to_string(),
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("77 okx_handle".to_string()),
+//     }
+// }
+//
+// // 处理特殊深度数据
+// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
+//     HandleSwapInfo::handle_special_depth(ExchangeEnum::OkxSwap, res_data)
+// }
+//
+// // 格式化深度信息
+// 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: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
+//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
+//         })
+//     }
+//     return depth_items;
+// }
+//
+// // 处理特殊Ticker信息
+// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
+//     let res_data_str = res_data.data;
+//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+//     format_special_ticker(res_data_json[0].clone(), res_data.label)
+// }
+//
+// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
+//     let bids = data["bids"][0].as_array().unwrap();
+//     let asks = data["asks"][0].as_array().unwrap();
+//     let bp = Decimal::from_str(bids[0].as_str().unwrap()).unwrap();
+//     let bq = Decimal::from_str(bids[1].as_str().unwrap()).unwrap();
+//     let ap = Decimal::from_str(asks[0].as_str().unwrap()).unwrap();
+//     let aq = Decimal::from_str(asks[1].as_str().unwrap()).unwrap();
+//     let mp = (bp + ap) * dec!(0.5);
+//     let t = Decimal::from_str(&data["seqId"].to_string()).unwrap();
+//     let create_at = data["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
+//
+//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
+//     let depth_info = vec![bp, bq, ap, aq];
+//     SpecialDepth {
+//         name: label,
+//         depth: depth_info,
+//         ticker: ticker_info,
+//         t,
+//         create_at,
+//     }
+// }
+//
+//
+// // 处理position信息
+// pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
+//     let res_data_str = res_data.data;
+//     let data_list: Vec<SwapBalanceAndPositionSubscribe> = serde_json::from_str(&res_data_str).unwrap();
+//
+//     let position_data = data_list[0].pos_data.clone();
+//     if position_data.len() > 0 {
+//         position_data.iter().map(|item| format_position_item(item, ct_val)).collect()
+//     } else {
+//         vec![]
+//     }
+// }
+//
+// pub fn format_position_item(value: &SwapBalanceAndPositionPosDataSubscribe, ct_val: Decimal) -> Position {
+//     let position_mode = match value.pos_side.as_str() {
+//         "long" => { PositionModeEnum::Long }
+//         "short" => { PositionModeEnum::Short }
+//         _ => { PositionModeEnum::Both }
+//     };
+//     Position {
+//         symbol: value.inst_id.replace("-SWAP", ""),
+//         margin_level: Decimal::ZERO,
+//         amount: value.pos * ct_val,
+//         frozen_amount: Decimal::ZERO,
+//         price: value.avg_px,
+//         profit: Decimal::ZERO,
+//         position_mode,
+//         margin: Decimal::ZERO,
+//     }
+// }

+ 1072 - 1072
standard/src/okx_swap.rs

@@ -1,1072 +1,1072 @@
-use std::collections::{BTreeMap, HashMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use serde::{Deserialize, Serialize};
-use serde_json::json;
-use tokio::time::Instant;
-use tracing::{debug, error};
-use exchanges::okx_swap_rest::OkxSwapRest;
-use global::trace_stack::TraceStack;
-use crate::exchange::ExchangeEnum;
-use crate::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, Ticker, utils};
-
-/// Okx交易所账户信息请求数据结构
-/// - 接口`"/api/v5/account/balance"`
-///
-/// struct SwapAccount
-/// - `adj_eq`: String, 美金层面有效保证金
-/// - `borrow_froz`: String, 账户美金层面潜在借币占用保证金
-/// - `details`: Vec<SwapAccountDetails>, 各币种资产详细信息
-/// - `imr`: String, 美金层面占用保证金
-/// - `iso_eq`: String, 美金层面逐仓仓位权益
-/// - `mgn_ratio`: String, 美金层面保证金率
-/// - `mmr`: String, 美金层面维持保证金
-/// - `notional_usd`: String, 以美金价值为单位的持仓数量,即仓位美金价值
-/// - `ord_froz`: String, 美金层面全仓挂单占用保证金
-/// - `total_eq`: String, 美金层面权益
-/// - `u_time`: String, 账户信息的更新时间
-///
-/// struct SwapAccountDetails
-/// - `avail_bal`: Decimal, 可用余额
-/// - `avail_eq`: Decimal, 可用保证金
-/// - `cash_bal`: Decimal, 币种余额
-/// - `ccy`: String, 币种
-/// - `cross_liab`: String, 币种全仓负债额
-/// - `dis_eq`: Decimal, 美金层面币种折算权益
-/// - `eq`: Decimal, 币种总权益
-/// - `eq_usd`: Decimal, 币种权益美金价值
-/// - `fixed_bal`: Decimal, 币种冻结金额
-/// - `frozen_bal`: Decimal, 币种占用金额
-/// - `interest`:String, 计息,应扣未扣利息。
-/// - `iso_eq`: Decimal, 币种逐仓仓位权益
-/// - `iso_liab`: String, 逐仓未实现盈亏
-/// - `iso_upl`: Decimal, 币种逐仓负债额
-/// - `liab`: String, 币种负债额
-/// - `max_loan`: String, 币种最大可借
-/// - `mgn_ratio`: String, 保证金率
-/// - `notional_lever`: Decimal, 币种杠杆倍数
-/// - `ord_frozen`: Decimal, 挂单冻结数量
-/// - `twap`: Decimal, 当前负债币种触发系统自动换币的风险
-/// - `u_time`: String, 币种余额信息的更新时间
-/// - `upl`: Decimal, 未实现盈亏
-/// - `upl_liab`: String, 由于仓位未实现亏损导致的负债
-/// - `stgy_eq`: Decimal, 策略权益
-/// - `spot_in_use_amt`: String, 现货对冲占用数量
-/// - `borrow_froz`: String, 币种美金层面潜在借币占用保证金
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapAccount {
-    adj_eq: String,
-    borrow_froz: String,
-    details: Vec<SwapAccountDetails>,
-    imr: String,
-    iso_eq: String,
-    mgn_ratio: String,
-    mmr: String,
-    notional_usd: String,
-    ord_froz: String,
-    total_eq: String,
-    u_time: String,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapAccountDetails {
-    avail_bal: Decimal,
-    avail_eq: Decimal,
-    cash_bal: Decimal,
-    ccy: String,
-    cross_liab: String,
-    dis_eq: Decimal,
-    eq: Decimal,
-    eq_usd: Decimal,
-    fixed_bal: Decimal,
-    frozen_bal: Decimal,
-    interest: String,
-    iso_eq: Decimal,
-    iso_liab: String,
-    iso_upl: Decimal,
-    liab: String,
-    max_loan: String,
-    mgn_ratio: String,
-    notional_lever: Decimal,
-    ord_frozen: Decimal,
-    twap: Decimal,
-    u_time: String,
-    upl: Decimal,
-    upl_liab: String,
-    stgy_eq: Decimal,
-    spot_in_use_amt: String,
-    borrow_froz: String,
-}
-
-/// Okx交易所持仓信息请求数据结构
-/// - 接口`"/api/v5/account/positions"`
-///
-/// struct SwapPosition
-/// - `adl`: Decimal, 信号区
-/// - `avail_pos`: Decimal, 可平仓数量,适用于 币币杠杆,交割/永续(开平仓模式)
-/// - `avg_px`: Decimal, 开仓平均价
-/// - `c_time`: String, 持仓创建时间
-/// - `ccy`: String, 占用保证金的币种
-/// - `delta_b_s`: String, 美金本位持仓仓位delta,仅适用于期权
-/// - `delta_p_a`: String, 币本位持仓仓位delta,仅适用于期权
-/// - `gamma_b_s`: String, 美金本位持仓仓位gamma,仅适用于期权
-/// - `gamma_p_a`: String, 币本位持仓仓位gamma,仅适用于期权
-/// - `imr`: String, 初始保证金,仅适用于全仓
-/// - `inst_id`: String, 产品ID
-/// - `inst_type`: String, 产品类型
-/// - `interest`: Decimal, 利息,已经生成的未扣利息
-/// - `idx_px`: Decimal, 最新指数价格
-/// - `last`: Decimal, 最新成交价
-/// - `usd_px`: String, 美金价格
-/// - `be_px`: Decimal, 盈亏平衡价
-/// - `lever`: Decimal, 杠杆倍数,不适用于期权
-/// - `liab`: String, 负债额,仅适用于币币杠杆
-/// - `liab_ccy`: String, 负债币种,仅适用于币币杠杆
-/// - `liq_px`: Decimal, 预估强平价
-/// - `mark_px`: Decimal, 最新标记价格
-/// - `margin`: Decimal, 保证金余额,可增减,仅适用于逐仓
-/// - `mgn_mode`: Decimal, 保证金模式
-/// - `mgn_ratio`: Decimal, 保证金率
-/// - `mmr`: Decimal, 维持保证金
-/// - `notional_usd`: Decimal, 以美金价值为单位的持仓数量
-/// - `opt_val`: String, 期权市值,仅适用于期权
-/// - `p_time`: String,
-/// - `pos`: Decimal, 持仓数量,逐仓自主划转模式下,转入保证金后会产生pos为0的仓位
-/// - `pos_ccy`: String, 仓位资产币种,仅适用于币币杠杆仓位
-/// - `pos_id`: Decimal, 持仓ID
-/// - `pos_side`: String, 持仓方向
-/// - `spot_in_use_amt`: String,
-/// - `spot_in_use_ccy`: String,
-/// - `theta_b_s`: String, 美金本位持仓仓位theta,仅适用于期权
-/// - `theta_p_a`: String, 币本位持仓仓位theta,仅适用于期权
-/// - `trade_id`: Decimal, 最新成交ID
-/// - `biz_ref_id`: String, 外部业务id
-/// - `biz_ref_type`: String, 外部业务类型
-/// - `quote_bal`: Decimal, 计价币余额 ,适用于 币币杠杆(逐仓自主划转模式 和 一键借币模式)
-/// - `base_bal`: Decimal, 交易币余额,适用于 币币杠杆(逐仓自主划转模式 和 一键借币模式)
-/// - `base_borrowed`: String, 交易币已借,适用于 币币杠杆(逐仓一键借币模式)
-/// - `base_interest`: String, 交易币计息,适用于 币币杠杆(逐仓一键借币模式)
-/// - `quote_borrowed`: String, 计价币已借,适用于 币币杠杆(逐仓一键借币模式)
-/// - `quote_interest`: String, 计价币计息,适用于 币币杠杆(逐仓一键借币模式)
-/// - `u_time`: String, 最近一次持仓更新时间
-/// - `upl`: Decimal, 未实现收益(以标记价格计算)
-/// - `upl_last_px`: Decimal, 以最新成交价格计算的未实现收益,主要做展示使用,实际值还是 upl
-/// - `upl_ratio`: Decimal, 未实现收益率(以标记价格计算
-/// - `upl_ratio_last_px`: Decimal, 以最新成交价格计算的未实现收益率
-/// - `vega_b_s`: String, 美金本位持仓仓位vega,仅适用于期权
-/// - `vega_p_a`: String, 币本位持仓仓位vega,仅适用于期权
-/// - `realized_pnl`: Decimal, 已实现收益
-/// - `pnl`: Decimal, 平仓订单累计收益额
-/// - `fee`: Decimal, 累计手续费金额,正数代表平台返佣 ,负数代表平台扣除
-/// - `funding_fee`: Decimal, 累计资金费用
-/// - `liq_penalty`: Decimal, 累计爆仓罚金,有值时为负数。
-/// - `close_order_algo`: Vec<SwapPositionCloseOrderAlgo>, 	平仓策略委托订单
-///
-/// struct SwapPositionCloseOrderAlgo
-///
-/// - `algo_id`: String, 策略委托单ID
-/// - `sl_trigger_px`: Decimal, 止损触发价
-/// - `sl_trigger_px_type`: String, 止损触发价类型
-/// - `tp_trigger_px`: Decimal, 止盈委托价
-/// - `tp_trigger_px_type`: String, 止盈触发价类型
-/// - `close_fraction`: Decimal, 策略委托触发时
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SwapPosition {
-    pub adl: String,
-    pub avail_pos: String,
-    pub avg_px: Decimal,
-    pub c_time: String,
-    pub ccy: String,
-    pub delta_b_s: String,
-    pub delta_p_a: String,
-    pub gamma_b_s: String,
-    pub gamma_p_a: String,
-    pub imr: String,
-    pub inst_id: String,
-    pub inst_type: String,
-    pub interest: String,
-    pub idx_px: String,
-    pub last: String,
-    pub usd_px: String,
-    pub be_px: String,
-    pub lever: Decimal,
-    pub liab: String,
-    pub liab_ccy: String,
-    pub liq_px: String,
-    pub mark_px: String,
-    pub margin: String,
-    pub mgn_mode: String,
-    pub mgn_ratio: String,
-    pub mmr: String,
-    pub notional_usd: String,
-    pub opt_val: String,
-    pub pos: Decimal,
-    pub pos_ccy: String,
-    pub pos_id: String,
-    pub pos_side: String,
-    pub spot_in_use_amt: String,
-    pub spot_in_use_ccy: String,
-    pub theta_b_s: String,
-    pub theta_p_a: String,
-    pub trade_id: String,
-    pub biz_ref_id: String,
-    pub biz_ref_type: String,
-    pub quote_bal: String,
-    pub base_bal: String,
-    pub base_borrowed: String,
-    pub base_interest: String,
-    pub quote_borrowed: String,
-    pub quote_interest: String,
-    pub u_time: String,
-    pub upl: Decimal,
-    pub upl_last_px: String,
-    pub upl_ratio: String,
-    pub upl_ratio_last_px: String,
-    pub vega_b_s: String,
-    pub vega_p_a: String,
-    pub realized_pnl: String,
-    pub pnl: String,
-    pub fee: String,
-    pub funding_fee: String,
-    pub liq_penalty: String,
-    pub close_order_algo: Vec<SwapPositionCloseOrderAlgo>,
-}
-
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SwapPositionCloseOrderAlgo {
-    pub algo_id: String,
-    pub sl_trigger_px: String,
-    pub sl_trigger_px_type: String,
-    pub tp_trigger_px: String,
-    pub tp_trigger_px_type: String,
-    pub close_fraction: String,
-}
-
-/// Okx交易所行情信息请求数据结构
-/// - 接口`"/api/v5/market/ticker"`
-///
-/// struct SwapTicker
-/// - `inst_type`: String, 产品类型
-/// - `inst_id`: String, 产品ID
-/// - `last`: Decimal, 最新成交价
-/// - `last_sz`: Decimal, 最新成交的数量
-/// - `ask_px`: Decimal, 卖一价
-/// - `ask_sz`: Decimal, 卖一价的挂单数数量
-/// - `bid_px`: Decimal, 买一价
-/// - `bid_sz`: Decimal, 买一价的挂单数量
-/// - `open24h`: Decimal, 24小时开盘价
-/// - `high24h`: Decimal, 24小时最高价
-/// - `low24h`: Decimal, 24小时最低价
-/// - `vol_ccy24h`: Decimal, 24小时成交量,以币为单位
-/// - `vol24h`: Decimal, 24小时成交量,以张为单位
-/// - `ts`: String, ticker数据产生时间
-/// - `sod_utc0`: Decimal, UTC 0 时开盘价
-/// - `sod_utc8`: Decimal, UTC+8 时开盘价
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapTicker {
-    inst_type: String,
-    inst_id: String,
-    last: Decimal,
-    last_sz: Decimal,
-    ask_px: Decimal,
-    ask_sz: Decimal,
-    bid_px: Decimal,
-    bid_sz: Decimal,
-    open24h: Decimal,
-    high24h: Decimal,
-    low24h: Decimal,
-    vol_ccy24h: Decimal,
-    vol24h: Decimal,
-    ts: String,
-    sod_utc0: Decimal,
-    sod_utc8: Decimal,
-}
-
-/// Okx交易所市场信息请求数据结构
-/// - 接口`"/api/v5/public/instruments"`
-///
-/// struct SwapMarket
-/// - `alias`: String,
-/// - `base_ccy`: String,
-/// - `category`: String,
-/// - `ct_mult`: Decimal,
-/// - `ct_type`: String,
-/// - `ct_val`: Decimal,
-/// - `ct_val_ccy`: String,
-/// - `exp_time`: String,
-/// - `inst_family`: String,
-/// - `inst_id`: String,
-/// - `inst_type`: String,
-/// - `lever`: Decimal,
-/// - `list_time`: String,
-/// - `lot_sz`: Decimal,
-/// - `max_iceberg_sz`: Decimal,
-/// - `max_lmt_sz`: Decimal,
-/// - `max_mkt_sz`: Decimal,
-/// - `max_stop_sz`: Decimal,
-/// - `max_trigger_sz`: Decimal,
-/// - `max_twap_sz`: Decimal,
-/// - `min_sz`: Decimal,
-/// - `opt_type`: String,
-/// - `quote_ccy`: String,
-/// - `settle_ccy`: String,
-/// - `state`: String,
-/// - `stk`: String,
-/// - `tick_sz`: Decimal,
-/// - `uly`: String,
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapMarket {
-    alias: String,
-    base_ccy: String,
-    category: String,
-    ct_mult: Decimal,
-    ct_type: String,
-    ct_val: Decimal,
-    ct_val_ccy: String,
-    exp_time: String,
-    inst_family: String,
-    inst_id: String,
-    inst_type: String,
-    lever: Decimal,
-    list_time: String,
-    lot_sz: Decimal,
-    max_iceberg_sz: Decimal,
-    max_lmt_sz: Decimal,
-    max_mkt_sz: Decimal,
-    max_stop_sz: Decimal,
-    max_trigger_sz: Decimal,
-    max_twap_sz: Decimal,
-    min_sz: Decimal,
-    opt_type: String,
-    quote_ccy: String,
-    settle_ccy: String,
-    state: String,
-    stk: String,
-    tick_sz: Decimal,
-    uly: String,
-}
-
-/// Okx交易所订单信息请求数据结构
-/// - 接口`"/api/v5/trade/order"`
-///
-/// struct SwapOrder
-/// - `inst_type`: String, 产品类型
-/// - `inst_id`: String, 产品ID
-/// - `ccy`: String, 保证金币种
-/// - `ord_id`: String, 订单ID
-/// - `cl_ord_id`: String, 客户自定义订单ID
-/// - `tag`: String, 订单标签
-/// - `px`: Decimal, 委托价格
-/// - `px_usd`: String, 期权价格
-/// - `px_vol`: String, 期权订单的隐含波动率
-/// - `px_type`: String, 期权的价格类型
-/// - `sz`: Decimal, 委托数量
-/// - `pnl`: Decimal, 收益
-/// - `ord_type`: String, 订单类型
-/// - `side`: String, 订单方向
-/// - `pos_side`: String, 持仓方向
-/// - `td_mode`: String, 交易模式
-/// - `acc_fill_sz`: Decimal, 累计成交数量
-/// - `fill_px`: String, 最新成交价格,如果成交数量为0,该字段为""
-/// - `trade_id`: String, 最新成交ID
-/// - `fill_sz`: Decimal, 最新成交数量
-/// - `fill_time`: String, 最新成交时间
-/// - `source`: String, 订单来源
-/// - `state`: String, 订单状态
-/// - `avg_px`: Decimal, 成交均价,如果成交数量为0,该字段也为""
-/// - `lever`: Decimal, 杠杆倍数
-/// - `attach_algo_cl_ord_id`: String, 下单附带止盈止损时,客户自定义的策略订单ID
-/// - `tp_trigger_px`: Decimal, 止盈触发价
-/// - `tp_trigger_px_type`: String, 止盈触发价类型
-/// - `tp_ord_px`: Decimal, 止盈委托价
-/// - `sl_trigger_px`: Decimal, 止损触发价
-/// - `sl_trigger_px_type`: String, 止损触发价类型
-/// - `sl_ord_px`: Decimal, 止损委托价
-/// - `stp_id`: String, 自成交保护ID
-/// - `stp_mode`: String, 自成交保护模式
-/// - `fee_ccy`: String, 交易手续费币种
-/// - `fee`: Decimal, 手续费与返佣
-/// - `rebate_ccy`: String, 返佣金币种
-/// - `rebate`: String, 返佣金额,仅适用于币币和杠杆
-/// - `tgt_ccy`: String, 币币市价单委托数量sz的单位
-/// - `category`: String, 订单种类
-/// - `reduce_only`: String, 是否只减仓
-/// - `cancel_source`: String, 	订单取消来源的原因枚举值代码
-/// - `cancel_source_reason`: String, 订单取消来源的对应具体原因
-/// - `quick_mgn_type`: String, 一键借币类型,仅适用于杠杆逐仓的一键借币模式
-/// - `algo_cl_ord_id`: String, 客户自定义策略订单ID
-/// - `algo_id`: String, 策略委托单ID,策略订单触发时有值,否则为""
-/// - `u_time`: String, 订单状态更新时间
-/// - `c_time`: String, 订单创建时间
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SwapOrder {
-    inst_type: String,
-    inst_id: String,
-    ccy: String,
-    ord_id: String,
-    cl_ord_id: String,
-    tag: String,
-    px: Decimal,
-    px_usd: String,
-    px_vol: String,
-    px_type: String,
-    sz: Decimal,
-    pnl: String,
-    ord_type: String,
-    side: String,
-    pos_side: String,
-    td_mode: String,
-    acc_fill_sz: Decimal,
-    fill_px: String,
-    trade_id: String,
-    fill_sz: String,
-    fill_time: String,
-    source: String,
-    state: String,
-    avg_px: String,
-    lever: String,
-    attach_algo_cl_ord_id: String,
-    tp_trigger_px: String,
-    tp_trigger_px_type: String,
-    tp_ord_px: String,
-    sl_trigger_px: String,
-    sl_trigger_px_type: String,
-    sl_ord_px: String,
-    stp_id: String,
-    stp_mode: String,
-    fee_ccy: String,
-    fee: String,
-    rebate_ccy: String,
-    rebate: String,
-    tgt_ccy: String,
-    category: String,
-    reduce_only: String,
-    cancel_source: String,
-    cancel_source_reason: String,
-    quick_mgn_type: String,
-    algo_cl_ord_id: String,
-    algo_id: String,
-    u_time: String,
-    c_time: String,
-}
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct OkxSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: OkxSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl OkxSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> OkxSwap {
-        let market = Market::new();
-        let mut okx_swap = OkxSwap {
-            exchange: ExchangeEnum::OkxSwap,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: OkxSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        okx_swap.market = OkxSwap::get_market(&mut okx_swap).await.unwrap_or(okx_swap.market);
-        return okx_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for OkxSwap {
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-
-    fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::OkxSwap }
-
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-
-    fn get_self_is_colo(&self) -> bool { self.is_colo }
-
-    fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
-
-    fn get_self_market(&self) -> Market { self.market.clone() }
-
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        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 = res_data_json[0]["ts"].as_str().unwrap().to_string();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let res_data = self.request.get_balance(symbol_array[1].to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let balance_info_list: Vec<SwapAccount> = serde_json::from_str(res_data_str).unwrap();
-            let detail = balance_info_list[0].details.iter().find(|&item| item.ccy == symbol_array[1]);
-            match detail {
-                None => {
-                    error!("Okx:获取Account信息错误!\nhandle_swap_account:res_data={:?}", res_data);
-                    panic!("Okx:获取Account信息错误!\nhandle_swap_account:res_data={:?}", res_data)
-                }
-                Some(value) => {
-                    let result = Account {
-                        coin: value.ccy.to_uppercase(),
-                        balance: value.avail_bal + value.fixed_bal,
-                        available_balance: value.avail_bal,
-                        frozen_balance: value.fixed_bal,
-                        stocks: Decimal::ZERO,
-                        available_stocks: Decimal::ZERO,
-                        frozen_stocks: Decimal::ZERO,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.to_string(), "-"));
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_positions("SWAP".to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let data_list: Vec<SwapPosition> = serde_json::from_str(&res_data_str).unwrap();
-            let position_info: Vec<&SwapPosition> = data_list.iter().filter(|item| item.inst_id == symbol_format).collect();
-            let result = position_info.iter().map(|item| format_position_item(item, ct_val)).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let res_data = self.request.get_positions("SWAP".to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let data_list: Vec<SwapPosition> = serde_json::from_str(&res_data_str).unwrap();
-            let result = data_list.iter().map(|item| format_position_item(item, Decimal::ONE)).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-        let res_data = self.request.get_ticker(symbol_format.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let ticker_info_list: Vec<SwapTicker> = serde_json::from_str(&res_data_str).unwrap();
-            let ticker_info = ticker_info_list.iter().find(|item| item.inst_id == symbol_format);
-            match ticker_info {
-                None => {
-                    error!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str);
-                    panic!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str)
-                }
-                Some(value) => {
-                    let result = Ticker {
-                        time: value.ts.parse().unwrap(),
-                        high: value.high24h,
-                        low: value.low24h,
-                        sell: value.ask_px,
-                        buy: value.bid_px,
-                        last: value.last,
-                        volume: value.last_sz,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(symbol.clone(), "-"));
-        let res_data = self.request.get_ticker(symbol_format.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let ticker_info_list: Vec<SwapTicker> = serde_json::from_str(&res_data_str).unwrap();
-            let ticker_info = ticker_info_list.iter().find(|item| item.inst_id == symbol_format);
-            match ticker_info {
-                None => {
-                    error!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str);
-                    panic!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str)
-                }
-                Some(value) => {
-                    let result = Ticker {
-                        time: value.ts.parse().unwrap(),
-                        high: value.high24h,
-                        low: value.low24h,
-                        sell: value.ask_px,
-                        buy: value.bid_px,
-                        last: value.last,
-                        volume: value.last_sz,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let res_data = self.request.get_instruments().await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Vec<SwapMarket> = serde_json::from_str(res_data_str).unwrap();
-            let market_info = res_data_json.iter().find(|item| item.inst_id == format!("{}-SWAP", symbol_format));
-            match market_info {
-                None => {
-                    error!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str);
-                    panic!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str)
-                }
-                Some(value) => {
-                    println!("{:?}", value);
-                    let symbol_array: Vec<&str> = value.inst_family.split("-").collect();
-                    let result = Market {
-                        symbol: format!("{}_{}", symbol_array[0], symbol_array[1]),
-                        base_asset: symbol_array[0].to_string(),
-                        quote_asset: symbol_array[1].to_string(),
-                        tick_size: value.tick_sz,
-                        amount_size: value.min_sz * value.ct_val,
-                        price_precision: Decimal::from_u32(value.tick_sz.scale()).unwrap(),
-                        amount_precision: Decimal::from_u32((value.min_sz * value.ct_val).scale()).unwrap(),
-                        min_qty: value.min_sz,
-                        max_qty: value.max_lmt_sz,
-                        min_notional: value.min_sz * value.ct_val,
-                        max_notional: value.max_lmt_sz * value.ct_val,
-                        ct_val: value.ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "-");
-        let res_data = self.request.get_instruments().await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Vec<SwapMarket> = serde_json::from_str(res_data_str).unwrap();
-            let market_info = res_data_json.iter().find(|item| item.inst_id == format!("{}-SWAP", symbol_format));
-            match market_info {
-                None => {
-                    error!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str);
-                    panic!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str)
-                }
-                Some(value) => {
-                    let symbol_array: Vec<&str> = value.inst_family.split("-").collect();
-                    let result = Market {
-                        symbol: format!("{}_{}", symbol_array[0], symbol_array[1]),
-                        base_asset: symbol_array[0].to_string(),
-                        quote_asset: symbol_array[1].to_string(),
-                        tick_size: value.tick_sz,
-                        amount_size: value.min_sz * value.ct_val,
-                        price_precision: Decimal::from_u32(value.tick_sz.scale()).unwrap(),
-                        amount_precision: Decimal::from_u32((value.min_sz * value.ct_val).scale()).unwrap(),
-                        min_qty: value.min_sz,
-                        max_qty: value.max_lmt_sz,
-                        min_notional: value.min_sz * value.ct_val,
-                        max_notional: value.max_lmt_sz * value.ct_val,
-                        ct_val: value.ct_mult,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_order(symbol_format, order_id.to_string(), custom_id.to_string()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Vec<SwapOrder> = serde_json::from_str(res_data_str).unwrap();
-            let order_info = res_data_json[0].clone();
-            let result = format_order_item(order_info, ct_val);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_incomplete_order(symbol_format.clone()).await;
-        if res_data.code == "200" {
-            let res_data_str = &res_data.data;
-            let res_data_json: Vec<SwapOrder> = serde_json::from_str(res_data_str).unwrap();
-            let result = res_data_json.iter().map(|item| format_order_item(item.clone(), ct_val)).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-        let ct_val = self.market.ct_val;
-        let mut params = json!({
-            "tdMode": "cross",
-            "clOrdId": custom_id.to_string(),
-            "instId": symbol_format,
-            "px": price.to_string(),
-        });
-        params["ordType"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
-        let size = (amount / ct_val).floor();
-        params["sz"] = json!(size);
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-                params["posSide"] = json!("long");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-                params["posSide"] = json!("long");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-                params["posSide"] = json!("short");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-                params["posSide"] = json!("short");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.swap_order(params).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 = res_data_json[0].clone();
-            let id = order_info["ordId"].as_str().unwrap().to_string();
-            let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id,
-                price,
-                amount,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("799 okx_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(symbol.clone(), "-"));
-        let mut params = json!({
-            "tdMode": "cross",
-            "clOrdId": custom_id.to_string(),
-            "instId": symbol_format,
-            "px": price.to_string(),
-        });
-        params["ordType"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
-        let size = (amount / ct_val).floor();
-        params["sz"] = json!(size);
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-                params["posSide"] = json!("long");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-                params["posSide"] = json!("long");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-                params["posSide"] = json!("short");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-                params["posSide"] = json!("short");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.swap_order(params).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 = res_data_json[0].clone();
-            let id = order_info["ordId"].as_str().unwrap().to_string();
-            let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id,
-                price,
-                amount,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("853 okx_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-        let res_data = self.request.cancel_order(symbol_format, order_id.to_string(), custom_id.to_string()).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 = res_data_json[0].clone();
-            let id = order_info["ordId"].as_str().unwrap().to_string();
-            let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id,
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "REMOVE".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("879 okx_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-        let res_data = self.request.set_position_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.to_string()))
-        }
-    }
-
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-        let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-        let res_data = self.request.set_leverage(symbol_format, 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.to_string()))
-        }
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string())) }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string())) }
-
-    async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-        let mut handles = vec![];
-        // 撤销订单
-        let cancel = order_command.cancel;
-        for item in cancel.keys() {
-            let mut self_clone = self.clone();
-            let cancel_clone = cancel.clone();
-            let item_clone = item.clone();
-            let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                if order_id != "" {
-                    let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                    match result {
-                        Ok(_) => {
-                            // result_sd.send(result).await.unwrap();
-                        }
-                        Err(error) => {
-                            // 取消失败去查订单。
-                            let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                            match query_rst {
-                                Ok(order) => {
-                                    result_sd.send(order).await.unwrap();
-                                }
-                                Err(query_err) => {
-                                    error!(?query_err);
-                                    error!("撤单失败,而且查单也失败了,okx_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                                }
-                            }
-                            err_sd.send(error).await.unwrap();
-                        }
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 下单指令
-        let mut limits = HashMap::new();
-        limits.extend(order_command.limits_open);
-        limits.extend(order_command.limits_close);
-        for item in limits.keys() {
-            let mut self_clone = self.clone();
-            let limits_clone = limits.clone();
-            let item_clone = item.clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let ts = trace_stack.clone();
-
-            let handle = tokio::spawn(async move {
-                let value = limits_clone[&item_clone].clone();
-                let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-                let side = value.get(1).unwrap();
-                let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-                let cid = value.get(3).unwrap();
-
-                //  order_name: [数量,方向,价格,c_id]
-                let result = self_clone.take_order(cid, side, price, amount).await;
-                match result {
-                    Ok(mut result) => {
-                        // ts.on_after_send();
-                        result.trace_stack = ts.clone();
-
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        result_sd.send(err_order).await.unwrap();
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        // 检查订单指令
-        let check = order_command.check;
-        for item in check.keys() {
-            let mut self_clone = self.clone();
-            let check_clone = check.clone();
-            let item_clone = item.clone();
-            let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-            let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-            let result_sd = self.order_sender.clone();
-            let err_sd = self.error_sender.clone();
-            let handle = tokio::spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        err_sd.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_order_item(data: SwapOrder, ct_val: Decimal) -> Order {
-    debug!("format-order-start, okx_swap");
-    debug!(?data);
-    let custom_status = if ["canceled", "filled", "mmp_canceled"].contains(&data.state.as_str()) {
-        "REMOVE".to_string()
-    } else if ["live", "partially_filled"].contains(&data.state.as_str()) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-
-    let result = Order {
-        id: data.ord_id,
-        custom_id: data.cl_ord_id,
-        price: data.px,
-        amount: data.sz * ct_val,
-        deal_amount: data.acc_fill_sz * ct_val,
-        avg_price: if data.avg_px != "" { Decimal::from_str(&data.avg_px).unwrap() } else { Decimal::ZERO },
-        status: custom_status,
-        order_type: data.ord_type,
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("1049 okx_swap".to_string()),
-    };
-    debug!(?result);
-    debug!("format-order-end, okx_swap");
-    result
-}
-
-pub fn format_position_item(value: &SwapPosition, ct_val: Decimal) -> Position {
-    let position_mode = match value.pos_side.as_str() {
-        "long" => { PositionModeEnum::Long }
-        "short" => { PositionModeEnum::Short }
-        _ => { PositionModeEnum::Both }
-    };
-    Position {
-        symbol: value.inst_id.replace("-SWAP", ""),
-        margin_level: value.lever,
-        amount: value.pos * ct_val,
-        frozen_amount: Decimal::ZERO,
-        price: value.avg_px,
-        profit: value.upl,
-        position_mode,
-        margin: if value.margin != "" { Decimal::from_str(&value.margin).unwrap() } else { Decimal::ZERO },
-    }
-}
+// use std::collections::{BTreeMap, HashMap};
+// use std::io::{Error, ErrorKind};
+// use std::str::FromStr;
+// use tokio::sync::mpsc::Sender;
+// use async_trait::async_trait;
+// use futures::stream::FuturesUnordered;
+// use futures::TryStreamExt;
+// use rust_decimal::Decimal;
+// use rust_decimal::prelude::FromPrimitive;
+// use serde::{Deserialize, Serialize};
+// use serde_json::json;
+// use tokio::time::Instant;
+// use tracing::{debug, error};
+// use exchanges::okx_swap_rest::OkxSwapRest;
+// use global::trace_stack::TraceStack;
+// use crate::exchange::ExchangeEnum;
+// use crate::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, Ticker, utils};
+//
+// /// Okx交易所账户信息请求数据结构
+// /// - 接口`"/api/v5/account/balance"`
+// ///
+// /// struct SwapAccount
+// /// - `adj_eq`: String, 美金层面有效保证金
+// /// - `borrow_froz`: String, 账户美金层面潜在借币占用保证金
+// /// - `details`: Vec<SwapAccountDetails>, 各币种资产详细信息
+// /// - `imr`: String, 美金层面占用保证金
+// /// - `iso_eq`: String, 美金层面逐仓仓位权益
+// /// - `mgn_ratio`: String, 美金层面保证金率
+// /// - `mmr`: String, 美金层面维持保证金
+// /// - `notional_usd`: String, 以美金价值为单位的持仓数量,即仓位美金价值
+// /// - `ord_froz`: String, 美金层面全仓挂单占用保证金
+// /// - `total_eq`: String, 美金层面权益
+// /// - `u_time`: String, 账户信息的更新时间
+// ///
+// /// struct SwapAccountDetails
+// /// - `avail_bal`: Decimal, 可用余额
+// /// - `avail_eq`: Decimal, 可用保证金
+// /// - `cash_bal`: Decimal, 币种余额
+// /// - `ccy`: String, 币种
+// /// - `cross_liab`: String, 币种全仓负债额
+// /// - `dis_eq`: Decimal, 美金层面币种折算权益
+// /// - `eq`: Decimal, 币种总权益
+// /// - `eq_usd`: Decimal, 币种权益美金价值
+// /// - `fixed_bal`: Decimal, 币种冻结金额
+// /// - `frozen_bal`: Decimal, 币种占用金额
+// /// - `interest`:String, 计息,应扣未扣利息。
+// /// - `iso_eq`: Decimal, 币种逐仓仓位权益
+// /// - `iso_liab`: String, 逐仓未实现盈亏
+// /// - `iso_upl`: Decimal, 币种逐仓负债额
+// /// - `liab`: String, 币种负债额
+// /// - `max_loan`: String, 币种最大可借
+// /// - `mgn_ratio`: String, 保证金率
+// /// - `notional_lever`: Decimal, 币种杠杆倍数
+// /// - `ord_frozen`: Decimal, 挂单冻结数量
+// /// - `twap`: Decimal, 当前负债币种触发系统自动换币的风险
+// /// - `u_time`: String, 币种余额信息的更新时间
+// /// - `upl`: Decimal, 未实现盈亏
+// /// - `upl_liab`: String, 由于仓位未实现亏损导致的负债
+// /// - `stgy_eq`: Decimal, 策略权益
+// /// - `spot_in_use_amt`: String, 现货对冲占用数量
+// /// - `borrow_froz`: String, 币种美金层面潜在借币占用保证金
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SwapAccount {
+//     adj_eq: String,
+//     borrow_froz: String,
+//     details: Vec<SwapAccountDetails>,
+//     imr: String,
+//     iso_eq: String,
+//     mgn_ratio: String,
+//     mmr: String,
+//     notional_usd: String,
+//     ord_froz: String,
+//     total_eq: String,
+//     u_time: String,
+// }
+//
+// #[derive(Debug, Clone, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SwapAccountDetails {
+//     avail_bal: Decimal,
+//     avail_eq: Decimal,
+//     cash_bal: Decimal,
+//     ccy: String,
+//     cross_liab: String,
+//     dis_eq: Decimal,
+//     eq: Decimal,
+//     eq_usd: Decimal,
+//     fixed_bal: Decimal,
+//     frozen_bal: Decimal,
+//     interest: String,
+//     iso_eq: Decimal,
+//     iso_liab: String,
+//     iso_upl: Decimal,
+//     liab: String,
+//     max_loan: String,
+//     mgn_ratio: String,
+//     notional_lever: Decimal,
+//     ord_frozen: Decimal,
+//     twap: Decimal,
+//     u_time: String,
+//     upl: Decimal,
+//     upl_liab: String,
+//     stgy_eq: Decimal,
+//     spot_in_use_amt: String,
+//     borrow_froz: String,
+// }
+//
+// /// Okx交易所持仓信息请求数据结构
+// /// - 接口`"/api/v5/account/positions"`
+// ///
+// /// struct SwapPosition
+// /// - `adl`: Decimal, 信号区
+// /// - `avail_pos`: Decimal, 可平仓数量,适用于 币币杠杆,交割/永续(开平仓模式)
+// /// - `avg_px`: Decimal, 开仓平均价
+// /// - `c_time`: String, 持仓创建时间
+// /// - `ccy`: String, 占用保证金的币种
+// /// - `delta_b_s`: String, 美金本位持仓仓位delta,仅适用于期权
+// /// - `delta_p_a`: String, 币本位持仓仓位delta,仅适用于期权
+// /// - `gamma_b_s`: String, 美金本位持仓仓位gamma,仅适用于期权
+// /// - `gamma_p_a`: String, 币本位持仓仓位gamma,仅适用于期权
+// /// - `imr`: String, 初始保证金,仅适用于全仓
+// /// - `inst_id`: String, 产品ID
+// /// - `inst_type`: String, 产品类型
+// /// - `interest`: Decimal, 利息,已经生成的未扣利息
+// /// - `idx_px`: Decimal, 最新指数价格
+// /// - `last`: Decimal, 最新成交价
+// /// - `usd_px`: String, 美金价格
+// /// - `be_px`: Decimal, 盈亏平衡价
+// /// - `lever`: Decimal, 杠杆倍数,不适用于期权
+// /// - `liab`: String, 负债额,仅适用于币币杠杆
+// /// - `liab_ccy`: String, 负债币种,仅适用于币币杠杆
+// /// - `liq_px`: Decimal, 预估强平价
+// /// - `mark_px`: Decimal, 最新标记价格
+// /// - `margin`: Decimal, 保证金余额,可增减,仅适用于逐仓
+// /// - `mgn_mode`: Decimal, 保证金模式
+// /// - `mgn_ratio`: Decimal, 保证金率
+// /// - `mmr`: Decimal, 维持保证金
+// /// - `notional_usd`: Decimal, 以美金价值为单位的持仓数量
+// /// - `opt_val`: String, 期权市值,仅适用于期权
+// /// - `p_time`: String,
+// /// - `pos`: Decimal, 持仓数量,逐仓自主划转模式下,转入保证金后会产生pos为0的仓位
+// /// - `pos_ccy`: String, 仓位资产币种,仅适用于币币杠杆仓位
+// /// - `pos_id`: Decimal, 持仓ID
+// /// - `pos_side`: String, 持仓方向
+// /// - `spot_in_use_amt`: String,
+// /// - `spot_in_use_ccy`: String,
+// /// - `theta_b_s`: String, 美金本位持仓仓位theta,仅适用于期权
+// /// - `theta_p_a`: String, 币本位持仓仓位theta,仅适用于期权
+// /// - `trade_id`: Decimal, 最新成交ID
+// /// - `biz_ref_id`: String, 外部业务id
+// /// - `biz_ref_type`: String, 外部业务类型
+// /// - `quote_bal`: Decimal, 计价币余额 ,适用于 币币杠杆(逐仓自主划转模式 和 一键借币模式)
+// /// - `base_bal`: Decimal, 交易币余额,适用于 币币杠杆(逐仓自主划转模式 和 一键借币模式)
+// /// - `base_borrowed`: String, 交易币已借,适用于 币币杠杆(逐仓一键借币模式)
+// /// - `base_interest`: String, 交易币计息,适用于 币币杠杆(逐仓一键借币模式)
+// /// - `quote_borrowed`: String, 计价币已借,适用于 币币杠杆(逐仓一键借币模式)
+// /// - `quote_interest`: String, 计价币计息,适用于 币币杠杆(逐仓一键借币模式)
+// /// - `u_time`: String, 最近一次持仓更新时间
+// /// - `upl`: Decimal, 未实现收益(以标记价格计算)
+// /// - `upl_last_px`: Decimal, 以最新成交价格计算的未实现收益,主要做展示使用,实际值还是 upl
+// /// - `upl_ratio`: Decimal, 未实现收益率(以标记价格计算
+// /// - `upl_ratio_last_px`: Decimal, 以最新成交价格计算的未实现收益率
+// /// - `vega_b_s`: String, 美金本位持仓仓位vega,仅适用于期权
+// /// - `vega_p_a`: String, 币本位持仓仓位vega,仅适用于期权
+// /// - `realized_pnl`: Decimal, 已实现收益
+// /// - `pnl`: Decimal, 平仓订单累计收益额
+// /// - `fee`: Decimal, 累计手续费金额,正数代表平台返佣 ,负数代表平台扣除
+// /// - `funding_fee`: Decimal, 累计资金费用
+// /// - `liq_penalty`: Decimal, 累计爆仓罚金,有值时为负数。
+// /// - `close_order_algo`: Vec<SwapPositionCloseOrderAlgo>, 	平仓策略委托订单
+// ///
+// /// struct SwapPositionCloseOrderAlgo
+// ///
+// /// - `algo_id`: String, 策略委托单ID
+// /// - `sl_trigger_px`: Decimal, 止损触发价
+// /// - `sl_trigger_px_type`: String, 止损触发价类型
+// /// - `tp_trigger_px`: Decimal, 止盈委托价
+// /// - `tp_trigger_px_type`: String, 止盈触发价类型
+// /// - `close_fraction`: Decimal, 策略委托触发时
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// pub struct SwapPosition {
+//     pub adl: String,
+//     pub avail_pos: String,
+//     pub avg_px: Decimal,
+//     pub c_time: String,
+//     pub ccy: String,
+//     pub delta_b_s: String,
+//     pub delta_p_a: String,
+//     pub gamma_b_s: String,
+//     pub gamma_p_a: String,
+//     pub imr: String,
+//     pub inst_id: String,
+//     pub inst_type: String,
+//     pub interest: String,
+//     pub idx_px: String,
+//     pub last: String,
+//     pub usd_px: String,
+//     pub be_px: String,
+//     pub lever: Decimal,
+//     pub liab: String,
+//     pub liab_ccy: String,
+//     pub liq_px: String,
+//     pub mark_px: String,
+//     pub margin: String,
+//     pub mgn_mode: String,
+//     pub mgn_ratio: String,
+//     pub mmr: String,
+//     pub notional_usd: String,
+//     pub opt_val: String,
+//     pub pos: Decimal,
+//     pub pos_ccy: String,
+//     pub pos_id: String,
+//     pub pos_side: String,
+//     pub spot_in_use_amt: String,
+//     pub spot_in_use_ccy: String,
+//     pub theta_b_s: String,
+//     pub theta_p_a: String,
+//     pub trade_id: String,
+//     pub biz_ref_id: String,
+//     pub biz_ref_type: String,
+//     pub quote_bal: String,
+//     pub base_bal: String,
+//     pub base_borrowed: String,
+//     pub base_interest: String,
+//     pub quote_borrowed: String,
+//     pub quote_interest: String,
+//     pub u_time: String,
+//     pub upl: Decimal,
+//     pub upl_last_px: String,
+//     pub upl_ratio: String,
+//     pub upl_ratio_last_px: String,
+//     pub vega_b_s: String,
+//     pub vega_p_a: String,
+//     pub realized_pnl: String,
+//     pub pnl: String,
+//     pub fee: String,
+//     pub funding_fee: String,
+//     pub liq_penalty: String,
+//     pub close_order_algo: Vec<SwapPositionCloseOrderAlgo>,
+// }
+//
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// pub struct SwapPositionCloseOrderAlgo {
+//     pub algo_id: String,
+//     pub sl_trigger_px: String,
+//     pub sl_trigger_px_type: String,
+//     pub tp_trigger_px: String,
+//     pub tp_trigger_px_type: String,
+//     pub close_fraction: String,
+// }
+//
+// /// Okx交易所行情信息请求数据结构
+// /// - 接口`"/api/v5/market/ticker"`
+// ///
+// /// struct SwapTicker
+// /// - `inst_type`: String, 产品类型
+// /// - `inst_id`: String, 产品ID
+// /// - `last`: Decimal, 最新成交价
+// /// - `last_sz`: Decimal, 最新成交的数量
+// /// - `ask_px`: Decimal, 卖一价
+// /// - `ask_sz`: Decimal, 卖一价的挂单数数量
+// /// - `bid_px`: Decimal, 买一价
+// /// - `bid_sz`: Decimal, 买一价的挂单数量
+// /// - `open24h`: Decimal, 24小时开盘价
+// /// - `high24h`: Decimal, 24小时最高价
+// /// - `low24h`: Decimal, 24小时最低价
+// /// - `vol_ccy24h`: Decimal, 24小时成交量,以币为单位
+// /// - `vol24h`: Decimal, 24小时成交量,以张为单位
+// /// - `ts`: String, ticker数据产生时间
+// /// - `sod_utc0`: Decimal, UTC 0 时开盘价
+// /// - `sod_utc8`: Decimal, UTC+8 时开盘价
+// #[derive(Debug, Clone, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SwapTicker {
+//     inst_type: String,
+//     inst_id: String,
+//     last: Decimal,
+//     last_sz: Decimal,
+//     ask_px: Decimal,
+//     ask_sz: Decimal,
+//     bid_px: Decimal,
+//     bid_sz: Decimal,
+//     open24h: Decimal,
+//     high24h: Decimal,
+//     low24h: Decimal,
+//     vol_ccy24h: Decimal,
+//     vol24h: Decimal,
+//     ts: String,
+//     sod_utc0: Decimal,
+//     sod_utc8: Decimal,
+// }
+//
+// /// Okx交易所市场信息请求数据结构
+// /// - 接口`"/api/v5/public/instruments"`
+// ///
+// /// struct SwapMarket
+// /// - `alias`: String,
+// /// - `base_ccy`: String,
+// /// - `category`: String,
+// /// - `ct_mult`: Decimal,
+// /// - `ct_type`: String,
+// /// - `ct_val`: Decimal,
+// /// - `ct_val_ccy`: String,
+// /// - `exp_time`: String,
+// /// - `inst_family`: String,
+// /// - `inst_id`: String,
+// /// - `inst_type`: String,
+// /// - `lever`: Decimal,
+// /// - `list_time`: String,
+// /// - `lot_sz`: Decimal,
+// /// - `max_iceberg_sz`: Decimal,
+// /// - `max_lmt_sz`: Decimal,
+// /// - `max_mkt_sz`: Decimal,
+// /// - `max_stop_sz`: Decimal,
+// /// - `max_trigger_sz`: Decimal,
+// /// - `max_twap_sz`: Decimal,
+// /// - `min_sz`: Decimal,
+// /// - `opt_type`: String,
+// /// - `quote_ccy`: String,
+// /// - `settle_ccy`: String,
+// /// - `state`: String,
+// /// - `stk`: String,
+// /// - `tick_sz`: Decimal,
+// /// - `uly`: String,
+// #[derive(Debug, Clone, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct SwapMarket {
+//     alias: String,
+//     base_ccy: String,
+//     category: String,
+//     ct_mult: Decimal,
+//     ct_type: String,
+//     ct_val: Decimal,
+//     ct_val_ccy: String,
+//     exp_time: String,
+//     inst_family: String,
+//     inst_id: String,
+//     inst_type: String,
+//     lever: Decimal,
+//     list_time: String,
+//     lot_sz: Decimal,
+//     max_iceberg_sz: Decimal,
+//     max_lmt_sz: Decimal,
+//     max_mkt_sz: Decimal,
+//     max_stop_sz: Decimal,
+//     max_trigger_sz: Decimal,
+//     max_twap_sz: Decimal,
+//     min_sz: Decimal,
+//     opt_type: String,
+//     quote_ccy: String,
+//     settle_ccy: String,
+//     state: String,
+//     stk: String,
+//     tick_sz: Decimal,
+//     uly: String,
+// }
+//
+// /// Okx交易所订单信息请求数据结构
+// /// - 接口`"/api/v5/trade/order"`
+// ///
+// /// struct SwapOrder
+// /// - `inst_type`: String, 产品类型
+// /// - `inst_id`: String, 产品ID
+// /// - `ccy`: String, 保证金币种
+// /// - `ord_id`: String, 订单ID
+// /// - `cl_ord_id`: String, 客户自定义订单ID
+// /// - `tag`: String, 订单标签
+// /// - `px`: Decimal, 委托价格
+// /// - `px_usd`: String, 期权价格
+// /// - `px_vol`: String, 期权订单的隐含波动率
+// /// - `px_type`: String, 期权的价格类型
+// /// - `sz`: Decimal, 委托数量
+// /// - `pnl`: Decimal, 收益
+// /// - `ord_type`: String, 订单类型
+// /// - `side`: String, 订单方向
+// /// - `pos_side`: String, 持仓方向
+// /// - `td_mode`: String, 交易模式
+// /// - `acc_fill_sz`: Decimal, 累计成交数量
+// /// - `fill_px`: String, 最新成交价格,如果成交数量为0,该字段为""
+// /// - `trade_id`: String, 最新成交ID
+// /// - `fill_sz`: Decimal, 最新成交数量
+// /// - `fill_time`: String, 最新成交时间
+// /// - `source`: String, 订单来源
+// /// - `state`: String, 订单状态
+// /// - `avg_px`: Decimal, 成交均价,如果成交数量为0,该字段也为""
+// /// - `lever`: Decimal, 杠杆倍数
+// /// - `attach_algo_cl_ord_id`: String, 下单附带止盈止损时,客户自定义的策略订单ID
+// /// - `tp_trigger_px`: Decimal, 止盈触发价
+// /// - `tp_trigger_px_type`: String, 止盈触发价类型
+// /// - `tp_ord_px`: Decimal, 止盈委托价
+// /// - `sl_trigger_px`: Decimal, 止损触发价
+// /// - `sl_trigger_px_type`: String, 止损触发价类型
+// /// - `sl_ord_px`: Decimal, 止损委托价
+// /// - `stp_id`: String, 自成交保护ID
+// /// - `stp_mode`: String, 自成交保护模式
+// /// - `fee_ccy`: String, 交易手续费币种
+// /// - `fee`: Decimal, 手续费与返佣
+// /// - `rebate_ccy`: String, 返佣金币种
+// /// - `rebate`: String, 返佣金额,仅适用于币币和杠杆
+// /// - `tgt_ccy`: String, 币币市价单委托数量sz的单位
+// /// - `category`: String, 订单种类
+// /// - `reduce_only`: String, 是否只减仓
+// /// - `cancel_source`: String, 	订单取消来源的原因枚举值代码
+// /// - `cancel_source_reason`: String, 订单取消来源的对应具体原因
+// /// - `quick_mgn_type`: String, 一键借币类型,仅适用于杠杆逐仓的一键借币模式
+// /// - `algo_cl_ord_id`: String, 客户自定义策略订单ID
+// /// - `algo_id`: String, 策略委托单ID,策略订单触发时有值,否则为""
+// /// - `u_time`: String, 订单状态更新时间
+// /// - `c_time`: String, 订单创建时间
+// #[derive(Debug, Clone, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// pub struct SwapOrder {
+//     inst_type: String,
+//     inst_id: String,
+//     ccy: String,
+//     ord_id: String,
+//     cl_ord_id: String,
+//     tag: String,
+//     px: Decimal,
+//     px_usd: String,
+//     px_vol: String,
+//     px_type: String,
+//     sz: Decimal,
+//     pnl: String,
+//     ord_type: String,
+//     side: String,
+//     pos_side: String,
+//     td_mode: String,
+//     acc_fill_sz: Decimal,
+//     fill_px: String,
+//     trade_id: String,
+//     fill_sz: String,
+//     fill_time: String,
+//     source: String,
+//     state: String,
+//     avg_px: String,
+//     lever: String,
+//     attach_algo_cl_ord_id: String,
+//     tp_trigger_px: String,
+//     tp_trigger_px_type: String,
+//     tp_ord_px: String,
+//     sl_trigger_px: String,
+//     sl_trigger_px_type: String,
+//     sl_ord_px: String,
+//     stp_id: String,
+//     stp_mode: String,
+//     fee_ccy: String,
+//     fee: String,
+//     rebate_ccy: String,
+//     rebate: String,
+//     tgt_ccy: String,
+//     category: String,
+//     reduce_only: String,
+//     cancel_source: String,
+//     cancel_source_reason: String,
+//     quick_mgn_type: String,
+//     algo_cl_ord_id: String,
+//     algo_id: String,
+//     u_time: String,
+//     c_time: String,
+// }
+//
+// #[allow(dead_code)]
+// #[derive(Clone)]
+// pub struct OkxSwap {
+//     exchange: ExchangeEnum,
+//     symbol: String,
+//     is_colo: bool,
+//     params: BTreeMap<String, String>,
+//     request: OkxSwapRest,
+//     market: Market,
+//     order_sender: Sender<Order>,
+//     error_sender: Sender<Error>,
+// }
+//
+// impl OkxSwap {
+//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> OkxSwap {
+//         let market = Market::new();
+//         let mut okx_swap = OkxSwap {
+//             exchange: ExchangeEnum::OkxSwap,
+//             symbol: symbol.to_uppercase(),
+//             is_colo,
+//             params: params.clone(),
+//             request: OkxSwapRest::new(is_colo, params.clone()),
+//             market,
+//             order_sender,
+//             error_sender,
+//         };
+//         okx_swap.market = OkxSwap::get_market(&mut okx_swap).await.unwrap_or(okx_swap.market);
+//         return okx_swap;
+//     }
+// }
+//
+// #[async_trait]
+// impl Platform for OkxSwap {
+//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
+//
+//     fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::OkxSwap }
+//
+//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
+//
+//     fn get_self_is_colo(&self) -> bool { self.is_colo }
+//
+//     fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
+//
+//     fn get_self_market(&self) -> Market { self.market.clone() }
+//
+//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
+//
+//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
+//
+//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
+//
+//     async fn get_server_time(&mut self) -> Result<String, Error> {
+//         let res_data = self.request.get_server_time().await;
+//         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 = res_data_json[0]["ts"].as_str().unwrap().to_string();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_account(&mut self) -> Result<Account, Error> {
+//         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
+//         let res_data = self.request.get_balance(symbol_array[1].to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let balance_info_list: Vec<SwapAccount> = serde_json::from_str(res_data_str).unwrap();
+//             let detail = balance_info_list[0].details.iter().find(|&item| item.ccy == symbol_array[1]);
+//             match detail {
+//                 None => {
+//                     error!("Okx:获取Account信息错误!\nhandle_swap_account:res_data={:?}", res_data);
+//                     panic!("Okx:获取Account信息错误!\nhandle_swap_account:res_data={:?}", res_data)
+//                 }
+//                 Some(value) => {
+//                     let result = Account {
+//                         coin: value.ccy.to_uppercase(),
+//                         balance: value.avail_bal + value.fixed_bal,
+//                         available_balance: value.avail_bal,
+//                         frozen_balance: value.fixed_bal,
+//                         stocks: Decimal::ZERO,
+//                         available_stocks: Decimal::ZERO,
+//                         frozen_stocks: Decimal::ZERO,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.to_string(), "-"));
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_positions("SWAP".to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let data_list: Vec<SwapPosition> = serde_json::from_str(&res_data_str).unwrap();
+//             let position_info: Vec<&SwapPosition> = data_list.iter().filter(|item| item.inst_id == symbol_format).collect();
+//             let result = position_info.iter().map(|item| format_position_item(item, ct_val)).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
+//         let res_data = self.request.get_positions("SWAP".to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let data_list: Vec<SwapPosition> = serde_json::from_str(&res_data_str).unwrap();
+//             let result = data_list.iter().map(|item| format_position_item(item, Decimal::ONE)).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
+//         let res_data = self.request.get_ticker(symbol_format.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let ticker_info_list: Vec<SwapTicker> = serde_json::from_str(&res_data_str).unwrap();
+//             let ticker_info = ticker_info_list.iter().find(|item| item.inst_id == symbol_format);
+//             match ticker_info {
+//                 None => {
+//                     error!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str);
+//                     panic!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str)
+//                 }
+//                 Some(value) => {
+//                     let result = Ticker {
+//                         time: value.ts.parse().unwrap(),
+//                         high: value.high24h,
+//                         low: value.low24h,
+//                         sell: value.ask_px,
+//                         buy: value.bid_px,
+//                         last: value.last,
+//                         volume: value.last_sz,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(symbol.clone(), "-"));
+//         let res_data = self.request.get_ticker(symbol_format.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let ticker_info_list: Vec<SwapTicker> = serde_json::from_str(&res_data_str).unwrap();
+//             let ticker_info = ticker_info_list.iter().find(|item| item.inst_id == symbol_format);
+//             match ticker_info {
+//                 None => {
+//                     error!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str);
+//                     panic!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str)
+//                 }
+//                 Some(value) => {
+//                     let result = Ticker {
+//                         time: value.ts.parse().unwrap(),
+//                         high: value.high24h,
+//                         low: value.low24h,
+//                         sell: value.ask_px,
+//                         buy: value.bid_px,
+//                         last: value.last,
+//                         volume: value.last_sz,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market(&mut self) -> Result<Market, Error> {
+//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
+//         let res_data = self.request.get_instruments().await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Vec<SwapMarket> = serde_json::from_str(res_data_str).unwrap();
+//             let market_info = res_data_json.iter().find(|item| item.inst_id == format!("{}-SWAP", symbol_format));
+//             match market_info {
+//                 None => {
+//                     error!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str);
+//                     panic!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str)
+//                 }
+//                 Some(value) => {
+//                     println!("{:?}", value);
+//                     let symbol_array: Vec<&str> = value.inst_family.split("-").collect();
+//                     let result = Market {
+//                         symbol: format!("{}_{}", symbol_array[0], symbol_array[1]),
+//                         base_asset: symbol_array[0].to_string(),
+//                         quote_asset: symbol_array[1].to_string(),
+//                         tick_size: value.tick_sz,
+//                         amount_size: value.min_sz * value.ct_val,
+//                         price_precision: Decimal::from_u32(value.tick_sz.scale()).unwrap(),
+//                         amount_precision: Decimal::from_u32((value.min_sz * value.ct_val).scale()).unwrap(),
+//                         min_qty: value.min_sz,
+//                         max_qty: value.max_lmt_sz,
+//                         min_notional: value.min_sz * value.ct_val,
+//                         max_notional: value.max_lmt_sz * value.ct_val,
+//                         ct_val: value.ct_val,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
+//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
+//         let res_data = self.request.get_instruments().await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Vec<SwapMarket> = serde_json::from_str(res_data_str).unwrap();
+//             let market_info = res_data_json.iter().find(|item| item.inst_id == format!("{}-SWAP", symbol_format));
+//             match market_info {
+//                 None => {
+//                     error!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str);
+//                     panic!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str)
+//                 }
+//                 Some(value) => {
+//                     let symbol_array: Vec<&str> = value.inst_family.split("-").collect();
+//                     let result = Market {
+//                         symbol: format!("{}_{}", symbol_array[0], symbol_array[1]),
+//                         base_asset: symbol_array[0].to_string(),
+//                         quote_asset: symbol_array[1].to_string(),
+//                         tick_size: value.tick_sz,
+//                         amount_size: value.min_sz * value.ct_val,
+//                         price_precision: Decimal::from_u32(value.tick_sz.scale()).unwrap(),
+//                         amount_precision: Decimal::from_u32((value.min_sz * value.ct_val).scale()).unwrap(),
+//                         min_qty: value.min_sz,
+//                         max_qty: value.max_lmt_sz,
+//                         min_notional: value.min_sz * value.ct_val,
+//                         max_notional: value.max_lmt_sz * value.ct_val,
+//                         ct_val: value.ct_mult,
+//                     };
+//                     Ok(result)
+//                 }
+//             }
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_order(symbol_format, order_id.to_string(), custom_id.to_string()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Vec<SwapOrder> = serde_json::from_str(res_data_str).unwrap();
+//             let order_info = res_data_json[0].clone();
+//             let result = format_order_item(order_info, ct_val);
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
+//         let ct_val = self.market.ct_val;
+//         let res_data = self.request.get_incomplete_order(symbol_format.clone()).await;
+//         if res_data.code == "200" {
+//             let res_data_str = &res_data.data;
+//             let res_data_json: Vec<SwapOrder> = serde_json::from_str(res_data_str).unwrap();
+//             let result = res_data_json.iter().map(|item| format_order_item(item.clone(), ct_val)).collect();
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
+//         let ct_val = self.market.ct_val;
+//         let mut params = json!({
+//             "tdMode": "cross",
+//             "clOrdId": custom_id.to_string(),
+//             "instId": symbol_format,
+//             "px": price.to_string(),
+//         });
+//         params["ordType"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
+//         let size = (amount / ct_val).floor();
+//         params["sz"] = json!(size);
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//                 params["posSide"] = json!("long");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//                 params["posSide"] = json!("long");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//                 params["posSide"] = json!("short");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//                 params["posSide"] = json!("short");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.swap_order(params).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 = res_data_json[0].clone();
+//             let id = order_info["ordId"].as_str().unwrap().to_string();
+//             let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
+//             let result = Order {
+//                 id,
+//                 custom_id,
+//                 price,
+//                 amount,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("799 okx_swap".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(symbol.clone(), "-"));
+//         let mut params = json!({
+//             "tdMode": "cross",
+//             "clOrdId": custom_id.to_string(),
+//             "instId": symbol_format,
+//             "px": price.to_string(),
+//         });
+//         params["ordType"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
+//         let size = (amount / ct_val).floor();
+//         params["sz"] = json!(size);
+//         match origin_side {
+//             "kd" => {
+//                 params["side"] = json!("buy");
+//                 params["posSide"] = json!("long");
+//             }
+//             "pd" => {
+//                 params["side"] = json!("sell");
+//                 params["posSide"] = json!("long");
+//             }
+//             "kk" => {
+//                 params["side"] = json!("sell");
+//                 params["posSide"] = json!("short");
+//             }
+//             "pk" => {
+//                 params["side"] = json!("buy");
+//                 params["posSide"] = json!("short");
+//             }
+//             _ => { error!("下单参数错误"); }
+//         };
+//         let res_data = self.request.swap_order(params).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 = res_data_json[0].clone();
+//             let id = order_info["ordId"].as_str().unwrap().to_string();
+//             let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
+//             let result = Order {
+//                 id,
+//                 custom_id,
+//                 price,
+//                 amount,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "NEW".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("853 okx_swap".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
+//         let res_data = self.request.cancel_order(symbol_format, order_id.to_string(), custom_id.to_string()).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 = res_data_json[0].clone();
+//             let id = order_info["ordId"].as_str().unwrap().to_string();
+//             let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
+//             let result = Order {
+//                 id,
+//                 custom_id,
+//                 price: Decimal::ZERO,
+//                 amount: Decimal::ZERO,
+//                 deal_amount: Decimal::ZERO,
+//                 avg_price: Decimal::ZERO,
+//                 status: "REMOVE".to_string(),
+//                 order_type: "".to_string(),
+//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("879 okx_swap".to_string()),
+//             };
+//             Ok(result)
+//         } else {
+//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
+//         }
+//     }
+//
+//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
+//         Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
+//     }
+//
+//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
+//         let res_data = self.request.set_position_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.to_string()))
+//         }
+//     }
+//
+//     async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
+//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
+//         let res_data = self.request.set_leverage(symbol_format, 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.to_string()))
+//         }
+//     }
+//
+//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string())) }
+//
+//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string())) }
+//
+//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
+//         let mut handles = vec![];
+//         // 撤销订单
+//         let cancel = order_command.cancel;
+//         for item in cancel.keys() {
+//             let mut self_clone = self.clone();
+//             let cancel_clone = cancel.clone();
+//             let item_clone = item.clone();
+//             let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 if order_id != "" {
+//                     let result = self_clone.cancel_order(&order_id, &custom_id).await;
+//                     match result {
+//                         Ok(_) => {
+//                             // result_sd.send(result).await.unwrap();
+//                         }
+//                         Err(error) => {
+//                             // 取消失败去查订单。
+//                             let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                             match query_rst {
+//                                 Ok(order) => {
+//                                     result_sd.send(order).await.unwrap();
+//                                 }
+//                                 Err(query_err) => {
+//                                     error!(?query_err);
+//                                     error!("撤单失败,而且查单也失败了,okx_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
+//                                 }
+//                             }
+//                             err_sd.send(error).await.unwrap();
+//                         }
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 下单指令
+//         let mut limits = HashMap::new();
+//         limits.extend(order_command.limits_open);
+//         limits.extend(order_command.limits_close);
+//         for item in limits.keys() {
+//             let mut self_clone = self.clone();
+//             let limits_clone = limits.clone();
+//             let item_clone = item.clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let ts = trace_stack.clone();
+//
+//             let handle = tokio::spawn(async move {
+//                 let value = limits_clone[&item_clone].clone();
+//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
+//                 let side = value.get(1).unwrap();
+//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
+//                 let cid = value.get(3).unwrap();
+//
+//                 //  order_name: [数量,方向,价格,c_id]
+//                 let result = self_clone.take_order(cid, side, price, amount).await;
+//                 match result {
+//                     Ok(mut result) => {
+//                         // ts.on_after_send();
+//                         result.trace_stack = ts.clone();
+//
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         let mut err_order = Order::new();
+//                         err_order.custom_id = cid.clone();
+//                         err_order.status = "REMOVE".to_string();
+//
+//                         result_sd.send(err_order).await.unwrap();
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//         // 检查订单指令
+//         let check = order_command.check;
+//         for item in check.keys() {
+//             let mut self_clone = self.clone();
+//             let check_clone = check.clone();
+//             let item_clone = item.clone();
+//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
+//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
+//             let result_sd = self.order_sender.clone();
+//             let err_sd = self.error_sender.clone();
+//             let handle = tokio::spawn(async move {
+//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
+//                 match result {
+//                     Ok(result) => {
+//                         result_sd.send(result).await.unwrap();
+//                     }
+//                     Err(error) => {
+//                         err_sd.send(error).await.unwrap();
+//                     }
+//                 }
+//             });
+//             handles.push(handle)
+//         }
+//
+//         let futures = FuturesUnordered::from_iter(handles);
+//         let _: Result<Vec<_>, _> = futures.try_collect().await;
+//     }
+// }
+//
+// pub fn format_order_item(data: SwapOrder, ct_val: Decimal) -> Order {
+//     debug!("format-order-start, okx_swap");
+//     debug!(?data);
+//     let custom_status = if ["canceled", "filled", "mmp_canceled"].contains(&data.state.as_str()) {
+//         "REMOVE".to_string()
+//     } else if ["live", "partially_filled"].contains(&data.state.as_str()) {
+//         "NEW".to_string()
+//     } else {
+//         "NULL".to_string()
+//     };
+//
+//     let result = Order {
+//         id: data.ord_id,
+//         custom_id: data.cl_ord_id,
+//         price: data.px,
+//         amount: data.sz * ct_val,
+//         deal_amount: data.acc_fill_sz * ct_val,
+//         avg_price: if data.avg_px != "" { Decimal::from_str(&data.avg_px).unwrap() } else { Decimal::ZERO },
+//         status: custom_status,
+//         order_type: data.ord_type,
+//         trace_stack: TraceStack::new(0, Instant::now()).on_special("1049 okx_swap".to_string()),
+//     };
+//     debug!(?result);
+//     debug!("format-order-end, okx_swap");
+//     result
+// }
+//
+// pub fn format_position_item(value: &SwapPosition, ct_val: Decimal) -> Position {
+//     let position_mode = match value.pos_side.as_str() {
+//         "long" => { PositionModeEnum::Long }
+//         "short" => { PositionModeEnum::Short }
+//         _ => { PositionModeEnum::Both }
+//     };
+//     Position {
+//         symbol: value.inst_id.replace("-SWAP", ""),
+//         margin_level: value.lever,
+//         amount: value.pos * ct_val,
+//         frozen_amount: Decimal::ZERO,
+//         price: value.avg_px,
+//         profit: value.upl,
+//         position_mode,
+//         margin: if value.margin != "" { Decimal::from_str(&value.margin).unwrap() } else { Decimal::ZERO },
+//     }
+// }

+ 31 - 32
standard/src/utils.rs

@@ -1,6 +1,5 @@
 use tracing::trace;
 use exchanges::proxy;
-use crate::exchange::ExchangeEnum;
 
 /// 修改交易对连接符号
 /// - `symbol(str)`: 交易对, "BTC_USDT", 默认以下划线传递
@@ -16,34 +15,34 @@ pub fn proxy_handle() {
     }
 }
 
-/// 币种映射器
-#[allow(dead_code)]
-pub fn symbol_enter_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
-    let symbol_upper = symbol.to_uppercase();
-    match exchange_enum {
-        ExchangeEnum::KucoinSwap => {
-            if symbol_upper.contains("BTC") {
-                symbol_upper.replace("BTC", "XBT")
-            } else { symbol_upper.to_string() }
-        }
-        _ => {
-            symbol_upper.to_string()
-        }
-    }
-}
-
-/// 币种映射器
-#[allow(dead_code)]
-pub fn symbol_out_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
-    let symbol_upper = symbol.to_uppercase();
-    match exchange_enum {
-        ExchangeEnum::KucoinSwap => {
-            if symbol_upper.contains("XBT") {
-                symbol_upper.replace("XBT", "BTC")
-            } else { symbol_upper.to_string() }
-        }
-        _ => {
-            symbol_upper.to_string()
-        }
-    }
-}
+// /// 币种映射器
+// #[allow(dead_code)]
+// pub fn symbol_enter_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
+//     let symbol_upper = symbol.to_uppercase();
+//     match exchange_enum {
+//         ExchangeEnum::KucoinSwap => {
+//             if symbol_upper.contains("BTC") {
+//                 symbol_upper.replace("BTC", "XBT")
+//             } else { symbol_upper.to_string() }
+//         }
+//         _ => {
+//             symbol_upper.to_string()
+//         }
+//     }
+// }
+//
+// /// 币种映射器
+// #[allow(dead_code)]
+// pub fn symbol_out_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
+//     let symbol_upper = symbol.to_uppercase();
+//     match exchange_enum {
+//         ExchangeEnum::KucoinSwap => {
+//             if symbol_upper.contains("XBT") {
+//                 symbol_upper.replace("XBT", "BTC")
+//             } else { symbol_upper.to_string() }
+//         }
+//         _ => {
+//             symbol_upper.to_string()
+//         }
+//     }
+// }

+ 19 - 19
strategy/src/core.rs

@@ -22,7 +22,7 @@ use global::public_params::{ASK_PRICE_INDEX, BID_PRICE_INDEX, LENGTH};
 use global::trace_stack::TraceStack;
 use standard::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, SpecialTicker, Ticker};
 use standard::exchange::{Exchange};
-use standard::exchange::ExchangeEnum::{BinanceSpot, BinanceSwap, BitgetSpot, BybitSwap, GateSpot, GateSwap, KucoinSwap, OkxSwap};
+use standard::exchange::ExchangeEnum::{BinanceSwap, GateSwap};
 
 use crate::model::{LocalPosition, OrderInfo, OriginalTradeBa, TokenParam, TraderMsg};
 use crate::predictor::Predictor;
@@ -208,30 +208,30 @@ impl Core {
                 amount_size: Default::default(),
             },
             platform_rest: match exchange.as_str() {
-                "kucoin_usdt_swap" => {
-                    Exchange::new(KucoinSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
+                // "kucoin_usdt_swap" => {
+                //     Exchange::new(KucoinSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
+                // }
                 "gate_usdt_swap" => {
                     Exchange::new(GateSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
                 }
-                "gate_usdt_spot" => {
-                    Exchange::new(GateSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
+                // "gate_usdt_spot" => {
+                //     Exchange::new(GateSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
+                // }
                 "binance_usdt_swap" => {
                     Exchange::new(BinanceSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
                 }
-                "binance_spot" => {
-                    Exchange::new(BinanceSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
-                "bitget_spot" => {
-                    Exchange::new(BitgetSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
-                "okex_usdt_swap" => {
-                    Exchange::new(OkxSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
-                "bybit_usdt_swap" => {
-                    Exchange::new(BybitSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
+                // "binance_spot" => {
+                //     Exchange::new(BinanceSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
+                // }
+                // "bitget_spot" => {
+                //     Exchange::new(BitgetSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
+                // }
+                // "okex_usdt_swap" => {
+                //     Exchange::new(OkxSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
+                // }
+                // "bybit_usdt_swap" => {
+                //     Exchange::new(BybitSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
+                // }
                 _ => {
                     error!("203未找到对应的交易所rest枚举!");
                     panic!("203未找到对应的交易所rest枚举!");

+ 1 - 2
strategy/src/gate_swap.rs

@@ -3,7 +3,6 @@ use std::collections::BTreeMap;
 use std::sync::Arc;
 use std::sync::atomic::AtomicBool;
 use rust_decimal::Decimal;
-use serde_json::Value;
 use tokio::spawn;
 use tokio::sync::Mutex;
 use tokio::time::Instant;
@@ -35,7 +34,7 @@ pub async fn gate_swap_run(is_shutdown_arc: Arc<AtomicBool>,
         let res_data = gate_exc.wallet_fee().await;
         assert_eq!(res_data.code, "200", "获取gate交易所参数 user_id 失败, 启动失败!");
 
-        let wallet_obj :Value = serde_json::from_str(&res_data.data).unwrap();
+        let wallet_obj = res_data.data;
         info!(?wallet_obj);
         user_id = wallet_obj["user_id"].to_string();
     }