Переглянути джерело

binance excel导出交易记录

skyfffire 1 рік тому
батько
коміт
e78bc9ac11

+ 40 - 25
derive/src/binance_swap_export.rs

@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
 use async_trait::async_trait;
 use chrono::{FixedOffset, NaiveDateTime, TimeZone};
 use serde::{Deserialize, Serialize};
-use tracing::warn;
+use tracing::{error, warn};
 use exchanges::binance_swap_rest::BinanceSwapRest;
 use standard::utils;
 use crate::ExportConnector;
@@ -61,32 +61,47 @@ impl ExportConnector for BinanceSwapExport {
             warn!("查询条数最大为1000条,已修改为1000条!");
             1000
         } else { limit };
-        let res_data = self.request.get_user_trades(symbol_format, start_time, end_time, limit_params).await;
-        if res_data.code == "200" {
-            let trades_info: Vec<TradesSwap> = serde_json::from_str(&res_data.data).unwrap();
-            let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "成交价格", "成交数量", "成交价值", "交易费用", "交易时间"];
-            let mut data_array: Vec<Vec<String>> = Vec::new();
-            for (index, value) in trades_info.iter().enumerate() {
-                if index >= data_array.len() {
-                    data_array.push(Vec::new());
-                }
-                let time = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.time.clone()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+        let mut last_id = "".to_string();
+        let mut data_array = vec![];
+
+        loop {
+            let res_data = self.request.get_user_trades(symbol_format.clone(), start_time, end_time, limit_params, last_id.clone()).await;
+            if res_data.code == 200 {
+                let trades_info: Vec<TradesSwap> = serde_json::from_str(&res_data.data.to_string()).unwrap();
+                for (index, value) in trades_info.iter().enumerate() {
+                    last_id = value.id.to_string();
+                    if index >= data_array.len() {
+                        data_array.push(Vec::new());
+                    }
+                    let time = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.time.clone()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
 
-                data_array[index] = vec![
-                    value.id.to_string(),
-                    value.order_id.to_string(),
-                    value.symbol.clone(),
-                    value.side.clone(),
-                    value.price.clone(),
-                    value.qty.clone(),
-                    value.quote_qty.clone(),
-                    value.commission.clone(),
-                    time,
-                ];
+                    data_array.push(vec![
+                        value.id.to_string(),
+                        value.order_id.to_string(),
+                        value.symbol.clone(),
+                        value.side.clone(),
+                        value.price.clone(),
+                        value.qty.clone(),
+                        value.quote_qty.clone(),
+                        value.commission.clone(),
+                        time,
+                    ]);
+                }
+                warn!("★★★★★★★★★★★★★★★★★★★★{}" ,data_array.len());
+                let last_time = trades_info.last().unwrap().time;
+                // if last_time < start_time {
+                if data_array.len() > 5 {
+                    // data_array = data_array.iter().filter(|item| {
+                    //     NaiveDateTime::parse_from_str(item.last().unwrap(), "%Y-%m-%d %H:%M:%S%.3f")
+                    //         .unwrap()
+                    //         .timestamp_millis() > start_time
+                    // }).cloned().collect();
+                    break;
+                }
             }
-            global::export_utils::export_excel(header_array, data_array, prefix_name)
-        } else {
-            res_data.to_string()
         }
+
+        let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "成交价格", "成交数量", "成交价值", "交易费用", "交易时间"];
+        global::export_utils::export_excel(header_array, data_array, prefix_name)
     }
 }

+ 78 - 78
derive/src/bitget_spot_export.rs

@@ -1,78 +1,78 @@
-use std::collections::BTreeMap;
-use std::str::FromStr;
-use async_trait::async_trait;
-use chrono::{FixedOffset, NaiveDateTime, TimeZone};
-use rust_decimal::Decimal;
-use serde::{Deserialize, Serialize};
-use tracing::warn;
-use exchanges::bitget_spot_rest::BitgetSpotRest;
-use standard::utils;
-use crate::ExportConnector;
-
-pub struct BitgetSpotExport {
-    request: BitgetSpotRest,
-}
-
-impl BitgetSpotExport {
-    pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> BitgetSpotExport {
-        BitgetSpotExport {
-            request: BitgetSpotRest::new(is_colo, params.clone())
-        }
-    }
-}
-
-/// TradesSwap
-/// - `symbol`: String, 交易对名称
-/// - `trade_id`: String, 成交单ID
-/// - `side`: String, 交易方向
-/// - `price`: String, 成交价格
-/// - `size`: String, 成交数量
-/// - `ts`: String, 成交时间
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct TradesSpot {
-    symbol: String,
-    trade_id: String,
-    side: String,
-    price: String,
-    size: String,
-    ts: String,
-}
-
-#[async_trait]
-impl ExportConnector for BitgetSpotExport {
-    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, "");
-        let start_at = if start_time > 0 { start_time.to_string() } else { "".to_string() };
-        let end_at = if end_time > 0 { end_time.to_string() } else { "".to_string() };
-        let limit_params = if limit > 1000 {
-            warn!("查询条数最大为1000条,已修改为1000条!");
-            1000
-        } else { limit };
-        let res_data = self.request.get_market_fills_history(symbol_format, start_at.to_string(), end_at.to_string(), limit_params.to_string()).await;
-        if res_data.code == "200" {
-            let trades_info: Vec<TradesSpot> = serde_json::from_str(&res_data.data).unwrap();
-            let header_array = vec!["交易编号", "交易币对", "买卖方向", "订单价格", "订单数量", "成交额", "创建时间"];
-            let mut data_array: Vec<Vec<String>> = Vec::new();
-            for (index, value) in trades_info.iter().enumerate() {
-                if index >= data_array.len() {
-                    data_array.push(Vec::new());
-                }
-                let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.ts.parse::<i64>().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-                let trade_value = Decimal::from_str(&value.price).unwrap() * Decimal::from_str(&value.size).unwrap();
-                data_array[index] = vec![
-                    value.trade_id.clone(),
-                    value.symbol.clone(),
-                    value.side.clone(),
-                    value.price.clone(),
-                    value.size.clone(),
-                    trade_value.to_string(),
-                    created_at,
-                ];
-            }
-            global::export_utils::export_excel(header_array, data_array, prefix_name)
-        } else {
-            res_data.to_string()
-        }
-    }
-}
+// use std::collections::BTreeMap;
+// use std::str::FromStr;
+// use async_trait::async_trait;
+// use chrono::{FixedOffset, NaiveDateTime, TimeZone};
+// use rust_decimal::Decimal;
+// use serde::{Deserialize, Serialize};
+// use tracing::warn;
+// use exchanges::bitget_spot_rest::BitgetSpotRest;
+// use standard::utils;
+// use crate::ExportConnector;
+//
+// pub struct BitgetSpotExport {
+//     request: BitgetSpotRest,
+// }
+//
+// impl BitgetSpotExport {
+//     pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> BitgetSpotExport {
+//         BitgetSpotExport {
+//             request: BitgetSpotRest::new(is_colo, params.clone())
+//         }
+//     }
+// }
+//
+// /// TradesSwap
+// /// - `symbol`: String, 交易对名称
+// /// - `trade_id`: String, 成交单ID
+// /// - `side`: String, 交易方向
+// /// - `price`: String, 成交价格
+// /// - `size`: String, 成交数量
+// /// - `ts`: String, 成交时间
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct TradesSpot {
+//     symbol: String,
+//     trade_id: String,
+//     side: String,
+//     price: String,
+//     size: String,
+//     ts: String,
+// }
+//
+// #[async_trait]
+// impl ExportConnector for BitgetSpotExport {
+//     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, "");
+//         let start_at = if start_time > 0 { start_time.to_string() } else { "".to_string() };
+//         let end_at = if end_time > 0 { end_time.to_string() } else { "".to_string() };
+//         let limit_params = if limit > 1000 {
+//             warn!("查询条数最大为1000条,已修改为1000条!");
+//             1000
+//         } else { limit };
+//         let res_data = self.request.get_market_fills_history(symbol_format, start_at.to_string(), end_at.to_string(), limit_params.to_string()).await;
+//         if res_data.code == "200" {
+//             let trades_info: Vec<TradesSpot> = serde_json::from_str(&res_data.data).unwrap();
+//             let header_array = vec!["交易编号", "交易币对", "买卖方向", "订单价格", "订单数量", "成交额", "创建时间"];
+//             let mut data_array: Vec<Vec<String>> = Vec::new();
+//             for (index, value) in trades_info.iter().enumerate() {
+//                 if index >= data_array.len() {
+//                     data_array.push(Vec::new());
+//                 }
+//                 let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.ts.parse::<i64>().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+//                 let trade_value = Decimal::from_str(&value.price).unwrap() * Decimal::from_str(&value.size).unwrap();
+//                 data_array[index] = vec![
+//                     value.trade_id.clone(),
+//                     value.symbol.clone(),
+//                     value.side.clone(),
+//                     value.price.clone(),
+//                     value.size.clone(),
+//                     trade_value.to_string(),
+//                     created_at,
+//                 ];
+//             }
+//             global::export_utils::export_excel(header_array, data_array, prefix_name)
+//         } else {
+//             res_data.to_string()
+//         }
+//     }
+// }

+ 20 - 20
derive/src/export_excel.rs

@@ -1,20 +1,20 @@
 use std::collections::BTreeMap;
 use crate::binance_swap_export::BinanceSwapExport;
-use crate::bitget_spot_export::BitgetSpotExport;
+// use crate::bitget_spot_export::BitgetSpotExport;
 use crate::ExportConnector;
 use crate::gate_swap_export::GateSwapExport;
-use crate::kucoin_spot_export::KucoinSpotExport;
-use crate::kucoin_swap_export::KucoinSwapExport;
-use crate::okx_swap_export::OkxSwapExport;
+// use crate::kucoin_spot_export::KucoinSpotExport;
+// use crate::kucoin_swap_export::KucoinSwapExport;
+// use crate::okx_swap_export::OkxSwapExport;
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ExportEnum {
     BinanceSwap,
-    KucoinSwap,
-    KucoinSpot,
+    // KucoinSwap,
+    // KucoinSpot,
     GateSwap,
-    BitgetSpot,
-    OkxSwap,
+    // BitgetSpot,
+    // OkxSwap,
 }
 
 #[derive(Debug, Clone)]
@@ -26,21 +26,21 @@ impl ExportExcel {
             ExportEnum::BinanceSwap => {
                 Box::new(BinanceSwapExport::new(is_colo, params).await)
             }
-            ExportEnum::KucoinSwap => {
-                Box::new(KucoinSwapExport::new(is_colo, params).await)
-            }
-            ExportEnum::KucoinSpot => {
-                Box::new(KucoinSpotExport::new(is_colo, params).await)
-            }
+            // ExportEnum::KucoinSwap => {
+            //     Box::new(KucoinSwapExport::new(is_colo, params).await)
+            // }
+            // ExportEnum::KucoinSpot => {
+            //     Box::new(KucoinSpotExport::new(is_colo, params).await)
+            // }
             ExportEnum::GateSwap => {
                 Box::new(GateSwapExport::new(is_colo, params).await)
             }
-            ExportEnum::BitgetSpot => {
-                Box::new(BitgetSpotExport::new(is_colo, params).await)
-            }
-            ExportEnum::OkxSwap => {
-                Box::new(OkxSwapExport::new(is_colo, params).await)
-            }
+            // ExportEnum::BitgetSpot => {
+            //     Box::new(BitgetSpotExport::new(is_colo, params).await)
+            // }
+            // ExportEnum::OkxSwap => {
+            //     Box::new(OkxSwapExport::new(is_colo, params).await)
+            // }
         }
     }
 }

+ 40 - 34
derive/src/gate_swap_export.rs

@@ -6,7 +6,7 @@ use rust_decimal::Decimal;
 use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
 use rust_decimal_macros::dec;
 use serde::{Deserialize, Serialize};
-use tracing::{error, warn};
+use tracing::{warn};
 use exchanges::gate_swap_rest::GateSwapRest;
 use standard::utils;
 use crate::ExportConnector;
@@ -50,45 +50,51 @@ struct TradesSwap {
 
 #[async_trait]
 impl ExportConnector for GateSwapExport {
-    async fn export_trades(&mut self, prefix_name: &str, symbol: String, start_time: i64, end_time: i64, limit: i64) -> String {
-        let symbol_array: Vec<&str> = symbol.split("_").collect();
+    async fn export_trades(&mut self, prefix_name: &str, symbol: String, start_time: i64, _end_time: i64, limit: i64) -> String {
+        let _symbol_array: Vec<&str> = symbol.split("_").collect();
         let symbol_format = utils::format_symbol(symbol.clone(), "_");
-        let limit_params = if limit > 1000 {
+        let _limit_params = if limit > 1000 {
             warn!("查询条数最大为1000条,已修改为1000条!");
             1000
         } else { limit };
-        let res_data = self.request.my_trades(symbol_array[1].to_lowercase(), symbol_format, limit_params).await;
-        if start_time > 0 || end_time > 0 { error!("该交易所不支持根据时间查询!") };
-        if res_data.code == "200" {
-            let trades_info: Vec<TradesSwap> = serde_json::from_str(&res_data.data).unwrap();
-            let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "成交价格", "成交数量", "成交价值", "交易费用", "成交角色", "成交时间"];
-            let mut data_array: Vec<Vec<String>> = Vec::new();
-
-            for (index, value) in trades_info.iter().enumerate() {
-                if index >= data_array.len() {
-                    data_array.push(Vec::new());
+        let mut last_id = "".to_string();
+        let mut data_array = vec![];
+        loop {
+            let res_data = self.request.my_trades("usdt".to_string(), symbol_format.clone(), 1000, last_id.clone()).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() {
+                    last_id = value.id.to_string();
+                    let size = Decimal::from_i64(value.size).unwrap();
+                    let side = if size < Decimal::ZERO { "sell" } else { "buy" };
+                    let created_time = Decimal::from_f64(value.create_time).unwrap() * dec!(1000);
+                    let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(created_time.to_i64().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+                    let trade_value = Decimal::from_str(&value.price).unwrap() * size.abs();
+                    data_array.push(vec![
+                        value.id.to_string(),
+                        value.order_id.clone(),
+                        value.contract.clone(),
+                        side.to_string(),
+                        value.price.clone(),
+                        size.abs().to_string(),
+                        trade_value.to_string(),
+                        value.fee.clone(),
+                        value.role.clone(),
+                        created_at,
+                    ]);
+                }
+                let last_time = (trades_info.last().unwrap().create_time * 1000.0).to_i64().unwrap();
+                if last_time < start_time {
+                    data_array = data_array.iter().filter(|item| {
+                        NaiveDateTime::parse_from_str(item.last().unwrap(), "%Y-%m-%d %H:%M:%S%.3f")
+                            .unwrap()
+                            .timestamp_millis() > start_time
+                    }).cloned().collect();
+                    break;
                 }
-                let size = Decimal::from_i64(value.size).unwrap();
-                let side = if size < Decimal::ZERO { "sell" } else { "buy" };
-                let created_time = Decimal::from_f64(value.create_time).unwrap() * dec!(1000);
-                let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(created_time.to_i64().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-                let trade_value = Decimal::from_str(&value.price).unwrap() * size.abs();
-                data_array[index] = vec![
-                    value.id.to_string(),
-                    value.order_id.clone(),
-                    value.contract.clone(),
-                    side.to_string(),
-                    value.price.clone(),
-                    size.abs().to_string(),
-                    trade_value.to_string(),
-                    value.fee.clone(),
-                    value.role.clone(),
-                    created_at,
-                ];
             }
-            global::export_utils::export_excel(header_array, data_array, prefix_name)
-        } else {
-            res_data.to_string()
         }
+        let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "成交价格", "成交数量", "成交价值", "交易费用", "成交角色", "成交时间"];
+        global::export_utils::export_excel(header_array, data_array, prefix_name)
     }
 }

+ 104 - 104
derive/src/kucoin_spot_export.rs

@@ -1,104 +1,104 @@
-use std::collections::BTreeMap;
-use async_trait::async_trait;
-use chrono::{FixedOffset, NaiveDateTime, TimeZone};
-use serde::{Deserialize, Serialize};
-use tracing::warn;
-use exchanges::kucoin_spot_rest::KucoinSpotRest;
-use standard::exchange::ExchangeEnum;
-use standard::utils;
-use crate::ExportConnector;
-
-pub struct KucoinSpotExport {
-    request: KucoinSpotRest,
-}
-
-impl KucoinSpotExport {
-    pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> KucoinSpotExport {
-        KucoinSpotExport {
-            request: KucoinSpotRest::new(is_colo, params.clone())
-        }
-    }
-}
-
-/// TradesSwap
-/// - `symbol`: String, 合約編號
-/// - `trade_id`: String, 交易編號
-/// - `order_id`: String, 訂單編號
-/// - `counter_order_id`: String, 對手方訂單Id
-/// - `side`: String, 買賣方向
-/// - `liquidity`: String,流動性類型 taker or maker
-/// - `force_taker`: bool, 是否強製作爲taker處理
-/// - `price`: String, 成交價格
-/// - `size`: i64, 成交數量
-/// - `funds`: String, 成交額
-/// - `fee`: String, 交易費用
-/// - `fee_currency`: String, 收費幣種
-/// - `stop`: String, 止損單類型標記
-/// - `fee_rate`: String, 費率
-/// - `order_type`: String, 訂單類型
-/// - `created_at`: i64, 創建時間
-/// - `trade_type`: String, 交易類型: trade, liquidation, ADL or settlement
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct TradesSpot {
-    symbol: String,
-    trade_id: String,
-    order_id: String,
-    counter_order_id: String,
-    side: String,
-    liquidity: String,
-    force_taker: bool,
-    price: String,
-    size: i64,
-    funds: String,
-    fee: String,
-    fee_rate: String,
-    fee_currency: String,
-    stop: String,
-    #[serde(rename = "type")]
-    order_type: String,
-    created_at: i64,
-    trade_type: String,
-}
-
-#[async_trait]
-impl ExportConnector for KucoinSpotExport {
-    async fn export_trades(&mut self, prefix_name: &str, symbol: String, start_time: i64, end_time: i64, limit: i64) -> String {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let limit_params = if limit > 1000 {
-            warn!("查询条数最大为1000条,已修改为1000条!");
-            1000
-        } else { limit };
-        let res_data = self.request.get_fills(symbol_format, "".to_string(), "".to_string(), start_time, end_time, limit_params).await;
-        if res_data.code == "200" {
-            let res_data_json: serde_json::Value = serde_json::from_str(&res_data.data).unwrap();
-            let trades_info: Vec<TradesSpot> = serde_json::from_str(&res_data_json["items"].to_string()).unwrap();
-            let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "订单价格", "订单数量", "成交额", "手续费", "手续费率", "订单类型", "创建时间"];
-            let mut data_array: Vec<Vec<String>> = Vec::new();
-            for (index, value) in trades_info.iter().enumerate() {
-                if index >= data_array.len() {
-                    data_array.push(Vec::new());
-                }
-                let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.created_at.clone()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-
-                data_array[index] = vec![
-                    value.trade_id.clone(),
-                    value.order_id.clone(),
-                    value.symbol.clone(),
-                    value.side.clone(),
-                    value.price.clone(),
-                    value.size.to_string(),
-                    value.funds.clone(),
-                    value.fee.clone(),
-                    value.fee_rate.clone(),
-                    value.order_type.clone(),
-                    created_at,
-                ];
-            }
-            global::export_utils::export_excel(header_array, data_array, prefix_name)
-        } else {
-            res_data.to_string()
-        }
-    }
-}
+// use std::collections::BTreeMap;
+// use async_trait::async_trait;
+// use chrono::{FixedOffset, NaiveDateTime, TimeZone};
+// use serde::{Deserialize, Serialize};
+// use tracing::warn;
+// use exchanges::kucoin_spot_rest::KucoinSpotRest;
+// use standard::exchange::ExchangeEnum;
+// use standard::utils;
+// use crate::ExportConnector;
+//
+// pub struct KucoinSpotExport {
+//     request: KucoinSpotRest,
+// }
+//
+// impl KucoinSpotExport {
+//     pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> KucoinSpotExport {
+//         KucoinSpotExport {
+//             request: KucoinSpotRest::new(is_colo, params.clone())
+//         }
+//     }
+// }
+//
+// /// TradesSwap
+// /// - `symbol`: String, 合約編號
+// /// - `trade_id`: String, 交易編號
+// /// - `order_id`: String, 訂單編號
+// /// - `counter_order_id`: String, 對手方訂單Id
+// /// - `side`: String, 買賣方向
+// /// - `liquidity`: String,流動性類型 taker or maker
+// /// - `force_taker`: bool, 是否強製作爲taker處理
+// /// - `price`: String, 成交價格
+// /// - `size`: i64, 成交數量
+// /// - `funds`: String, 成交額
+// /// - `fee`: String, 交易費用
+// /// - `fee_currency`: String, 收費幣種
+// /// - `stop`: String, 止損單類型標記
+// /// - `fee_rate`: String, 費率
+// /// - `order_type`: String, 訂單類型
+// /// - `created_at`: i64, 創建時間
+// /// - `trade_type`: String, 交易類型: trade, liquidation, ADL or settlement
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct TradesSpot {
+//     symbol: String,
+//     trade_id: String,
+//     order_id: String,
+//     counter_order_id: String,
+//     side: String,
+//     liquidity: String,
+//     force_taker: bool,
+//     price: String,
+//     size: i64,
+//     funds: String,
+//     fee: String,
+//     fee_rate: String,
+//     fee_currency: String,
+//     stop: String,
+//     #[serde(rename = "type")]
+//     order_type: String,
+//     created_at: i64,
+//     trade_type: String,
+// }
+//
+// #[async_trait]
+// impl ExportConnector for KucoinSpotExport {
+//     async fn export_trades(&mut self, prefix_name: &str, symbol: String, start_time: i64, end_time: i64, limit: i64) -> String {
+//         let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
+//         let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
+//         let limit_params = if limit > 1000 {
+//             warn!("查询条数最大为1000条,已修改为1000条!");
+//             1000
+//         } else { limit };
+//         let res_data = self.request.get_fills(symbol_format, "".to_string(), "".to_string(), start_time, end_time, limit_params).await;
+//         if res_data.code == "200" {
+//             let res_data_json: serde_json::Value = serde_json::from_str(&res_data.data).unwrap();
+//             let trades_info: Vec<TradesSpot> = serde_json::from_str(&res_data_json["items"].to_string()).unwrap();
+//             let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "订单价格", "订单数量", "成交额", "手续费", "手续费率", "订单类型", "创建时间"];
+//             let mut data_array: Vec<Vec<String>> = Vec::new();
+//             for (index, value) in trades_info.iter().enumerate() {
+//                 if index >= data_array.len() {
+//                     data_array.push(Vec::new());
+//                 }
+//                 let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.created_at.clone()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+//
+//                 data_array[index] = vec![
+//                     value.trade_id.clone(),
+//                     value.order_id.clone(),
+//                     value.symbol.clone(),
+//                     value.side.clone(),
+//                     value.price.clone(),
+//                     value.size.to_string(),
+//                     value.funds.clone(),
+//                     value.fee.clone(),
+//                     value.fee_rate.clone(),
+//                     value.order_type.clone(),
+//                     created_at,
+//                 ];
+//             }
+//             global::export_utils::export_excel(header_array, data_array, prefix_name)
+//         } else {
+//             res_data.to_string()
+//         }
+//     }
+// }

+ 2 - 2
derive/src/lib.rs

@@ -2,8 +2,8 @@ use async_trait::async_trait;
 
 mod binance_swap_export;
 pub mod export_excel;
-mod kucoin_swap_export;
-mod kucoin_spot_export;
+// mod kucoin_swap_export;
+// mod kucoin_spot_export;
 mod gate_swap_export;
 mod bitget_spot_export;
 mod okx_swap_export;

+ 120 - 120
derive/src/okx_swap_export.rs

@@ -1,120 +1,120 @@
-use std::collections::BTreeMap;
-use std::str::FromStr;
-use async_trait::async_trait;
-use chrono::{FixedOffset, NaiveDateTime, TimeZone};
-use rust_decimal::Decimal;
-use serde::{Deserialize, Serialize};
-use tracing::warn;
-use exchanges::okx_swap_rest::OkxSwapRest;
-use standard::utils;
-use crate::ExportConnector;
-
-pub struct OkxSwapExport {
-    request: OkxSwapRest,
-}
-
-impl OkxSwapExport {
-    pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> OkxSwapExport {
-        OkxSwapExport {
-            request: OkxSwapRest::new(is_colo, params.clone())
-        }
-    }
-}
-
-/// TradesSwap
-///
-/// - `inst_type`: String,
-/// - `inst_id`: String,
-/// - `trade_id`: String,
-/// - `ord_id`: String,
-/// - `cl_ord_id`: String,
-/// - `bill_id`: String,
-/// - `tag`: String,
-/// - `fill_px`: String,
-/// - `fill_sz`: String,
-/// - `fill_idx_px`: String,
-/// - `fill_pnl`: String,
-/// - `fill_px_vol`: String,
-/// - `fill_px_usd`: String,
-/// - `fill_mark_vol`: String,
-/// - `fill_fwd_px`: String,
-/// - `fill_mark_px`: String,
-/// - `side`: String,
-/// - `pos_side`: String,
-/// - `exec_type`: String,
-/// - `fee_ccy`: String,
-/// - `fee`: String,
-/// - `ts`: String,
-/// - `fill_time`: String,
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct TradesSwap {
-    inst_type: String,
-    inst_id: String,
-    trade_id: String,
-    ord_id: String,
-    cl_ord_id: String,
-    bill_id: String,
-    tag: String,
-    fill_px: String,
-    fill_sz: String,
-    fill_idx_px: String,
-    fill_pnl: String,
-    fill_px_vol: String,
-    fill_px_usd: String,
-    fill_mark_vol: String,
-    fill_fwd_px: String,
-    fill_mark_px: String,
-    side: String,
-    pos_side: String,
-    exec_type: String,
-    fee_ccy: String,
-    fee: String,
-    ts: String,
-    fill_time: String,
-}
-
-#[async_trait]
-impl ExportConnector for OkxSwapExport {
-    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 > 100 {
-            warn!("查询条数最大为100条,已修改为100条!");
-            1000
-        } else { limit };
-        let start_time_str = if start_time > 0 { start_time.to_string() } else { "".to_string() };
-        let end_time_str = if end_time > 0 { end_time.to_string() } else { "".to_string() };
-        let limit_str = if limit_params > 0 { limit_params.to_string() } else { "".to_string() };
-        let res_data = self.request.get_trade_fills_history(symbol_format, start_time_str, end_time_str, limit_str).await;
-        if res_data.code == "200" {
-            let trades_info: Vec<TradesSwap> = serde_json::from_str(&res_data.data).unwrap();
-            let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "成交价格", "成交数量", "成交价值", "交易费用", "创建时间", "成交时间"];
-            let mut data_array: Vec<Vec<String>> = Vec::new();
-
-            for (index, value) in trades_info.iter().enumerate() {
-                if index >= data_array.len() {
-                    data_array.push(Vec::new());
-                }
-
-                let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.ts.parse::<i64>().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-                let trade_time = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.fill_time.parse::<i64>().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-                let trade_value = Decimal::from_str(&value.fill_px).unwrap() * Decimal::from_str(&value.fill_sz).unwrap();
-                data_array[index] = vec![
-                    value.trade_id.clone(),
-                    value.ord_id.clone(),
-                    value.inst_id.clone(),
-                    value.side.clone(),
-                    value.fill_px.clone(),
-                    value.fill_sz.clone(),
-                    trade_value.to_string(),
-                    value.fee.clone(),
-                    created_at,
-                    trade_time,
-                ];
-            }
-            global::export_utils::export_excel(header_array, data_array, prefix_name)
-        } else {
-            res_data.to_string()
-        }
-    }
-}
+// use std::collections::BTreeMap;
+// use std::str::FromStr;
+// use async_trait::async_trait;
+// use chrono::{FixedOffset, NaiveDateTime, TimeZone};
+// use rust_decimal::Decimal;
+// use serde::{Deserialize, Serialize};
+// use tracing::warn;
+// use exchanges::okx_swap_rest::OkxSwapRest;
+// use standard::utils;
+// use crate::ExportConnector;
+//
+// pub struct OkxSwapExport {
+//     request: OkxSwapRest,
+// }
+//
+// impl OkxSwapExport {
+//     pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> OkxSwapExport {
+//         OkxSwapExport {
+//             request: OkxSwapRest::new(is_colo, params.clone())
+//         }
+//     }
+// }
+//
+// /// TradesSwap
+// ///
+// /// - `inst_type`: String,
+// /// - `inst_id`: String,
+// /// - `trade_id`: String,
+// /// - `ord_id`: String,
+// /// - `cl_ord_id`: String,
+// /// - `bill_id`: String,
+// /// - `tag`: String,
+// /// - `fill_px`: String,
+// /// - `fill_sz`: String,
+// /// - `fill_idx_px`: String,
+// /// - `fill_pnl`: String,
+// /// - `fill_px_vol`: String,
+// /// - `fill_px_usd`: String,
+// /// - `fill_mark_vol`: String,
+// /// - `fill_fwd_px`: String,
+// /// - `fill_mark_px`: String,
+// /// - `side`: String,
+// /// - `pos_side`: String,
+// /// - `exec_type`: String,
+// /// - `fee_ccy`: String,
+// /// - `fee`: String,
+// /// - `ts`: String,
+// /// - `fill_time`: String,
+// #[derive(Debug, Deserialize, Serialize)]
+// #[serde(rename_all = "camelCase")]
+// struct TradesSwap {
+//     inst_type: String,
+//     inst_id: String,
+//     trade_id: String,
+//     ord_id: String,
+//     cl_ord_id: String,
+//     bill_id: String,
+//     tag: String,
+//     fill_px: String,
+//     fill_sz: String,
+//     fill_idx_px: String,
+//     fill_pnl: String,
+//     fill_px_vol: String,
+//     fill_px_usd: String,
+//     fill_mark_vol: String,
+//     fill_fwd_px: String,
+//     fill_mark_px: String,
+//     side: String,
+//     pos_side: String,
+//     exec_type: String,
+//     fee_ccy: String,
+//     fee: String,
+//     ts: String,
+//     fill_time: String,
+// }
+//
+// #[async_trait]
+// impl ExportConnector for OkxSwapExport {
+//     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 > 100 {
+//             warn!("查询条数最大为100条,已修改为100条!");
+//             1000
+//         } else { limit };
+//         let start_time_str = if start_time > 0 { start_time.to_string() } else { "".to_string() };
+//         let end_time_str = if end_time > 0 { end_time.to_string() } else { "".to_string() };
+//         let limit_str = if limit_params > 0 { limit_params.to_string() } else { "".to_string() };
+//         let res_data = self.request.get_trade_fills_history(symbol_format, start_time_str, end_time_str, limit_str).await;
+//         if res_data.code == "200" {
+//             let trades_info: Vec<TradesSwap> = serde_json::from_str(&res_data.data).unwrap();
+//             let header_array = vec!["交易编号", "订单编号", "交易币对", "买卖方向", "成交价格", "成交数量", "成交价值", "交易费用", "创建时间", "成交时间"];
+//             let mut data_array: Vec<Vec<String>> = Vec::new();
+//
+//             for (index, value) in trades_info.iter().enumerate() {
+//                 if index >= data_array.len() {
+//                     data_array.push(Vec::new());
+//                 }
+//
+//                 let created_at = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.ts.parse::<i64>().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+//                 let trade_time = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&NaiveDateTime::from_timestamp_millis(value.fill_time.parse::<i64>().unwrap()).unwrap()).format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+//                 let trade_value = Decimal::from_str(&value.fill_px).unwrap() * Decimal::from_str(&value.fill_sz).unwrap();
+//                 data_array[index] = vec![
+//                     value.trade_id.clone(),
+//                     value.ord_id.clone(),
+//                     value.inst_id.clone(),
+//                     value.side.clone(),
+//                     value.fill_px.clone(),
+//                     value.fill_sz.clone(),
+//                     trade_value.to_string(),
+//                     value.fee.clone(),
+//                     created_at,
+//                     trade_time,
+//                 ];
+//             }
+//             global::export_utils::export_excel(header_array, data_array, prefix_name)
+//         } else {
+//             res_data.to_string()
+//         }
+//     }
+// }

+ 2 - 2
derive/tests/binance_swap_export_test.rs

@@ -5,7 +5,7 @@ use derive::export_excel::ExportEnum;
 use crate::export_excel_test::test_new_export;
 
 
-const SYMBOL: &str = "BLZ_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::BinanceSwap).await;
-    let export_trades = export.export_trades("binance_swap",SYMBOL.to_string(), 0, 0, 100).await;
+    let export_trades = export.export_trades("binance_swap", SYMBOL.to_string(), 1724810954000, 1724828954000, 10).await;
     trace!(?export_trades);
 }

+ 45 - 45
derive/tests/export_excel_test.rs

@@ -8,11 +8,11 @@ use exchanges::proxy;
 #[allow(dead_code)]
 pub async fn test_new_export(export_enum: ExportEnum) -> Box<dyn ExportConnector> {
     // 检测是否走代理
-    pub fn proxy_handle() {
-        if proxy::ParsingDetail::http_enable_proxy() {
-            trace!("检测有代理配置,配置走代理");
-        }
-    }
+    // pub fn proxy_handle() {
+    //     if proxy::ParsingDetail::http_enable_proxy(None) {
+    //         trace!("检测有代理配置,配置走代理");
+    //     }
+    // }
 
     let account_info = global::account_info::get_account_info("../test_account.toml");
 
@@ -25,26 +25,26 @@ pub async fn test_new_export(export_enum: ExportEnum) -> Box<dyn ExportConnector
             params.insert("secret_key".to_string(), secret_key);
             ExportExcel::new(ExportEnum::BinanceSwap, false, params).await
         }
-        ExportEnum::KucoinSwap => {
-            let mut params: BTreeMap<String, String> = BTreeMap::new();
-            let access_key = account_info.kucoin_access_key;
-            let secret_key = account_info.kucoin_secret_key;
-            let pass_key = account_info.kucoin_pass;
-            params.insert("access_key".to_string(), access_key);
-            params.insert("secret_key".to_string(), secret_key);
-            params.insert("pass_key".to_string(), pass_key);
-            ExportExcel::new(ExportEnum::KucoinSwap, false, params).await
-        }
-        ExportEnum::KucoinSpot => {
-            let mut params: BTreeMap<String, String> = BTreeMap::new();
-            let access_key = account_info.kucoin_access_key;
-            let secret_key = account_info.kucoin_secret_key;
-            let pass_key = account_info.kucoin_pass;
-            params.insert("access_key".to_string(), access_key);
-            params.insert("secret_key".to_string(), secret_key);
-            params.insert("pass_key".to_string(), pass_key);
-            ExportExcel::new(ExportEnum::KucoinSpot, false, params).await
-        }
+        // ExportEnum::KucoinSwap => {
+        //     let mut params: BTreeMap<String, String> = BTreeMap::new();
+        //     let access_key = account_info.kucoin_access_key;
+        //     let secret_key = account_info.kucoin_secret_key;
+        //     let pass_key = account_info.kucoin_pass;
+        //     params.insert("access_key".to_string(), access_key);
+        //     params.insert("secret_key".to_string(), secret_key);
+        //     params.insert("pass_key".to_string(), pass_key);
+        //     ExportExcel::new(ExportEnum::KucoinSwap, false, params).await
+        // }
+        // ExportEnum::KucoinSpot => {
+        //     let mut params: BTreeMap<String, String> = BTreeMap::new();
+        //     let access_key = account_info.kucoin_access_key;
+        //     let secret_key = account_info.kucoin_secret_key;
+        //     let pass_key = account_info.kucoin_pass;
+        //     params.insert("access_key".to_string(), access_key);
+        //     params.insert("secret_key".to_string(), secret_key);
+        //     params.insert("pass_key".to_string(), pass_key);
+        //     ExportExcel::new(ExportEnum::KucoinSpot, false, params).await
+        // }
         ExportEnum::GateSwap => {
             let mut params: BTreeMap<String, String> = BTreeMap::new();
             let access_key = account_info.gate_access_key;
@@ -53,25 +53,25 @@ pub async fn test_new_export(export_enum: ExportEnum) -> Box<dyn ExportConnector
             params.insert("secret_key".to_string(), secret_key);
             ExportExcel::new(ExportEnum::GateSwap, false, params).await
         }
-        ExportEnum::BitgetSpot => {
-            let mut params: BTreeMap<String, String> = BTreeMap::new();
-            let access_key = account_info.bitget_access_key;
-            let secret_key = account_info.bitget_secret_key;
-            let pass_key = account_info.bitget_pass;
-            params.insert("access_key".to_string(), access_key);
-            params.insert("secret_key".to_string(), secret_key);
-            params.insert("pass_key".to_string(), pass_key);
-            ExportExcel::new(ExportEnum::BitgetSpot, false, params).await
-        }
-        ExportEnum::OkxSwap => {
-            let mut params: BTreeMap<String, String> = BTreeMap::new();
-            let access_key = account_info.okx_access_key;
-            let secret_key = account_info.okx_secret_key;
-            let pass_key = account_info.okx_pass;
-            params.insert("access_key".to_string(), access_key);
-            params.insert("secret_key".to_string(), secret_key);
-            params.insert("pass_key".to_string(), pass_key);
-            ExportExcel::new(ExportEnum::OkxSwap, false, params).await
-        }
+        // ExportEnum::BitgetSpot => {
+        //     let mut params: BTreeMap<String, String> = BTreeMap::new();
+        //     let access_key = account_info.bitget_access_key;
+        //     let secret_key = account_info.bitget_secret_key;
+        //     let pass_key = account_info.bitget_pass;
+        //     params.insert("access_key".to_string(), access_key);
+        //     params.insert("secret_key".to_string(), secret_key);
+        //     params.insert("pass_key".to_string(), pass_key);
+        //     ExportExcel::new(ExportEnum::BitgetSpot, false, params).await
+        // }
+        // ExportEnum::OkxSwap => {
+        //     let mut params: BTreeMap<String, String> = BTreeMap::new();
+        //     let access_key = account_info.okx_access_key;
+        //     let secret_key = account_info.okx_secret_key;
+        //     let pass_key = account_info.okx_pass;
+        //     params.insert("access_key".to_string(), access_key);
+        //     params.insert("secret_key".to_string(), secret_key);
+        //     params.insert("pass_key".to_string(), pass_key);
+        //     ExportExcel::new(ExportEnum::OkxSwap, false, params).await
+        // }
     }
 }

+ 2 - 2
derive/tests/gate_swap_export_test.rs

@@ -5,7 +5,7 @@ use derive::export_excel::ExportEnum;
 use crate::export_excel_test::test_new_export;
 
 
-const SYMBOL: &str = "TIA_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::GateSwap).await;
-    let export_trades = export.export_trades("gate_swap_42", SYMBOL.to_string(), 0, 0, 1000).await;
+    let export_trades = export.export_trades("gate_swap_42", SYMBOL.to_string(), 1723651201000, 1724035036000, 1000).await;
     trace!(?export_trades);
 }

+ 5 - 1
exchanges/src/binance_swap_rest.rs

@@ -256,7 +256,7 @@ impl BinanceSwapRest {
         data
     }
     //账户成交历史
-    pub async fn get_user_trades(&mut self, symbol: String, start_time: i64, end_time: i64, limit: i64) -> ResponseData {
+    pub async fn get_user_trades(&mut self, symbol: String, start_time: i64, end_time: i64, limit: i64,last_id:String) -> ResponseData {
         let mut params = serde_json::json!({
             "symbol":symbol,
             "limit":1000
@@ -270,6 +270,10 @@ impl BinanceSwapRest {
         if limit > 0 {
             params["limit"] = json!(limit);
         }
+        if last_id.len() > 0 {
+            params["fromId"] = json!(last_id);
+        }
+
         let data = self.request("GET".to_string(),
                                 "".to_string(),
                                 format!("/fapi/v1/userTrades"),

+ 2 - 1
exchanges/src/gate_swap_rest.rs

@@ -370,9 +370,10 @@ impl GateSwapRest {
     }
 
     //查询个人成交记录
-    pub async fn my_trades(&mut self, settle: String, contract: String, limit: i64) -> ResponseData {
+    pub async fn my_trades(&mut self, settle: String, contract: String, limit: i64, last_id: String) -> ResponseData {
         let mut params = serde_json::json!({
             "contract":contract,
+            "last_id": last_id,
             "limit":1000
         });
         if limit > 0 {