hl 1 gadu atpakaļ
vecāks
revīzija
fcdc83f3a7
3 mainītis faili ar 145 papildinājumiem un 28 dzēšanām
  1. 5 3
      src/handle_ticker.rs
  2. 10 0
      src/okx_swap/okx_swap_rest.rs
  3. 130 25
      src/okx_swap/okx_swap_standard.rs

+ 5 - 3
src/handle_ticker.rs

@@ -96,7 +96,9 @@ pub async fn get_binance_ticker_info(symbol: &str, start_at: &str, end_at: &str)
 }
 
 pub(crate) async fn get_okx_ticker_info(symbol: &str, start_at: &str, end_at: &str) -> Vec<Trades> {
-    let mut start_at_d = Decimal::from_str(start_at).unwrap();
+    let ct_val = okx_swap_standard::standard_ct_val(symbol).await;
+
+    let  start_at_d = Decimal::from_str(start_at).unwrap();
     let end_at_d = Decimal::from_str(end_at).unwrap();
 
     // let end_time = if end_at_d - start_at_d > dec!(3600) { (start_at_d + dec!(3600)).to_string() } else { end_at_d.to_string() };
@@ -108,7 +110,7 @@ pub(crate) async fn get_okx_ticker_info(symbol: &str, start_at: &str, end_at: &s
     info!("当前时间---{:?}---{:?}",start_at,end_at);
 
     let mut list_array: Vec<Trades> = vec![];
-    let ticker_one = okx_swap_standard::standard_history_candles(symbol, "", end_at_d_str.as_str()).await.unwrap();
+    let ticker_one = okx_swap_standard::standard_history_candles(symbol, "", end_at_d_str.as_str(), &ct_val).await.unwrap();
     if ticker_one.len() > 0 {
         let ticker_0 = ticker_one.get(0).cloned();
         let ticker_size = ticker_one.get(ticker_one.len() - 1).cloned();
@@ -125,7 +127,7 @@ pub(crate) async fn get_okx_ticker_info(symbol: &str, start_at: &str, end_at: &s
                 let start_at_str = format!("{}000", start_at);
                 // info!("比较:{:?}-{:?}",start_at_str , create_time_size);
                 if start_at_str < create_time_size {
-                    let ticker_one2 = okx_swap_standard::standard_history_candles(symbol, "", create_time_size.as_ref()).await.unwrap();
+                    let ticker_one2 = okx_swap_standard::standard_history_candles(symbol, "", create_time_size.as_ref(), &ct_val).await.unwrap();
 
                     let ticker_0_2 = ticker_one2.get(0).cloned();
                     let ticker_size_2 = ticker_one2.get(ticker_one.len() - 1).cloned();

+ 10 - 0
src/okx_swap/okx_swap_rest.rs

@@ -15,3 +15,13 @@ pub async fn get_history_trades(symbol: &str,start_at: &str, end_at: &str) -> Re
     get(url, params.to_string(), None).await
 }
 
+
+//查阅所有交易币对的 基础信息
+pub async fn get_symbol_dateils_all() -> Response {
+    let url = "https://www.okx.com/api/v5/public/instruments";
+    let  params = serde_json::json!({
+        "instType":"SWAP"
+    });
+    get(url, params.to_string(), None).await
+}
+

+ 130 - 25
src/okx_swap/okx_swap_standard.rs

@@ -1,9 +1,8 @@
 use std::io::{Error, ErrorKind};
 
 use serde::{Deserialize, Serialize};
-use tracing::info;
 
-use crate::okx_swap::okx_swap_rest::get_history_trades;
+use crate::okx_swap::okx_swap_rest::{get_history_trades, get_symbol_dateils_all};
 use crate::struct_standard::Trades;
 
 #[derive(Debug, Deserialize, Serialize)]
@@ -22,8 +21,8 @@ pub struct SwapTrades {
     ts: String,//成交时间,Unix时间戳的毫秒数格式, 如1597026383085
 }
 
-pub(crate) async fn standard_history_candles(symbol: &str, start_at: &str, end_at: &str) -> Result<Vec<Trades>, Error> {
-    let mut symbol_fmt = symbol.replace("_", "-").clone();
+pub(crate) async fn standard_history_candles(symbol: &str, start_at: &str, end_at: &str, ct_val: &i64) -> Result<Vec<Trades>, Error> {
+    let mut symbol_fmt = format!("{}-SWAP", symbol.replace("_", "-").clone());
     symbol_fmt = symbol_fmt.to_uppercase();
 
 
@@ -39,41 +38,147 @@ pub(crate) async fn standard_history_candles(symbol: &str, start_at: &str, end_a
 
             let ticker_list: Vec<SwapTrades> = serde_json::from_str(data.to_string().as_str()).unwrap();
             ticker_list.iter().map(|item| {
-                let side = item.side.to_string();
-                let size_str = if item.side.as_str() == "sell" {
-                    format!("-{}", item.sz.clone())
+                let mut size_i: i64 = item.sz.clone().parse().expect("Not a valid number");
+                if item.side.as_str() == "sell" {
+                    size_i = -size_i;
                 } else if item.side.as_str() == "buy" {
-                    format!("{}", item.sz.clone())
-                } else {
-                    format!("??????")
-                };
+                    size_i = size_i;
+                }
 
                 Trades {
                     id: item.trade_id.to_string(),
                     symbol: symbol.to_string(),
                     create_time: item.ts.to_string(),
-                    size: size_str,
+                    size: (size_i * ct_val).to_string(),
                     price: item.px.clone(),
                 }
             }).collect()
         } else {
             vec![]
         };
-        // let result = trades_list.iter().map(|item| {
-        //     //
-        //     // ite
-        //     // AggTrades {
-        //     //     id: item.a.to_string(),
-        //     //     start_id: item.f.to_string(),
-        //     //     end_id: item.l.to_string(),
-        //     //     symbol: symbol.to_string(),
-        //     //     create_time: item.t.to_string(),
-        //     //     size: item.q.to_string(),
-        //     //     price: item.p.clone(),
-        //     // }
-        // }).collect();
         Ok(result)
     } else {
         Err(Error::new(ErrorKind::Other, res_data.to_string()))
     }
 }
+
+#[derive(Debug, Deserialize, Serialize, Clone)]
+#[serde(rename_all = "camelCase")]
+#[allow(non_snake_case)]
+pub struct SwapSymbolDateils {
+    instType: String,
+    //    产品类型
+    instId: String,
+    //    产品id, 如 BTC-USD-SWAP
+    uly: String,
+    //    标的指数,如 BTC-USD,仅适用于交割/永续/期权
+    instFamily: String,
+    //    交易品种,如 BTC-USD,仅适用于交割/永续/期权
+    category: String,
+    //    币种类别(已废弃)
+    baseCcy: String,
+    //   交易货币币种,如 BTC-USDT 中的 BTC ,仅适用于币币/币币杠杆
+    quoteCcy: String,
+    //   计价货币币种,如 BTC-USDT 中的USDT ,仅适用于币币/币币杠杆
+    settleCcy: String,
+    //   盈亏结算和保证金币种,如 BTC 仅适用于交割/永续/期权
+    ctVal: String,
+    //  合约面值,仅适用于交割/永续/期权
+    ctMult: String,
+    //   合约乘数,仅适用于交割/永续/期权
+    ctValCcy: String,
+    //  合约面值计价币种,仅适用于交割/永续/期权
+    optType: String,
+    //   期权类型,C或P 仅适用于期权
+    stk: String,
+    //  行权价格,仅适用于期权
+    listTime: String,
+    //  上线时间   Unix时间戳的毫秒数格式,如 1597026383085
+    expTime: String,
+    //   产品下线时间   适用于币币/杠杆/交割/永续/期权,对于 交割/期权,为交割/行权日期;亦可以为产品下线时间,有变动就会推送。
+    lever: String,
+    //   该instId支持的最大杠杆倍数,不适用于币币、期权
+    tickSz: String,
+    //   下单价格精度,如 0.0001     对于期权来说,是梯度中的最小下单价格精度,如果想要获取期权价格梯度,请使用"获取期权价格梯度"接口
+    lotSz: String,
+    //   下单数量精度,如 BTC-USDT-SWAP:1
+    minSz: String,
+    //   最小下单数量,    合约的数量单位是“张”,现货的数量单位是“交易货币”
+    ctType: String,
+    //  linear:正向合约 inverse:反向合约   仅适用于交割/永续
+    alias: String,
+    //    合约日期别名
+    // this_week:本周
+    // next_week:次周
+    // this_month:本月
+    // next_month:次月
+    // quarter:季度
+    // next_quarter:次季度
+    // 仅适用于交割
+    // 不建议使用,用户应通过 expTime 字段获取合约的交割日期
+    state: String,
+    //     产品状态
+    // live:交易中
+    // suspend:暂停中
+    // preopen:预上线,如:交割和期权的新合约在 live 之前,会有 preopen 状态
+    // test:测试中(测试产品,不可交易)
+    maxLmtSz: String,
+    //    合约或现货限价单的单笔最大委托数量,   合约的数量单位是“张”,现货的数量单位是“交易货币”
+    maxMktSz: String,
+    //    合约或现货市价单的单笔最大委托数量,   合约的数量单位是“张”,现货的数量单位是“USDT”
+    maxLmtAmt: String,
+    //    限价单的单笔最大USD价值
+    maxMktAmt: String,
+    //    市价单的单笔最大USD价值    仅适用于币币/币币杠杆
+    maxTwapSz: String,
+    //    合约或现货时间加权单的单笔最大委托数量,  合约的数量单位是“张”,现货的数量单位是“交易货币”
+    maxIcebergSz: String,
+    //    合约或现货冰山委托的单笔最大委托数量,  合约的数量单位是“张”,现货的数量单位是“交易货币”
+    maxTriggerSz: String,
+    //     合约或现货计划委托委托的单笔最大委托数量,   合约的数量单位是“张”,现货的数量单位是“交易货币”
+    maxStopSz: String,//     合约或现货止盈止损市价委托的单笔最大委托数量,   合约的数量单位是“张”,现货的数量单位是“USDT”
+}
+
+pub(crate) async fn standard_symbol_dateils(symbol: &str) -> Result<Option<SwapSymbolDateils>, Error> {
+    let mut symbol_fmt = symbol.replace("_", "-").clone();
+    symbol_fmt = symbol_fmt.to_uppercase();
+    let ct_val_ccy_array: Vec<&str> = symbol_fmt.split("-").collect();
+    let symbol_name = ct_val_ccy_array[0];
+
+
+    let res_data = get_symbol_dateils_all().await;
+    if res_data.code == "200" {
+        let res_data_str = res_data.data;
+        let json_value: serde_json::Value = serde_json::from_str(&res_data_str).unwrap();
+
+        if json_value.get("code").is_some() && json_value["code"] == "0" {
+            let data = json_value.get("data").unwrap();
+            // info!("data:{:?}",data.to_string().as_str());
+            let symbol_dateils_all: Vec<SwapSymbolDateils> = serde_json::from_str(data.to_string().as_str()).unwrap();
+
+            for symbol_dateils in symbol_dateils_all {
+                if symbol_name == symbol_dateils.ctValCcy.as_str() {
+                    return Ok(Option::from(symbol_dateils));
+                }
+            }
+        }
+        Ok(None)
+    } else {
+        Err(Error::new(ErrorKind::Other, res_data.to_string()))
+    }
+}
+
+pub async fn standard_ct_val(symbol: &str) -> i64 {
+    match standard_symbol_dateils(symbol).await.unwrap() {
+        None => {
+            1
+        }
+        Some(d) => {
+            let num: i64 = d.ctVal.parse().expect("Not a valid number");
+            num
+        }
+    }
+}
+
+
+