Parcourir la source

添加导出binance成交记录
添加导出kucoin成交记录

gepangpang il y a 2 ans
Parent
commit
1474c00ce1

+ 2 - 1
Cargo.toml

@@ -28,5 +28,6 @@ members=[
     "exchanges",
     "standard",
     "strategy",
-    "global"
+    "global",
+    "derive"
 ]

+ 3 - 0
derive/.gitignore

@@ -0,0 +1,3 @@
+/target
+/.idea
+/logs*

+ 21 - 0
derive/Cargo.toml

@@ -0,0 +1,21 @@
+[package]
+name = "derive"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+exchanges = { path = "../exchanges" }
+standard = { path = "../standard" }
+global = { path = "../global" }
+tokio = { version = "1.31.0", features = ["full"] }
+async-trait = "0.1.73"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0.104"
+rust_decimal = "1.32.0"
+rust_decimal_macros = "1.32.0"
+chrono = "0.4.30"
+futures = "0.3"
+tracing = "0.1"
+tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }

+ 87 - 0
derive/src/binance_swap_export.rs

@@ -0,0 +1,87 @@
+use std::collections::BTreeMap;
+use async_trait::async_trait;
+use chrono::{FixedOffset, NaiveDateTime, TimeZone};
+use serde::{Deserialize, Serialize};
+use exchanges::binance_swap_rest::BinanceSwapRest;
+use standard::utils;
+use crate::ExportConnector;
+
+pub struct BinanceSwapExport {
+    request: BinanceSwapRest,
+}
+
+impl BinanceSwapExport {
+    pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> BinanceSwapExport {
+        BinanceSwapExport {
+            request: BinanceSwapRest::new(is_colo, params.clone())
+        }
+    }
+}
+
+/// TradesSwap
+/// - `buyer`: bool, 是否是买方
+/// - `commission`: String, 手续费
+/// - `commission_asset`: String, 手续费计价单位
+/// - `id`: i64, 交易ID
+/// - `maker`: bool, 是否是挂单方
+/// - `order_id`: i64, 订单编号
+/// - `price`: String, 成交价
+/// - `qty`: String, 成交量
+/// - `quote_qty`: String, 成交额
+/// - `realized_pnl`: String, 实现盈亏
+/// - `side`: String, 买卖方向
+/// - `position_side`: String, 持仓方向
+/// - `symbol`: String, 交易对
+/// - `time`: i64 时间
+#[derive(Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+struct TradesSwap {
+    buyer: bool,
+    commission: String,
+    commission_asset: String,
+    id: i64,
+    maker: bool,
+    order_id: i64,
+    price: String,
+    qty: String,
+    quote_qty: String,
+    realized_pnl: String,
+    side: String,
+    position_side: String,
+    symbol: String,
+    time: i64,
+}
+
+#[async_trait]
+impl ExportConnector for BinanceSwapExport {
+    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 res_data = self.request.get_user_trades(symbol_format, start_time as i32, end_time as i32, limit).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 %T").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,
+                ];
+            }
+            global::export_utils::export_excel(header_array, data_array, prefix_name)
+        } else {
+            res_data.to_string()
+        }
+    }
+}

+ 26 - 0
derive/src/export_excel.rs

@@ -0,0 +1,26 @@
+use std::collections::BTreeMap;
+use crate::binance_swap_export::BinanceSwapExport;
+use crate::ExportConnector;
+use crate::kucoin_swap_export::KucoinSwapExport;
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum ExportEnum {
+    BinanceSwap,
+    KucoinSwap,
+}
+
+#[derive(Debug, Clone)]
+pub struct ExportExcel;
+
+impl ExportExcel {
+    pub async fn new(export_enum: ExportEnum, is_colo: bool, params: BTreeMap<String, String>) -> Box<dyn ExportConnector> {
+        match export_enum {
+            ExportEnum::BinanceSwap => {
+                Box::new(BinanceSwapExport::new(is_colo, params).await)
+            }
+            ExportEnum::KucoinSwap => {
+                Box::new(KucoinSwapExport::new(is_colo, params).await)
+            }
+        }
+    }
+}

+ 105 - 0
derive/src/kucoin_swap_export.rs

@@ -0,0 +1,105 @@
+use std::collections::BTreeMap;
+use async_trait::async_trait;
+use chrono::{FixedOffset, NaiveDateTime, TimeZone, Utc};
+use serde::{Deserialize, Serialize};
+use exchanges::kucoin_swap_rest::KucoinSwapRest;
+use standard::exchange::ExchangeEnum;
+use standard::utils;
+use crate::ExportConnector;
+
+pub struct KucoinSwapExport {
+    request: KucoinSwapRest,
+}
+
+impl KucoinSwapExport {
+    pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> KucoinSwapExport {
+        KucoinSwapExport {
+            request: KucoinSwapRest::new(is_colo, params.clone())
+        }
+    }
+}
+
+/// TradesSwap
+/// - `symbol`: String, 合約編號
+/// - `trade_id`: String, 交易編號
+/// - `order_id`: String, 訂單編號
+/// - `side`: String, 買賣方向
+/// - `liquidity`: String,流動性類型 taker or maker
+/// - `force_taker`: bool, 是否強製作爲taker處理
+/// - `price`: String, 成交價格
+/// - `size`: i64, 成交數量
+/// - `value`: String, 成交價值
+/// - `fee_rate`: String, 費率
+/// - `fix_fee`: String, 固定費用
+/// - `fee_currency`: String, 收費幣種
+/// - `stop`: String, 止損單類型標記
+/// - `fee`: String, 交易費用
+/// - `order_type`: String, 訂單類型
+/// - `trade_type`: String, 交易類型: trade, liquidation, ADL or settlement
+/// - `created_at`: i64, 創建時間
+/// - `settle_currency`: String, 結算幣種
+/// - `trade_time`: i64, 交易時間納秒
+#[derive(Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+struct TradesSwap {
+    symbol: String,
+    trade_id: String,
+    order_id: String,
+    side: String,
+    liquidity: String,
+    force_taker: bool,
+    price: String,
+    size: i64,
+    value: String,
+    fee_rate: String,
+    fix_fee: String,
+    fee_currency: String,
+    stop: String,
+    fee: String,
+    order_type: String,
+    trade_type: String,
+    created_at: i64,
+    settle_currency: String,
+    trade_time: i64,
+}
+
+#[async_trait]
+impl ExportConnector for KucoinSwapExport {
+    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 res_data = self.request.get_fills(symbol_format, "".to_string(), "".to_string(), start_time, end_time, limit).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<TradesSwap> = 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 %T").to_string();
+                let trade_time = FixedOffset::east_opt(8 * 3600).unwrap().from_utc_datetime(&Utc.timestamp_nanos(value.trade_time.clone()).naive_utc()).format("%Y-%m-%d %T").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.value.clone(),
+                    value.fee_rate.clone(),
+                    value.fix_fee.clone(),
+                    value.fee.clone(),
+                    value.order_type.clone(),
+                    created_at,
+                    trade_time,
+                ];
+            }
+            global::export_utils::export_excel(header_array, data_array, prefix_name)
+        } else {
+            res_data.to_string()
+        }
+    }
+}

+ 10 - 0
derive/src/lib.rs

@@ -0,0 +1,10 @@
+use async_trait::async_trait;
+
+pub mod binance_swap_export;
+pub mod export_excel;
+mod kucoin_swap_export;
+
+#[async_trait]
+pub trait ExportConnector {
+    async fn export_trades(&mut self, prefix_name: &str, symbol: String, start_time: i64, end_time: i64, limit: i64) -> String;
+}

+ 19 - 0
derive/tests/binance_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 = "BLZ_USDT";
+
+// 测试获取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::BinanceSwap).await;
+    let export_trades = export.export_trades("binance_swap","".to_string(), 0, 0, 50).await;
+    trace!(?export_trades);
+}

+ 39 - 0
derive/tests/export_excel_test.rs

@@ -0,0 +1,39 @@
+use std::collections::{BTreeMap};
+use tracing::trace;
+use derive::export_excel::{ExportEnum, ExportExcel};
+use derive::ExportConnector;
+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!("检测有代理配置,配置走代理");
+        }
+    }
+
+    let account_info = global::account_info::get_account_info("../test_account.toml");
+
+    match export_enum {
+        ExportEnum::BinanceSwap => {
+            let mut params: BTreeMap<String, String> = BTreeMap::new();
+            let access_key = account_info.binance_access_key;
+            let secret_key = account_info.binance_secret_key;
+            params.insert("access_key".to_string(), access_key);
+            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
+        }
+    }
+}

+ 18 - 0
derive/tests/kucoin_swap_export_test.rs

@@ -0,0 +1,18 @@
+mod export_excel_test;
+
+use tracing::{instrument, trace};
+use derive::export_excel::ExportEnum;
+use crate::export_excel_test::test_new_export;
+
+
+const SYMBOL: &str = "LOOM_USDT";
+// 测试获取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::KucoinSwap).await;
+    let export_trades = export.export_trades("kucoin_swap",SYMBOL.to_string(), 0, 0, 100).await;
+    trace!(?export_trades);
+}

+ 1 - 1
global/src/export_utils.rs

@@ -2,7 +2,7 @@ use chrono::Local;
 use simple_excel_writer::*;
 use uuid::Uuid;
 
-pub fn export_excel(header_array: Vec<&str>, data: Vec<Vec<&str>>, prefix_name: &str) -> String {
+pub fn export_excel(header_array: Vec<&str>, data: Vec<Vec<String>>, prefix_name: &str) -> String {
     //本地存储路径
     let save_path = "C:/Users/Public/Documents/";
     let _ = std::fs::create_dir(format!("{}rust_export/", save_path));

+ 0 - 1
standard/src/okx_swap.rs

@@ -740,7 +740,6 @@ impl Platform for OkxSwap {
         let res_data = self.request.get_incomplete_order(symbol_format.clone()).await;
         if res_data.code == "200" {
             let res_data_str = &res_data.data;
-            println!("{}", res_data_str);
             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)