Browse Source

添加coinex导出

gepangpang 8 months ago
parent
commit
27a1b8970c

+ 108 - 0
derive/src/coinex_swap_export.rs

@@ -0,0 +1,108 @@
+use std::collections::BTreeMap;
+use std::str::FromStr;
+use async_trait::async_trait;
+use chrono::{FixedOffset, NaiveDateTime, TimeZone};
+use rust_decimal::Decimal;
+use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
+use rust_decimal_macros::dec;
+use serde::{Deserialize, Serialize};
+use tracing::{trace, warn};
+use exchanges::coinex_swap_rest::CoinexSwapRest;
+use standard::utils;
+use crate::ExportConnector;
+
+pub struct CoinexSwapExport {
+    request: CoinexSwapRest,
+}
+
+impl CoinexSwapExport {
+    pub async fn new(_is_colo: bool, params: BTreeMap<String, String>) -> CoinexSwapExport {
+        CoinexSwapExport {
+            request: CoinexSwapRest::new(params.clone())
+        }
+    }
+}
+
+/// TradesSwap
+/// - `id`: i64, 成交记录 ID
+/// - `create_time`: i64, 成交时间
+/// - `contract`: String, 合约标识
+/// - `order_id`: String, 成交记录关联订单 ID
+/// - `size`: i64, 成交数量
+/// - `price`: String, 成交价格
+/// - `text`: String, 成交角色, taker - 吃单, maker - 做单
+/// - `fee`: String, 订单的自定义信息
+/// - `point_fee`: String, 成交手续费
+/// - `role`: String, 成交点卡手续费
+#[derive(Debug, Deserialize, Serialize)]
+struct TradesSwap {
+    order_id: i64,
+    market: String,
+    market_type: String,
+    side: String,
+    #[serde(rename = "type")]
+    trade_type: String,
+    amount: String,
+    price: String,
+    unfilled_amount: String,
+    filled_amount: String,
+    filled_value: String,
+    client_id: String,
+    fee: String,
+    fee_ccy: String,
+    maker_fee_rate: String,
+    taker_fee_rate: String,
+    created_at: i64,
+    updated_at: i64,
+}
+
+#[async_trait]
+impl ExportConnector for CoinexSwapExport {
+    async fn export_trades(&mut self, prefix_name: &str, symbol: String, start_time: i64, end_time: i64, limit: i64) -> String {
+        let symbol_format = utils::format_symbol(symbol.clone(), "");
+        let limit_params = if limit > 1000 {
+            warn!("查询条数最大为1000条,已修改为1000条!");
+            1000
+        } else { limit };
+        let mut data_array = vec![];
+        let mut page = 1;
+        loop {
+            let res_data = self.request.finished_order(symbol_format.clone(), page, limit_params).await;
+            if res_data.code == 200 {
+                let trades_info: Vec<TradesSwap> = serde_json::from_str(&res_data.data.to_string()).unwrap();
+                for value in trades_info.iter() {
+                    let size = Decimal::from_str(&value.amount).unwrap();
+                    let create_time = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.created_at).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+                    let update_time = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.updated_at).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+                    data_array.push(vec![
+                        value.client_id.clone(),
+                        value.order_id.to_string(),
+                        value.market.clone(),
+                        value.side.clone(),
+                        value.price.clone(),
+                        size.abs().to_string(),
+                        value.filled_value.clone(),
+                        value.fee.clone(),
+                        create_time,
+                        update_time,
+                    ]);
+                }
+                let last_time = (trades_info.last().unwrap().created_at).to_i64().unwrap();
+                if last_time < start_time {
+                    data_array = data_array.iter().filter(|item| {
+                        let last_time = NaiveDateTime::parse_from_str(item.last().unwrap(), "%Y-%m-%d %H:%M:%S%.3f")
+                            .unwrap()
+                            .timestamp_millis();
+                        last_time > start_time && last_time < end_time
+                    }).cloned().collect();
+                    break;
+                } else {
+                    page = page + 1;
+                }
+            }
+        }
+        let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "成交价格", "成交数量", "成交价值", "交易费用", "创建时间", "成交时间"];
+        let data_array_rev: Vec<Vec<String>> = data_array.iter().rev().cloned().collect();
+        global::export_utils::export_excel(header_array, data_array_rev, prefix_name)
+    }
+}

+ 5 - 0
derive/src/export_excel.rs

@@ -2,6 +2,7 @@ use std::collections::BTreeMap;
 use crate::binance_swap_export::BinanceSwapExport;
 use crate::bybit_swap_export::BybitSwapExport;
 use crate::bitget_swap_export::BitgetSwapExport;
+use crate::coinex_swap_export::CoinexSwapExport;
 // use crate::bitget_spot_export::BitgetSpotExport;
 use crate::ExportConnector;
 use crate::gate_swap_export::GateSwapExport;
@@ -17,6 +18,7 @@ pub enum ExportEnum {
     GateSwap,
     BybitSwap,
     BitgetSwap,
+    CoinexSwap,
     // BitgetSpot,
     // OkxSwap,
 }
@@ -45,6 +47,9 @@ impl ExportExcel {
             ExportEnum::BitgetSwap => {
                 Box::new(BitgetSwapExport::new(is_colo, params).await)
             }
+            ExportEnum::CoinexSwap=>{
+                Box::new(CoinexSwapExport::new(is_colo, params).await)
+            }
             // ExportEnum::BitgetSpot => {
             //     Box::new(BitgetSpotExport::new(is_colo, params).await)
             // }

+ 1 - 0
derive/src/lib.rs

@@ -9,6 +9,7 @@ mod bitget_spot_export;
 mod okx_swap_export;
 mod bybit_swap_export;
 mod bitget_swap_export;
+mod coinex_swap_export;
 
 #[async_trait]
 pub trait ExportConnector {

+ 2 - 2
derive/tests/bitget_swap_export_test.rs

@@ -5,7 +5,7 @@ use derive::export_excel::ExportEnum;
 use crate::export_excel_test::test_new_export;
 
 
-const SYMBOL: &str = "fartcoin_usdt";
+const SYMBOL: &str = "";
 
 // 测试获取Exchange实体
 #[tokio::test]
@@ -14,6 +14,6 @@ async fn test_get_self_exchange() {
     global::log_utils::init_log_with_trace();
 
     let mut export = test_new_export(ExportEnum::BitgetSwap).await;
-    let export_trades = export.export_trades("bitget_02", SYMBOL.to_string(), 1735090200000, 1735178400000, 100).await;
+    let export_trades = export.export_trades("bitget_b2_01", SYMBOL.to_string(), 1739178000000, 1739179380000, 100).await;
     trace!(?export_trades);
 }

+ 19 - 0
derive/tests/coinex_swap_export_test.rs

@@ -0,0 +1,19 @@
+mod export_excel_test;
+
+use tracing::{instrument, trace};
+use derive::export_excel::ExportEnum;
+use crate::export_excel_test::test_new_export;
+
+
+const SYMBOL: &str = "";
+
+// 测试获取Exchange实体
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_get_self_exchange() {
+    global::log_utils::init_log_with_trace();
+
+    let mut export = test_new_export(ExportEnum::CoinexSwap).await;
+    let export_trades = export.export_trades("coinex_011", SYMBOL.to_string(), 1723651201000, 1724537317221, 1000).await;
+    trace!(?export_trades);
+}

+ 8 - 0
derive/tests/export_excel_test.rs

@@ -71,6 +71,14 @@ pub async fn test_new_export(export_enum: ExportEnum) -> Box<dyn ExportConnector
             params.insert("pass_key".to_string(), pass_key);
             ExportExcel::new(ExportEnum::BitgetSwap, false, params).await
         }
+        ExportEnum::CoinexSwap => {
+            let mut params: BTreeMap<String, String> = BTreeMap::new();
+            let access_key = account_info.coinex_access_key;
+            let secret_key = account_info.coinex_secret_key;
+            params.insert("access_key".to_string(), access_key);
+            params.insert("secret_key".to_string(), secret_key);
+            ExportExcel::new(ExportEnum::CoinexSwap, false, params).await
+        }
         // ExportEnum::BitgetSpot => {
         //     let mut params: BTreeMap<String, String> = BTreeMap::new();
         //     let access_key = account_info.bitget_access_key;

+ 20 - 0
exchanges/src/coinex_swap_rest.rs

@@ -408,6 +408,26 @@ impl CoinexSwapRest {
         data
     }
 
+    // 查询已完成委托单
+    pub async fn finished_order(&mut self, market: String, page:i64 ,limit: i64)-> ResponseData {
+        let mut params = serde_json::json!({
+            "market_type": "FUTURES",
+            "page": 1,
+            "limit": 1000
+        });
+
+        if market != "" { params["market"] = serde_json::json!(market); }
+        if page > 0 { params["page"] = serde_json::json!(page); }
+        if limit > 0 { params["limit"] = serde_json::json!(limit); }
+
+        let data = self.request("GET".to_string(),
+                                "/v2".to_string(),
+                                "/futures/finished-order".to_string(),
+                                true,
+                                Some(params.to_string()), None).await;
+        data
+    }
+
     //查询合约账户变更历史
     pub async fn account_book(&mut self) -> ResponseData {
         error!("查询合约账户变更历史失败,无实现");

+ 4 - 0
global/src/account_info.rs

@@ -21,6 +21,8 @@ pub struct AccountInfo {
     pub bitget_pass: String,
     pub bybit_access_key: String,
     pub bybit_secret_key: String,
+    pub coinex_access_key: String,
+    pub coinex_secret_key: String,
     pub htx_access_key: String,
     pub htx_secret_key: String,
     pub htx_pass: String,
@@ -44,6 +46,8 @@ impl AccountInfo {
             bitget_pass: "".to_string(),
             bybit_access_key: "".to_string(),
             bybit_secret_key: "".to_string(),
+            coinex_access_key: "".to_string(),
+            coinex_secret_key: "".to_string(),
             htx_access_key: "".to_string(),
             htx_secret_key: "".to_string(),
             htx_pass: "".to_string(),