// 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, // delays: Vec, // max_delay: i64, // avg_delay: Decimal, // } // // impl KucoinSwapRest { // /*******************************************************************************************************/ // /*****************************************获取一个对象****************************************************/ // /*******************************************************************************************************/ // // pub fn new(is_colo: bool, login_param: BTreeMap) -> 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) -> 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 { // 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_tool( // 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::::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::::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_tool(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result { // 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(¶ms), // _ => 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, 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 // } // } // } // }