Browse Source

清理交易所 只留gate

JiahengHe 11 months ago
parent
commit
0312c25630
100 changed files with 20 additions and 23946 deletions
  1. 6 7
      Cargo.toml
  2. 0 3
      derive/.gitignore
  3. 0 21
      derive/Cargo.toml
  4. 0 92
      derive/src/binance_swap_export.rs
  5. 0 78
      derive/src/bitget_spot_export.rs
  6. 0 46
      derive/src/export_excel.rs
  7. 0 94
      derive/src/gate_swap_export.rs
  8. 0 104
      derive/src/kucoin_spot_export.rs
  9. 0 110
      derive/src/kucoin_swap_export.rs
  10. 0 14
      derive/src/lib.rs
  11. 0 120
      derive/src/okx_swap_export.rs
  12. 0 19
      derive/tests/binance_swap_export_test.rs
  13. 0 18
      derive/tests/bitget_spot_export_test.rs
  14. 0 77
      derive/tests/export_excel_test.rs
  15. 0 19
      derive/tests/gate_swap_export_test.rs
  16. 0 18
      derive/tests/kucoin_spot_export_test.rs
  17. 0 18
      derive/tests/kucoin_swap_export_test.rs
  18. 0 18
      derive/tests/okx_swap_export_test.rs
  19. 0 14
      exchanges/src/binance_spot_rest.rs
  20. 0 255
      exchanges/src/binance_spot_ws.rs
  21. 0 458
      exchanges/src/binance_swap_rest.rs
  22. 0 264
      exchanges/src/binance_swap_ws.rs
  23. 0 825
      exchanges/src/bitget_spot_rest.rs
  24. 0 346
      exchanges/src/bitget_spot_ws.rs
  25. 0 394
      exchanges/src/bitget_swap_rest.rs
  26. 0 316
      exchanges/src/bitget_swap_ws.rs
  27. 0 481
      exchanges/src/bybit_swap_rest.rs
  28. 0 353
      exchanges/src/bybit_swap_ws.rs
  29. 0 696
      exchanges/src/coinex_swap_rest.rs
  30. 0 414
      exchanges/src/coinex_swap_ws.rs
  31. 0 285
      exchanges/src/crypto_spot_ws.rs
  32. 0 15
      exchanges/src/gate_spot_rest.rs
  33. 0 15
      exchanges/src/gate_spot_ws.rs
  34. 0 508
      exchanges/src/htx_swap_rest.rs
  35. 0 467
      exchanges/src/htx_swap_ws.rs
  36. 0 521
      exchanges/src/kucoin_spot_rest.rs
  37. 0 378
      exchanges/src/kucoin_spot_ws.rs
  38. 0 625
      exchanges/src/kucoin_swap_rest.rs
  39. 0 403
      exchanges/src/kucoin_swap_ws.rs
  40. 0 23
      exchanges/src/lib.rs
  41. 0 580
      exchanges/src/okx_swap_rest.rs
  42. 0 371
      exchanges/src/okx_swap_ws.rs
  43. 0 94
      exchanges/tests/binance_spot_test.rs
  44. 0 246
      exchanges/tests/binance_swap_test.rs
  45. 0 515
      exchanges/tests/bitget_spot_test.rs
  46. 0 145
      exchanges/tests/bitget_swap_test.rs
  47. 0 320
      exchanges/tests/bybit_swap_test.rs
  48. 0 383
      exchanges/tests/coinex_swap_test.rs
  49. 0 86
      exchanges/tests/crypto_spot_test.rs
  50. 0 314
      exchanges/tests/htx_swap_test.rs
  51. 0 264
      exchanges/tests/kucoin_spot_test.rs
  52. 0 168
      exchanges/tests/kucoin_swap_test.rs
  53. 0 411
      exchanges/tests/okx_swap_test.rs
  54. 0 67
      exchanges/tests/socket_tool_test.rs
  55. 0 9
      src/core_libs.rs
  56. 0 118
      standard/src/binance_spot.rs
  57. 0 51
      standard/src/binance_spot_handle.rs
  58. 0 397
      standard/src/binance_swap.rs
  59. 0 40
      standard/src/binance_swap_handle.rs
  60. 0 625
      standard/src/bitget_spot.rs
  61. 0 136
      standard/src/bitget_spot_handle.rs
  62. 0 672
      standard/src/bitget_swap.rs
  63. 0 181
      standard/src/bitget_swap_handle.rs
  64. 0 752
      standard/src/bybit_swap.rs
  65. 0 209
      standard/src/bybit_swap_handle.rs
  66. 0 775
      standard/src/coinex_swap.rs
  67. 0 158
      standard/src/coinex_swap_handle.rs
  68. 1 53
      standard/src/exchange.rs
  69. 0 9
      standard/src/gate_swap.rs
  70. 1 192
      standard/src/handle_info.rs
  71. 0 643
      standard/src/htx_swap.rs
  72. 0 135
      standard/src/htx_swap_handle.rs
  73. 0 155
      standard/src/kucoin_handle.rs
  74. 0 738
      standard/src/kucoin_spot.rs
  75. 0 136
      standard/src/kucoin_spot_handle.rs
  76. 0 675
      standard/src/kucoin_swap.rs
  77. 0 21
      standard/src/lib.rs
  78. 0 198
      standard/src/okx_handle.rs
  79. 0 1072
      standard/src/okx_swap.rs
  80. 10 10
      standard/src/utils.rs
  81. 0 31
      standard/tests/binance_handle_test.rs
  82. 0 31
      standard/tests/binance_spot_handle_test.rs
  83. 0 172
      standard/tests/binance_swap_test.rs
  84. 0 56
      standard/tests/bitget_spot_handle_test.rs
  85. 0 195
      standard/tests/bitget_spot_test.rs
  86. 0 56
      standard/tests/htx_handle_test.rs
  87. 0 282
      standard/tests/htx_swap_test.rs
  88. 0 68
      standard/tests/kucoin_handle_test.rs
  89. 0 56
      standard/tests/kucoin_spot_handle_test.rs
  90. 0 145
      standard/tests/kucoin_spot_test.rs
  91. 0 271
      standard/tests/kucoin_swap_test.rs
  92. 0 68
      standard/tests/okx_handle_test.rs
  93. 0 229
      standard/tests/okx_swap_test.rs
  94. 0 137
      strategy/src/binance_spot.rs
  95. 0 104
      strategy/src/binance_usdt_swap.rs
  96. 0 222
      strategy/src/bitget_spot.rs
  97. 0 189
      strategy/src/bitget_usdt_swap.rs
  98. 0 252
      strategy/src/bybit_usdt_swap.rs
  99. 2 56
      strategy/src/clear_core.rs
  100. 0 270
      strategy/src/coinex_usdt_swap.rs

+ 6 - 7
Cargo.toml

@@ -8,26 +8,25 @@ edition = "2021"
 [dependencies]
 [dependencies]
 strategy = {path="./strategy"}
 strategy = {path="./strategy"}
 standard = { path="./standard" }
 standard = { path="./standard" }
-exchanges = { path="./exchanges" }
+#exchanges = { path="./exchanges" }
 global = { path="./global" }
 global = { path="./global" }
 tokio = { version = "1.31.0", features = ["full"] }
 tokio = { version = "1.31.0", features = ["full"] }
 chrono = "0.4.26"
 chrono = "0.4.26"
 tracing = "0.1"
 tracing = "0.1"
-tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
+#tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
 tracing-appender-timezone = { git = "https://github.com/skyfffire/tracing-appender-timezone.git" }
 tracing-appender-timezone = { git = "https://github.com/skyfffire/tracing-appender-timezone.git" }
 serde = { version = "1.0.188", features = ["derive"] }
 serde = { version = "1.0.188", features = ["derive"] }
-actix-rt = "2.5.0"
+#actix-rt = "2.5.0"
 actix-web = "4.0.0-beta.12"
 actix-web = "4.0.0-beta.12"
 ctrlc = "3.2.5"
 ctrlc = "3.2.5"
 serde_json = "1.0.105"
 serde_json = "1.0.105"
-rust_decimal = { version = "1.32.0", features = ["maths"] }
-rust_decimal_macros = "1.32.0"
+#rust_decimal = { version = "1.32.0", features = ["maths"] }
+#rust_decimal_macros = "1.32.0"
 
 
 [workspace]
 [workspace]
 members=[
 members=[
     "exchanges",
     "exchanges",
     "standard",
     "standard",
     "strategy",
     "strategy",
-    "global",
-    "derive"
+    "global"
 ]
 ]

+ 0 - 3
derive/.gitignore

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

+ 0 - 21
derive/Cargo.toml

@@ -1,21 +0,0 @@
-[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"] }

+ 0 - 92
derive/src/binance_swap_export.rs

@@ -1,92 +0,0 @@
-// use std::collections::BTreeMap;
-// use async_trait::async_trait;
-// use chrono::{FixedOffset, NaiveDateTime, TimeZone};
-// use serde::{Deserialize, Serialize};
-// use tracing::warn;
-// 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 limit_params = if limit > 1000 {
-//             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();
-//
-//                 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()
-//         }
-//     }
-// }

+ 0 - 78
derive/src/bitget_spot_export.rs

@@ -1,78 +0,0 @@
-// 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()
-//         }
-//     }
-// }

+ 0 - 46
derive/src/export_excel.rs

@@ -1,46 +0,0 @@
-// use std::collections::BTreeMap;
-// use crate::binance_swap_export::BinanceSwapExport;
-// 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;
-//
-// #[derive(Debug, Clone, PartialEq, Eq)]
-// pub enum ExportEnum {
-//     BinanceSwap,
-//     KucoinSwap,
-//     KucoinSpot,
-//     GateSwap,
-//     BitgetSpot,
-//     OkxSwap,
-// }
-//
-// #[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)
-//             }
-//             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)
-//             }
-//         }
-//     }
-// }

+ 0 - 94
derive/src/gate_swap_export.rs

@@ -1,94 +0,0 @@
-// 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::{error, warn};
-// use exchanges::gate_swap_rest::GateSwapRest;
-// use standard::utils;
-// use crate::ExportConnector;
-// 
-// pub struct GateSwapExport {
-//     request: GateSwapRest,
-// }
-// 
-// impl GateSwapExport {
-//     pub async fn new(is_colo: bool, params: BTreeMap<String, String>) -> GateSwapExport {
-//         GateSwapExport {
-//             request: GateSwapRest::new(is_colo, 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 {
-//     id: i64,
-//     create_time: f64,
-//     contract: String,
-//     order_id: String,
-//     size: i64,
-//     price: String,
-//     text: String,
-//     fee: String,
-//     point_fee: String,
-//     role: String,
-// }
-// 
-// #[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();
-//         let symbol_format = utils::format_symbol(symbol.clone(), "_");
-//         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 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()
-//         }
-//     }
-// }

+ 0 - 104
derive/src/kucoin_spot_export.rs

@@ -1,104 +0,0 @@
-// 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()
-//         }
-//     }
-// }

+ 0 - 110
derive/src/kucoin_swap_export.rs

@@ -1,110 +0,0 @@
-// use std::collections::BTreeMap;
-// use async_trait::async_trait;
-// use chrono::{FixedOffset, NaiveDateTime, TimeZone, Utc};
-// use serde::{Deserialize, Serialize};
-// use tracing::warn;
-// 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 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<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 %H:%M:%S%.3f").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 %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.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()
-//         }
-//     }
-// }

+ 0 - 14
derive/src/lib.rs

@@ -1,14 +0,0 @@
-use async_trait::async_trait;
-
-mod binance_swap_export;
-pub mod export_excel;
-mod kucoin_swap_export;
-mod kucoin_spot_export;
-mod gate_swap_export;
-mod bitget_spot_export;
-mod okx_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;
-}

+ 0 - 120
derive/src/okx_swap_export.rs

@@ -1,120 +0,0 @@
-// 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()
-//         }
-//     }
-// }

+ 0 - 19
derive/tests/binance_swap_export_test.rs

@@ -1,19 +0,0 @@
-// 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",SYMBOL.to_string(), 0, 0, 100).await;
-//     trace!(?export_trades);
-// }

+ 0 - 18
derive/tests/bitget_spot_export_test.rs

@@ -1,18 +0,0 @@
-// 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::BitgetSpot).await;
-//     let export_trades = export.export_trades("bitget_spot",SYMBOL.to_string(), 0, 0, 100).await;
-//     trace!(?export_trades);
-// }

+ 0 - 77
derive/tests/export_excel_test.rs

@@ -1,77 +0,0 @@
-// 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
-//         }
-//         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;
-//             let secret_key = account_info.gate_secret_key;
-//             params.insert("access_key".to_string(), access_key);
-//             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
-//         }
-//     }
-// }

+ 0 - 19
derive/tests/gate_swap_export_test.rs

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

+ 0 - 18
derive/tests/kucoin_spot_export_test.rs

@@ -1,18 +0,0 @@
-// 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::KucoinSpot).await;
-//     let export_trades = export.export_trades("kucoin_spot",SYMBOL.to_string(), 0, 0, 100).await;
-//     trace!(?export_trades);
-// }

+ 0 - 18
derive/tests/kucoin_swap_export_test.rs

@@ -1,18 +0,0 @@
-// 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);
-// }

+ 0 - 18
derive/tests/okx_swap_export_test.rs

@@ -1,18 +0,0 @@
-// 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::OkxSwap).await;
-//     let export_trades = export.export_trades("okx_swap",SYMBOL.to_string(), 0, 0, 100).await;
-//     trace!(?export_trades);
-// }

+ 0 - 14
exchanges/src/binance_spot_rest.rs

@@ -1,14 +0,0 @@
-use std::collections::BTreeMap;
-
-#[derive(Clone)]
-pub struct BinanceSpotRest {}
-
-impl BinanceSpotRest {
-    pub fn new(_is_colo: bool, _login_param: BTreeMap<String, String>) -> BinanceSpotRest
-    {
-        return BinanceSpotRest::new_label("default-BinanceSpotRest".to_string(), _is_colo, _login_param);
-    }
-    pub fn new_label(_label: String, _is_colo: bool, _login_param: BTreeMap<String, String>) -> BinanceSpotRest {
-        BinanceSpotRest {}
-    }
-}

+ 0 - 255
exchanges/src/binance_spot_ws.rs

@@ -1,255 +0,0 @@
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-//
-// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-// use serde_json::json;
-// use tokio::sync::Mutex;
-// use tokio_tungstenite::tungstenite::{Error, Message};
-// use tracing::{info, trace};
-//
-// use crate::response_base::ResponseData;
-// use crate::socket_tool::AbstractWsMode;
-//
-// pub enum BinanceSpotWsType {
-//     //订阅频道类型
-//     PublicAndPrivate,
-// }
-//
-// //订阅频道
-// #[derive(Clone)]
-// pub enum BinanceSpotSubscribeType {
-//     PuBookTicker,
-//     PuAggTrade,
-//     PuDepth20levels100ms,
-// }
-//
-// //账号信息
-// #[derive(Clone)]
-// #[allow(dead_code)]
-// pub struct BinanceSpotLogin {
-//     pub api_key: String,
-//     pub api_secret: String,
-// }
-//
-//
-// #[derive(Clone)]
-// #[allow(dead_code)]
-// pub struct BinanceSpotWs {
-//     //类型
-//     label: String,
-//     //地址
-//     address_url: String,
-//     //账号信息
-//     login_param: Option<BinanceSpotLogin>,
-//     //币对
-//     symbol_s: Vec<String>,
-//     //订阅
-//     subscribe_types: Vec<BinanceSpotSubscribeType>,
-//     //心跳间隔
-//     heartbeat_time: u64,
-// }
-//
-// impl BinanceSpotWs {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//     pub fn new(is_colo: bool, login_param: Option<BinanceSpotLogin>, ws_type: BinanceSpotWsType) -> BinanceSpotWs {
-//         return BinanceSpotWs::new_label("default-BinanceSpotWs".to_string(), is_colo, login_param, ws_type);
-//     }
-//     pub fn new_label(label: String, is_colo: bool, login_param: Option<BinanceSpotLogin>, ws_type: BinanceSpotWsType) -> BinanceSpotWs {
-//         /*******公共频道-私有频道数据组装*/
-//         let address_url = match ws_type {
-//             BinanceSpotWsType::PublicAndPrivate => {
-//                 "wss://stream.binance.com:9443/ws".to_string()
-//             }
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",address_url);
-//         } else {
-//             info!("走普通通道:{}",address_url);
-//         }
-//         /*****返回结构体*******/
-//         BinanceSpotWs {
-//             label,
-//             address_url,
-//             login_param,
-//             symbol_s: vec![],
-//             subscribe_types: vec![],
-//             heartbeat_time: 1000 * 20,
-//         }
-//     }
-//
-//     /*******************************************************************************************************/
-//     /*****************************************订阅函数********************************************************/
-//     /*******************************************************************************************************/
-//     //手动添加订阅信息
-//     pub fn set_subscribe(&mut self, subscribe_types: Vec<BinanceSpotSubscribeType>) {
-//         self.subscribe_types.extend(subscribe_types);
-//     }
-//     //手动添加币对
-//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-//         for symbol in b_array.iter_mut() {
-//             // 小写
-//             *symbol = symbol.to_lowercase();
-//             // 字符串替换
-//             *symbol = symbol.replace("_", "");
-//             *symbol = symbol.replace("-", "");
-//         }
-//         self.symbol_s = b_array;
-//     }
-//     //频道是否需要登录
-//     fn contains_pr(&self) -> bool {
-//         for t in self.subscribe_types.clone() {
-//             if match t {
-//                 BinanceSpotSubscribeType::PuBookTicker => false,
-//                 BinanceSpotSubscribeType::PuAggTrade => false,
-//                 BinanceSpotSubscribeType::PuDepth20levels100ms => false,
-//             } {
-//                 return true;
-//             }
-//         }
-//         false
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************工具函数********************************************************/
-//     /*******************************************************************************************************/
-//     //订阅枚举解析
-//     pub fn enum_to_string(symbol: String, subscribe_type: BinanceSpotSubscribeType) -> String {
-//         match subscribe_type {
-//             BinanceSpotSubscribeType::PuAggTrade => {
-//                 format!("{}@aggTrade", symbol)
-//             }
-//             BinanceSpotSubscribeType::PuDepth20levels100ms => {
-//                 format!("{}@depth20@100ms", symbol)
-//             }
-//             BinanceSpotSubscribeType::PuBookTicker => {
-//                 format!("{}@bookTicker", symbol)
-//             }
-//         }
-//     }
-//     //订阅信息生成
-//     pub fn get_subscription(&self) -> String {
-//         let mut params = vec![];
-//         for symbol in &self.symbol_s {
-//             for subscribe_type in &self.subscribe_types {
-//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-//                 params.push(ty_str);
-//             }
-//         }
-//
-//         let str = json!({
-//             "method": "SUBSCRIBE",
-//             "params":  params,
-//             "id": 1
-//             });
-//         str.to_string()
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************socket基本*****************************************************/
-//     /*******************************************************************************************************/
-//     //链接
-//     pub async fn ws_connect_async(&mut self,
-//                                   is_shutdown_arc: Arc<AtomicBool>,
-//                                   _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-//                                   write_rx: UnboundedReceiver<Message>,
-//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-//     {
-//         let login_is = self.contains_pr();
-//         let subscription = self.get_subscription();
-//         let address_url = self.address_url.clone();
-//         let label = self.label.clone();
-//         // let heartbeat_time = self.heartbeat_time.clone();
-//
-//
-//         //心跳-- 方法内部线程启动
-//         // let write_tx_clone1 = Arc::clone(write_tx_am);
-//         // tokio::spawn(async move {
-//         //     trace!("线程-异步心跳-开始");
-//         //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Pong, heartbeat_time).await;
-//         //     trace!("线程-异步心跳-结束");
-//         // });
-//
-//         //设置订阅
-//         let mut subscribe_array = vec![];
-//         if login_is {
-//             //登录相关
-//         }
-//         subscribe_array.push(subscription.to_string());
-//
-//         //链接
-//         let t2 = tokio::spawn(async move {
-//             trace!("线程-异步链接-开始");
-//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
-//                                                    label.clone(), subscribe_array,
-//                                                    write_rx, read_tx,
-//                                                    Self::message_text,
-//                                                    Self::message_ping,
-//                                                    Self::message_pong,
-//             ).await {
-//                 Ok(_) => { trace!("线程-异步链接-结束"); }
-//                 Err(e) => { trace!("发生异常:币安-现货链接关闭-{:?}",e); }
-//             }
-//             trace!("线程-异步链接-结束");
-//         });
-//         tokio::try_join!(t2).unwrap();
-//         trace!("线程-心跳与链接-结束");
-//
-//         Ok(())
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************数据解析*****************************************************/
-//     /*******************************************************************************************************/
-//     //数据解析-Text
-//     pub fn message_text(text: String) -> Option<ResponseData> {
-//         let response_data = Self::ok_text(text);
-//         Option::from(response_data)
-//     }
-//     //数据解析-ping
-//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "pong".to_string()));
-//     }
-//     //数据解析-pong
-//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析
-//     pub fn ok_text(text: String) -> ResponseData {
-//         // trace!("原始数据");
-//         // trace!(?text);
-//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-//
-//         if json_value.get("result").is_some() &&
-//             json_value.get("id").is_some()
-//         {
-//             //订阅反馈
-//             res_data.code = "-201".to_string();
-//             res_data.channel = "".to_string();
-//             res_data.message = "订阅成功!".to_string();
-//         } else if json_value.get("e").is_some() &&
-//             json_value["e"].as_str() == Option::from("aggTrade")
-//         {
-//             res_data.channel = "aggTrade".to_string();
-//             res_data.data = text;
-//         } else if json_value.get("u").is_some() &&
-//             json_value.get("s").is_some() &&
-//             json_value.get("b").is_some() &&
-//             json_value.get("B").is_some() &&
-//             json_value.get("a").is_some() &&
-//             json_value.get("A").is_some()
-//         {
-//             res_data.channel = "bookTicker".to_string();
-//             res_data.data = text;
-//         } else if json_value.get("bids").is_some() &&
-//             json_value.get("asks").is_some()
-//         {
-//             res_data.channel = "depth".to_string();
-//             res_data.data = text;
-//         } else {
-//             res_data.code = "".to_string();
-//             res_data.channel = "未知的频道".to_string();
-//         }
-//         res_data
-//     }
-// }

+ 0 - 458
exchanges/src/binance_swap_rest.rs

@@ -1,458 +0,0 @@
-use std::collections::BTreeMap;
-use std::str::FromStr;
-use reqwest::header::HeaderMap;
-use hex;
-use reqwest::Client;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-use tracing::{error, info, trace};
-use ring::hmac;
-use serde_json::{json, Value};
-
-#[derive(Clone)]
-pub struct BinanceSwapRest {
-    label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //登录所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl BinanceSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BinanceSwapRest
-    {
-        return BinanceSwapRest::new_label("default-BinanceSwapRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BinanceSwapRest
-    {
-        let base_url = if is_colo {
-            "https://fapi.binance.com".to_string()
-        } else {
-            "https://fapi.binance.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",base_url);
-        } else {
-            info!("走普通通道:{}",base_url);
-        }
-        /*****返回结构体*******/
-        BinanceSwapRest {
-            label,
-            base_url: base_url.to_string(),
-            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(),
-                                "".to_string(),
-                                format!("/fapi/v1/time"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //获取交易规则和交易对
-    pub async fn get_exchange_info(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-         });
-
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/exchangeInfo"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-
-    //账户信息
-    pub async fn get_account(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "recvWindow":"2000"
-         });
-
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v2/balance"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //查询订单
-    pub async fn get_order(&mut self, symbol: String, order_id: i64, orig_client_order_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-            "recvWindow":"2000"
-         });
-        if order_id > 0 {
-            params["orderId"] = json!(order_id);
-        }
-        if orig_client_order_id.len() > 0 {
-            params["origClientOrderId"] = json!(orig_client_order_id);
-        }
-
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/order"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查看当前全部挂单
-    pub async fn get_open_orders(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "recvWindow":"2000"
-         });
-
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/openOrders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查询所有订单(包括历史订单)
-    pub async fn get_all_orders(&mut self, symbol: String, limit: u64, start_time: i64, end_time: i64) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "limit":limit,
-            "startTime":start_time,
-            "endTime":end_time,
-            "recvWindow":"2000"
-         });
-
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/allOrders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //当前最优挂单
-    pub async fn get_book_ticker(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol
-         });
-
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/ticker/bookTicker"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //用户持仓风险V2
-    pub async fn get_position_risk(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "recvWindow":"2000"
-         });
-
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v2/positionRisk"),
-                                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(),
-                                "".to_string(),
-                                format!("/fapi/v1/order"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //更改持仓模式
-    pub async fn change_pos_side(&mut self, dual_side_position: bool) -> ResponseData {
-        let dual_side_position_str = format!("{}", dual_side_position);
-        let params = serde_json::json!({
-            "dualSidePosition":dual_side_position_str,
-            "recvWindow":"2000"
-         });
-        let data = self.request("POST".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/positionSide/dual"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //撤销订单
-    pub async fn cancel_order(&mut self, symbol: String, order_id: i64, orig_client_order_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-            "recvWindow":"2000"
-         });
-        if order_id > 0 {
-            params["orderId"] = json!(order_id);
-        }
-        if orig_client_order_id.len() > 0 {
-            params["origClientOrderId"] = json!(orig_client_order_id);
-        }
-        let data = self.request("DELETE".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/order"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //根据币对 撤销全部订单
-    pub async fn cancel_order_all(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol":symbol,
-            "recvWindow":"2000",
-         });
-        let data = self.request("DELETE".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/allOpenOrders"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //账户成交历史
-    pub async fn get_user_trades(&mut self, symbol: String, start_time: i64, end_time: i64, limit: i64) -> ResponseData {
-        let mut params = serde_json::json!({
-            "symbol":symbol,
-            "limit":1000,
-            "recvWindow":"1000",
-         });
-        if start_time > 0 {
-            params["startTime"] = json!(start_time);
-        }
-        if end_time > 0 {
-            params["endTime"] = json!(end_time);
-        }
-        if limit > 0 {
-            params["limit"] = json!(limit);
-        }
-        let data = self.request("GET".to_string(),
-                                "".to_string(),
-                                format!("/fapi/v1/userTrades"),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        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();
-    }
-
-    //调用请求
-    async fn request(&mut self,
-                     request_type: 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();
-        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();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" {
-            is_login_param = false
-        }
-
-        //请求头配置-如果需要登录则存在额外配置
-        let mut params_json: serde_json::Value = serde_json::from_str(params.clone().as_str()).unwrap();
-        // let mut body = "".to_string();
-        let timestamp = chrono::Utc::now().timestamp_millis().to_string();
-        params_json.as_object_mut().unwrap().insert("timestamp".to_string(), serde_json::Value::from(timestamp));
-
-
-        let mut headers = HeaderMap::new();
-        if request_type == "GET" {
-            headers.insert("Content-Type", "application/json; charset=UTF-8".parse().unwrap());
-        } else if request_type == "POST" || request_type == "PUT" || request_type == "DELETE" {
-            headers.insert("Content-Type", "application/x-www-form-urlencoded".parse().unwrap());
-        }
-
-
-        //是否需要登录-- 组装sing
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登录参数错误!".to_string());
-                return e;
-            } else {//需要登录-且登录参数齐全
-                //组装sing
-                let sing = Self::sign(secret_key.clone(),
-                                      params_json.to_string(),
-                );
-                params_json.as_object_mut().unwrap().insert("signature".to_string(), serde_json::Value::from(sing.clone()));
-                // trace!("sing:{}", sing);
-                //组装header
-                headers.extend(Self::headers(access_key));
-            }
-        }
-
-        trace!("headers:{:?}", headers);
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let response = self.http_tool(
-            format!("{}{}", prefix_url.clone(), request_url.clone()),
-            request_type.to_string(),
-            params_json.to_string(),
-            headers,
-        ).await;
-
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        self.get_delay_info();
-
-        response
-    }
-
-    pub fn headers(access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("X-MBX-APIKEY", access_key.parse().unwrap());
-        headers
-    }
-    pub fn sign(secret_key: String, params_str: String) -> String
-    {
-        /*签名生成*/
-        let params_str_v = RestTool::parse_params_to_str(params_str.to_string());
-        let message = format!("{}", params_str_v);
-
-        // let secret_key2 = "2b5eb11e18796d12d88f13dc27dbbd02c2cc51ff7059765ed9821957d82bb4d9";
-        // let message2 = "symbol=BTCUSDT&side=BUY&type=LIMIT&quantity=1&price=9000&timeInForce=GTC&recvWindow=5000&timestamp=1591702613943";
-        let signed_key = hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_ref());
-        let sign = hex::encode(hmac::sign(&signed_key, message.as_bytes()).as_ref());
-
-        sign
-    }
-
-
-    async fn http_tool(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> ResponseData {
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-        let url_param = RestTool::parse_params_to_str(params.clone());
-        let addrs_url = format!("{}?{}", url.clone(), url_param);
-
-        let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-        trace!("url:{}",url);
-        trace!("addrs_url:{}",addrs_url);
-        trace!("params_json:{}",params_json);
-        trace!("headers:{:?}",headers);
-        trace!("body:{:?}",params);
-
-
-        let request_builder = match request_type.as_str() {
-            "GET" => self.client.get(url.clone()).query(&params_json).headers(headers),
-            "POST" => self.client.post(url.clone()).query(&params_json).headers(headers),
-            "DELETE" => self.client.delete(url.clone()).query(&params_json).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => {
-                panic!("{}", format!("错误的请求类型:{}", request_type.clone()))
-            }
-        };
-
-        let response = request_builder.send().await.unwrap();
-        let is_success = response.status().is_success(); // 先检查状态码
-        let text = response.text().await.unwrap();
-        return if is_success {
-            self.on_success_data(text)
-        } else {
-            self.on_error_data(text, addrs_url, params)
-        }
-    }
-
-    pub fn on_success_data(&mut self, text: String) -> ResponseData {
-        let data = serde_json::from_str(text.as_str()).unwrap();
-
-        ResponseData::new(self.label.clone(), 200, "success".to_string(), data)
-    }
-
-    pub fn on_error_data(&mut self, text: String, base_url: String, params: String) -> ResponseData {
-        let json_value = serde_json::from_str::<Value>(&text);
-
-        match json_value {
-            Ok(data) => {
-                let message = data["msg"].as_str().unwrap();
-
-                let mut error = ResponseData::error(self.label.clone(), message.to_string());
-                error.code = i16::from_str(data["code"].as_str().unwrap()).unwrap();
-                error.message = format!("请求地址:{}, 请求参数:{}", base_url, params);
-                error
-            }
-            Err(e) => {
-                error!("解析错误:{:?}", e);
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", e, text));
-                error
-            }
-        }
-    }
-}

+ 0 - 264
exchanges/src/binance_swap_ws.rs

@@ -1,264 +0,0 @@
-use std::str::FromStr;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::Duration;
-
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use serde_json::{json, Value};
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{error, info, trace};
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::AbstractWsMode;
-
-//类型
-pub enum BinanceSwapWsType {
-    PublicAndPrivate,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum BinanceSwapSubscribeType {
-    PuBookTicker,
-    PuAggTrade,
-    PuDepth20levels100ms,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BinanceSwapLogin {
-    pub api_key: String,
-    pub api_secret: String,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BinanceSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号
-    login_param: Option<BinanceSwapLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<BinanceSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl BinanceSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<BinanceSwapLogin>, ws_type: BinanceSwapWsType) -> BinanceSwapWs {
-        return BinanceSwapWs::new_label("default-BinanceSwapWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<BinanceSwapLogin>, ws_type: BinanceSwapWsType) -> BinanceSwapWs {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            BinanceSwapWsType::PublicAndPrivate => {
-                // "wss://fstream.binance.com/stream?streams=btcusdt@depth20@100ms".to_string(),
-                "wss://fstream.binance.com/stream".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        BinanceSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 20,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<BinanceSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 小写
-            *symbol = symbol.to_lowercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "");
-            *symbol = symbol.replace("-", "");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                BinanceSwapSubscribeType::PuBookTicker => false,
-                BinanceSwapSubscribeType::PuAggTrade => false,
-                BinanceSwapSubscribeType::PuDepth20levels100ms => false,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: BinanceSwapSubscribeType) -> String {
-        match subscribe_type {
-            BinanceSwapSubscribeType::PuAggTrade => {
-                format!("{}@aggTrade", symbol)
-            }
-            BinanceSwapSubscribeType::PuDepth20levels100ms => {
-                format!("{}@depth20@100ms", symbol)
-            }
-            BinanceSwapSubscribeType::PuBookTicker => {
-                format!("{}@bookTicker", symbol)
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut params = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                params.push(ty_str);
-            }
-        }
-
-        let str = json!({
-            "method": "SUBSCRIBE",
-            "params":  params,
-            "id": 1
-            });
-        str.to_string()
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async<F, Future>(&mut self,
-                                             is_shutdown_arc: Arc<AtomicBool>,
-                                             handle_function: F,
-                                             _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                             write_to_socket_rx: UnboundedReceiver<Message>) -> Result<(), Error>
-    where
-        F: Fn(ResponseData) -> Future + Clone + Send + 'static + Sync,
-        Future: std::future::Future<Output=()> + Send + 'static, // 确保 Fut 是一个 Future,且输出类型为 ()
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        // let heartbeat_time = self.heartbeat_time.clone();
-
-
-        //心跳-- 方法内部线程启动
-        // let write_tx_clone1 = Arc::clone(write_tx_am);
-        // tokio::spawn(async move {
-        //     trace!("线程-异步心跳-开始");
-        //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Pong, heartbeat_time).await;
-        //     trace!("线程-异步心跳-结束");
-        // });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-        if login_is {
-            //登录相关
-        }
-        subscribe_array.push(subscription.to_string());
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
-
-            loop {
-                info!("binance_usdt_swap socket 连接中……");
-                // ws层重连
-                AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
-                                                 false, label.clone(), subscribe_array.clone(), write_to_socket_rx_arc.clone(),
-                                                 Self::message_text, Self::message_ping, Self::message_pong, Self::message_binary).await;
-
-                error!("binance_usdt_swap socket 断连,1s以后重连……");
-                tokio::time::sleep(Duration::from_secs(1)).await;
-            }
-        });
-
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -300, "success".to_string(), Value::String("pong".to_string())));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -301, "success".to_string(), Value::Null));
-    }
-    //数据解析-二进制
-    pub fn message_binary(_po: Vec<u8>) -> Option<ResponseData> {
-        //二进制WebSocket消息
-        let message_str = format!("Binary:{:?}", _po);
-        Option::from(ResponseData::new("".to_string(), 2, message_str, Value::Null))
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData {
-        // trace!("原始数据");
-        // trace!(?text);
-        let mut res_data = ResponseData::new("".to_string(), 200, "success".to_string(), Value::Null);
-        let json_value: Value = serde_json::from_str(&text).unwrap();
-
-        if json_value.get("result").is_some() && json_value.get("id").is_some() &&
-            json_value.get("id").unwrap() == 1
-        {
-            res_data.code = -201;
-            res_data.message = "订阅成功".to_string();
-        } else if json_value.get("error").is_some() {//订阅返回
-            res_data.code = i16::from_str(json_value["error"]["code"].as_str().unwrap()).unwrap();
-            res_data.message = json_value["error"]["msg"].to_string();
-        } else if json_value.get("stream").is_some() {//订阅返回
-            res_data.data = json_value["data"].clone();
-            res_data.code = 200;
-
-            let channel = json_value["stream"].as_str().unwrap();
-            if channel.contains("@aggTrade") {
-                res_data.channel = "aggTrade".to_string();
-            } else if channel.contains("@depth20@100ms") {
-                res_data.channel = "depth".to_string();
-            } else if channel.contains("@bookTicker") {
-                res_data.channel = "bookTicker".to_string();
-            } else {
-                res_data.code = -1;
-                res_data.channel = "未知的频道".to_string();
-            }
-        } else {
-            res_data.code = -1;
-            res_data.channel = "未知的频道2".to_string();
-        }
-        res_data
-    }
-}

+ 0 - 825
exchanges/src/bitget_spot_rest.rs

@@ -1,825 +0,0 @@
-// use std::collections::BTreeMap;
-// use reqwest::header::HeaderMap;
-// use reqwest::{Client};
-// use rust_decimal::Decimal;
-// use rust_decimal::prelude::FromPrimitive;
-// use rust_decimal_macros::dec;
-// use tracing::{info, trace};
-// use crate::http_tool::RestTool;
-// use crate::response_base::ResponseData;
-// use ring::hmac;
-// use serde_json::Value;
-//
-// #[derive(Clone, Debug)]
-// pub struct BitgetSpotRest {
-//     pub label: String,
-//     base_url: String,
-//     client: reqwest::Client,
-//     /*******参数*/
-//     //是否需要登录
-//     //登录所需参数
-//     login_param: BTreeMap<String, String>,
-//     delays: Vec<i64>,
-//     max_delay: i64,
-//     avg_delay: Decimal,
-//
-// }
-//
-// impl BitgetSpotRest {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//
-//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSpotRest
-//     {
-//         return BitgetSpotRest::new_label("default-BitgetSpotRest".to_string(), is_colo, login_param);
-//     }
-//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSpotRest {
-//         let base_url = if is_colo {
-//             "https://api.bitget.com".to_string()
-//         } else {
-//             "https://api.bitget.com".to_string()
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",base_url);
-//         } else {
-//             info!("走普通通道:{}",base_url);
-//         }
-//         /*****返回结构体*******/
-//         BitgetSpotRest {
-//             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/v2".to_string(),
-//                                 "/public/time".to_string(),
-//                                 false,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //账户信息
-//     pub async fn get_account_info(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/account/info".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取账户币种资产
-//     pub async fn get_account_assets(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/account/assets".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取币种信息
-//     pub async fn get_coins(&mut self, coin: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "coin":coin
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/public/coins".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取交易对信息
-//     pub async fn get_symbols(&mut self, symbol: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/public/symbols".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取现货VIP费率
-//     pub async fn get_vip_fee_rate(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/market/vip-fee-rate".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取行情信息
-//     pub async fn get_tickers(&mut self, symbol: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/market/tickers".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取合并交易深度
-//     pub async fn get_merge_depth(&mut self, symbol: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/market/merge-depth".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取K线数据
-//     //参数:granularity: K线的时间颗粒度
-//     //                   分钟:1min,5min,15min,30min
-//     //                   小时:1h,4h,6h,12h
-//     //                   天:1day,3day
-//     //                   周:1week
-//     //                   月:1M
-//     //                   零时区小时线:6Hutc,12Hutc
-//     //                   零时区日线:1Dutc ,3Dutc
-//     //                   零时区周线:1Wutc
-//     //                   零时区月线:1Mutc
-//     //                   1m、3m、5m可以查一个月 ;15m可以查52天; 30m查62天; 1H可以查83天; 2H可以查120天; 4H可以查240天; 6H可以查360天
-//     //start_time :K线数据的时间起始点,即获取该时间戳以后的K线数据 Unix毫秒时间戳,例如1690196141868
-//     //end_time :K线数据的时间终止点,即获取该时间戳以前的K线数据 Unix毫秒时间戳,例如1690196141868
-//     //limit :查询条数  默认100,最大1000
-//     pub async fn get_candles(&mut self, symbol: String, granularity: String, start_time: String, end_time: String, limit: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol,
-//             "granularity":granularity,
-//             "startTime":start_time,
-//             "endTime":end_time,
-//             "limit":limit,
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/market/candles".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取历史K线数据
-//     pub async fn get_history_candles(&mut self, symbol: String, granularity: String, end_time: String, limit: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol,
-//             "granularity":granularity,
-//             "endTime":end_time,
-//             "limit":limit,
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/market/history-candles".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取最近成交数据
-//     pub async fn get_market_fills(&mut self, symbol: String, limit: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol,
-//             "limit":limit,
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/market/fills".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取历史成交数据
-//     pub async fn get_market_fills_history(&mut self, symbol: String, start_time: String, end_time: String, limit: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "symbol":symbol,
-//             "limit": "1000"
-//          });
-//         if start_time.len() > 0 {
-//             params["startTime"] = serde_json::json!(start_time);
-//         }
-//         if end_time.len() > 0 {
-//             params["endTime"] = serde_json::json!(end_time);
-//         }
-//         if limit.len() > 0 {
-//             params["limit"] = serde_json::json!(limit);
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/market/fills-history".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //下单
-//     pub async fn spot_order(&mut self, params: serde_json::Value) -> ResponseData {
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/place-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //批量下单
-//     pub async fn spot_orders(&mut self, params: serde_json::Value) -> ResponseData {
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/batch-orders".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //撤单
-//     pub async fn spot_cancel_order(&mut self, symbol: String, order_id: String, client_oid: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "symbol":symbol,
-//          });
-//         if order_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-//         }
-//         if client_oid.len() > 0 {
-//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
-//         }
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/cancel-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //批量撤单
-//     pub async fn spot_cancel_orders(&mut self, symbol: String, order_list: Vec<Value>) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol,
-//             "orderList":order_list,
-//          });
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/batch-cancel-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //按币对撤单
-//     pub async fn spot_cancel_symbol_orders(&mut self, symbol: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol,
-//          });
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/cancel-symbol-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取订单详情
-//     pub async fn get_order(&mut self, order_id: String, client_oid: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "orderId":order_id,
-//             "clientOid":client_oid,
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/orderInfo".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取当前委托列表
-//     pub async fn get_unfilled_orders(&mut self,
-//                                      symbol: String,
-//                                      start_time: String,
-//                                      end_time: String,
-//                                      id_less_than: String,
-//                                      limit: String,
-//                                      order_id: String,
-//     ) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "symbol":symbol,
-//          });
-//         if start_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-//         }
-//         if end_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-//         }
-//         if id_less_than.len() > 0 {
-//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-//         }
-//         if limit.len() > 0 {
-//             params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
-//         }
-//         if order_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/unfilled-orders".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取历史委托列表
-//     pub async fn get_history_orders(&mut self,
-//                                     symbol: String,
-//                                     start_time: String,
-//                                     end_time: String,
-//                                     id_less_than: String,
-//                                     limit: String,
-//                                     order_id: String,
-//     ) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "symbol":symbol,
-//          });
-//         if start_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-//         }
-//         if end_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-//         }
-//         if id_less_than.len() > 0 {
-//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-//         }
-//         if limit.len() > 0 {
-//             params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
-//         }
-//         if order_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/history-orders".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //获取成交明细
-//     pub async fn get_fills(&mut self,
-//                            symbol: String,
-//                            order_id: String,
-//                            start_time: String,
-//                            end_time: String,
-//                            limit: String,
-//                            id_less_than: String,
-//     ) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "symbol":symbol,
-//          });
-//         if order_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-//         }
-//         if start_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-//         }
-//         if end_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-//         }
-//         if limit.len() > 0 {
-//             params.as_object_mut().unwrap().insert("limit".parse().unwrap(), serde_json::Value::from(limit));
-//         }
-//         if id_less_than.len() > 0 {
-//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/fills".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //下单计划委托
-//     pub async fn spot_place_plan_order(&mut self, params: serde_json::Value) -> ResponseData {
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/place-plan-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //修改计划委托
-//     pub async fn update_place_plan_order(&mut self, params: serde_json::Value) -> ResponseData {
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/modify-plan-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //撤销计划委托
-//     pub async fn cancel_plan_order(&mut self, order_id: String, client_oid: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//          });
-//         if order_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-//         }
-//         if client_oid.len() > 0 {
-//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
-//         }
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/cancel-plan-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取当前计划委托
-//     pub async fn get_current_plan_order(&mut self,
-//                                         symbol: String,
-//                                         limit: String,
-//                                         id_less_than: String,
-//                                         start_time: String,
-//                                         end_time: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "symbol":symbol,
-//             "limit":limit,
-//          });
-//
-//
-//         if id_less_than.len() > 0 {
-//             params.as_object_mut().unwrap().insert("idLessThan".parse().unwrap(), serde_json::Value::from(id_less_than));
-//         }
-//         if start_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("startTime".parse().unwrap(), serde_json::Value::from(start_time));
-//         }
-//         if end_time.len() > 0 {
-//             params.as_object_mut().unwrap().insert("endTime".parse().unwrap(), serde_json::Value::from(end_time));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/current-plan-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取历史计划委托
-//     pub async fn get_history_plan_order(&mut self,
-//                                         symbol: String,
-//                                         start_time: String,
-//                                         end_time: String,
-//                                         limit: String,
-//     ) -> ResponseData {
-//         let params = serde_json::json!({
-//             "symbol":symbol,
-//             "startTime":start_time,
-//             "endTime":end_time,
-//             "limit":limit,
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/history-plan-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //批量撤销计划委托
-//     pub async fn cancel_plan_orders(&mut self, symbol_list: Vec<String>) -> ResponseData {
-//         let mut params = serde_json::json!({
-//          });
-//         if symbol_list.len() > 0 {
-//             params.as_object_mut().unwrap().insert("symbolList".parse().unwrap(), serde_json::Value::from(symbol_list));
-//         }
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/trade/batch-cancel-plan-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //划转
-//     pub async fn wallet_transfer(&mut self,
-//                                  from_type: String,
-//                                  to_type: String,
-//                                  amount: String,
-//                                  coin: String,
-//                                  symbol: String,
-//                                  client_oid: String,
-//     ) -> ResponseData {
-//         let mut params = serde_json::json!({
-//                    "fromType":from_type ,
-//                    "toType":to_type ,
-//                    "amount":amount ,
-//                    "coin":coin ,
-//          });
-//         if symbol.len() > 0 {
-//             params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
-//         }
-//         if client_oid.len() > 0 {
-//             params.as_object_mut().unwrap().insert("clientOid".parse().unwrap(), serde_json::Value::from(client_oid));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/wallet/transfer".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取账单流水
-//     pub async fn get_account_bills(&mut self,
-//                                    coin: String,
-//                                    limit: String,
-//                                    start_time: String,
-//                                    end_time: String,
-//     ) -> ResponseData {
-//         let mut params = serde_json::json!({
-//                    "coin":coin ,
-//                    "groupType":"transaction" ,
-//                    "limit":limit ,
-//
-//          });
-//         if start_time.len() > 0 {
-//             params["startTime"] = serde_json::json!(start_time);
-//         }
-//         if end_time.len() > 0 {
-//             params["endTime"] = serde_json::json!(end_time);
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 "/spot/account/bills".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************工具函数********************************************************/
-//     /*******************************************************************************************************/
-//     pub fn get_delays(&self) -> Vec<i64> {
-//         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 passphrase = "".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") {
-//             passphrase = self.login_param.get("pass_key").unwrap().to_string();
-//         }
-//         let mut is_login_param = true;
-//         if access_key == "" || secret_key == "" || passphrase == "" {
-//             is_login_param = false
-//         }
-//
-//
-//         //请求头配置-如果需要登录则存在额外配置
-//         let mut body = "".to_string();
-//         let timestamp = Self::get_timestamp();
-//         let mut headers = HeaderMap::new();
-//         headers.insert("Content-Type", "application/json".parse().unwrap());
-//         headers.insert("locale", "en-US".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(),
-//                 );
-//                 //组装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(
-//             format!("{}{}", prefix_url.clone(), request_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("ACCESS-KEY", access_key.parse().unwrap());
-//         headers.insert("ACCESS-SIGN", sign.parse().unwrap());
-//         headers.insert("ACCESS-TIMESTAMP", timestamp.parse().unwrap());
-//         headers.insert("ACCESS-PASSPHRASE", passphrase.parse().unwrap());
-//         headers
-//     }
-//     pub fn sign(secret_key: String,
-//                 method: String, prefix_url: String, request_url: String,
-//                 params: String, body: String, timestamp: String) -> String
-//     {
-//         /*签名生成*/
-//         let url_param_str = RestTool::parse_params_to_str(params);
-//         let base_url = if method == "GET" && url_param_str.len() > 0 {
-//             format!("{}{}?{}", prefix_url, request_url, url_param_str)
-//         } else {
-//             format!("{}{}", prefix_url, request_url)
-//         };
-//
-//         // 时间戳 + 请求类型+ 请求参数字符串
-//         let message = format!("{}{}{}{}", timestamp, method, base_url, body);
-//         trace!("message:{}",message);
-//
-//         // 做签名
-//         let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-//         let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-//         let sign = base64::encode(result);
-//         sign
-//     }
-//
-//     async fn http_tool(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-//         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 params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-//         trace!("params_json:{}",params_json);
-//         trace!("headers:{:?}",headers);
-//
-//
-//         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(&params),
-//             _ => 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<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-//         // trace!("原始数据:{:?}",result);
-//         match result {
-//             Ok(res_data) => {
-//                 if res_data.code != "200" {
-//                     // trace!("不等于200");
-//                     let message: String = res_data.message;
-//                     let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
-//                     let code = json_value["code"].as_str().unwrap();
-//                     let msg = json_value["msg"].as_str().unwrap();
-//                     let error = ResponseData::new("".to_string(),
-//                                                   format!("{}", code),
-//                                                   format!("{}", msg),
-//                                                   format!("请求地址:{},请求参数:{}", base_url, params));
-//                     error
-//                 } else {
-//                     // trace!("等于200");
-//                     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 == "00000" {
-//                         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
-//                     } else {
-//                         let msg = json_value["msg"].as_str().unwrap();
-//                         // trace!("发生错误:??{:?}",data_json.to_string());
-//                         let error = ResponseData::new("".to_string(),
-//                                                       format!("{}", code),
-//                                                       format!("{}", msg),
-//                                                       format!("请求地址:{},请求参数:{}", base_url, params));
-//                         error
-//                     }
-//                 }
-//             }
-//             Err(err) => {
-//                 let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
-//                 error
-//             }
-//         }
-//     }
-//     fn get_timestamp() -> String {
-//         chrono::Utc::now().timestamp_millis().to_string()
-//     }
-// }

+ 0 - 346
exchanges/src/bitget_spot_ws.rs

@@ -1,346 +0,0 @@
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// use std::time::Duration;
-//
-// use chrono::Utc;
-// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-// use ring::hmac;
-// use serde_json::{json, Value};
-// use tokio::sync::Mutex;
-// use tokio_tungstenite::tungstenite::{Error, Message};
-// use tracing::{info, trace};
-//
-// use crate::response_base::ResponseData;
-// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-//
-// //类型
-// pub enum BitgetSpotWsType {
-//     Public,
-//     Private,
-// }
-//
-// //订阅频道
-// #[derive(Clone)]
-// pub enum BitgetSpotSubscribeType {
-//     PuTicker,
-//     PuCandle1m,
-//     PuTrade,
-//     PuBooks5,
-//
-//     PrAccount,
-//     PrOrders,
-// }
-//
-// //账号信息
-// #[derive(Clone)]
-// #[allow(dead_code)]
-// pub struct BitgetSpotLogin {
-//     pub api_key: String,
-//     pub secret_key: String,
-//     pub passphrase_key: String,
-// }
-//
-//
-// #[derive(Clone)]
-// pub struct BitgetSpotWs {
-//     //类型
-//     label: String,
-//     //地址
-//     address_url: String,
-//     //账号
-//     login_param: Option<BitgetSpotLogin>,
-//     //币对
-//     symbol_s: Vec<String>,
-//     //订阅
-//     subscribe_types: Vec<BitgetSpotSubscribeType>,
-//     //心跳间隔
-//     heartbeat_time: u64,
-// }
-//
-// impl BitgetSpotWs {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//     pub fn new(is_colo: bool, login_param: Option<BitgetSpotLogin>, ws_type: BitgetSpotWsType) -> BitgetSpotWs {
-//         return BitgetSpotWs::new_label("default-BitgetSpotWs".to_string(), is_colo, login_param, ws_type);
-//     }
-//     pub fn new_label(label: String, is_colo: bool, login_param: Option<BitgetSpotLogin>, ws_type: BitgetSpotWsType) -> BitgetSpotWs
-//     {
-//         /*******公共频道-私有频道数据组装*/
-//         let address_url = match ws_type {
-//             BitgetSpotWsType::Public => {
-//                 format!("wss://ws.bitget.com/v2/ws/public")
-//             }
-//             BitgetSpotWsType::Private => {
-//                 format!("wss://ws.bitget.com/v2/ws/private")
-//             }
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",address_url);
-//         } else {
-//             info!("走普通通道:{}",address_url);
-//         }
-//
-//         BitgetSpotWs {
-//             label,
-//             address_url,
-//             login_param,
-//             symbol_s: vec![],
-//             subscribe_types: vec![],
-//             heartbeat_time: 1000 * 10,
-//         }
-//     }
-//
-//     /*******************************************************************************************************/
-//     /*****************************************订阅函数********************************************************/
-//     /*******************************************************************************************************/
-//     //手动添加订阅信息
-//     pub fn set_subscribe(&mut self, subscribe_types: Vec<BitgetSpotSubscribeType>) {
-//         self.subscribe_types.extend(subscribe_types);
-//     }
-//     //手动添加币对
-//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-//         for symbol in b_array.iter_mut() {
-//             // 小写
-//             *symbol = symbol.to_uppercase();
-//             // 字符串替换
-//             *symbol = symbol.replace("-", "");
-//             *symbol = symbol.replace("_", "");
-//         }
-//         self.symbol_s = b_array;
-//     }
-//     //频道是否需要登录
-//     fn contains_pr(&self) -> bool {
-//         for t in self.subscribe_types.clone() {
-//             if match t {
-//                 BitgetSpotSubscribeType::PuTicker => false,
-//                 BitgetSpotSubscribeType::PuCandle1m => false,
-//                 BitgetSpotSubscribeType::PuTrade => false,
-//                 BitgetSpotSubscribeType::PuBooks5 => false,
-//
-//                 BitgetSpotSubscribeType::PrAccount => false,
-//                 BitgetSpotSubscribeType::PrOrders => false
-//             } {
-//                 return true;
-//             }
-//         }
-//         false
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************工具函数********************************************************/
-//     /*******************************************************************************************************/
-//     //订阅枚举解析
-//     pub fn enum_to_string(symbol: String, subscribe_type: BitgetSpotSubscribeType) -> Value {
-//         match subscribe_type {
-//             BitgetSpotSubscribeType::PuTicker => {
-//                 json!({
-//                     "instType": "SPOT",
-//                     "channel": "ticker",
-//                     "instId": symbol,
-//                 })
-//             }
-//             BitgetSpotSubscribeType::PuCandle1m => {
-//                 json!({
-//                     "instType": "SPOT",
-//                     "channel": "candle1m",
-//                     "instId": symbol,
-//                 })
-//             }
-//             BitgetSpotSubscribeType::PuTrade => {
-//                 json!({
-//                     "instType": "SPOT",
-//                     "channel": "trade",
-//                     "instId": symbol,
-//                 })
-//             }
-//             BitgetSpotSubscribeType::PuBooks5 => {
-//                 json!({
-//                     "instType": "SPOT",
-//                     "channel": "books5",
-//                     "instId": symbol,
-//                 })
-//             }
-//             BitgetSpotSubscribeType::PrAccount => {
-//                 json!({
-//                     "instType": "SPOT",
-//                     "channel": "account",
-//                     "coin": "default"
-//                 })
-//             }
-//             BitgetSpotSubscribeType::PrOrders => {
-//                 json!({
-//                     "instType": "SPOT",
-//                     "channel": "orders",
-//                     "instId": symbol
-//                 })
-//             }
-//         }
-//     }
-//     //订阅信息生成
-//     pub fn get_subscription(&self) -> String {
-//         let mut params = vec![];
-//         for symbol in &self.symbol_s {
-//             for subscribe_type in &self.subscribe_types {
-//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-//                 params.push(ty_str);
-//             }
-//         }
-//         let str = json!({
-//             "op": "subscribe",
-//             "args": params
-//         });
-//
-//         str.to_string()
-//     }
-//     //登录数据组装
-//     fn log_in_to_str(&self) -> String {
-//         let mut login_json_str = "".to_string();
-//
-//         let mut access_key: String = "".to_string();
-//         let mut secret_key: String = "".to_string();
-//         let mut passphrase: String = "".to_string();
-//         match self.login_param.clone() {
-//             None => {}
-//             Some(param) => {
-//                 access_key = param.api_key;
-//                 secret_key = param.secret_key;
-//                 passphrase = param.passphrase_key;
-//             }
-//         }
-//         if access_key.len() > 0 || secret_key.len() > 0 || passphrase.len() > 0 {
-//             let timestamp = Utc::now().timestamp().to_string();
-//             // 时间戳 + 请求类型+ 请求参数字符串
-//             let message = format!("{}GET{}", timestamp, "/user/verify");
-//             let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-//             let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-//             let sign = base64::encode(result);
-//
-//             let login_json = json!({
-//                               "op": "login",
-//                               "args": [{
-//                                 "apiKey": access_key,
-//                                 "passphrase": passphrase,
-//                                 "timestamp": timestamp,
-//                                 "sign": sign
-//                               }]
-//                         });
-//
-//             trace!("---login_json:{0}", login_json.to_string());
-//             trace!("--登录:{}", login_json.to_string());
-//             login_json_str = login_json.to_string();
-//         }
-//         login_json_str
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************socket基本*****************************************************/
-//     /*******************************************************************************************************/
-//     //链接
-//     pub async fn ws_connect_async(&mut self,
-//                                   is_shutdown_arc: Arc<AtomicBool>,
-//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-//                                   write_rx: UnboundedReceiver<Message>,
-//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-//     {
-//         let login_is = self.contains_pr();
-//         let subscription = self.get_subscription();
-//         let address_url = self.address_url.clone();
-//         let label = self.label.clone();
-//         let heartbeat_time = self.heartbeat_time.clone();
-//
-//
-//         //心跳-- 方法内部线程启动
-//         let write_tx_clone1 = Arc::clone(write_tx_am);
-//         tokio::spawn(async move {
-//             trace!("线程-异步心跳-开始");
-//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
-//             trace!("线程-异步心跳-结束");
-//         });
-//
-//         //设置订阅
-//         let mut subscribe_array = vec![];
-//         if login_is {
-//             //登录相关
-//             let login_str = self.log_in_to_str();
-//             let write_tx_clone2 = Arc::clone(write_tx_am);
-//             AbstractWsMode::send_subscribe(write_tx_clone2, Message::Text(login_str)).await;
-//             tokio::time::sleep(Duration::from_millis(1000 * 3)).await;
-//         }
-//         subscribe_array.push(subscription.to_string());
-//
-//         //链接
-//         let t2 = tokio::spawn(async move {
-//             trace!("线程-异步链接-开始");
-//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
-//                                                    label.clone(), subscribe_array,
-//                                                    write_rx, read_tx,
-//                                                    Self::message_text,
-//                                                    Self::message_ping,
-//                                                    Self::message_pong,
-//             ).await {
-//                 Ok(_) => { trace!("线程-异步链接-结束"); }
-//                 Err(e) => { trace!("发生异常:bitget-现货链接关闭-{:?}",e); }
-//             }
-//             trace!("线程-异步链接-结束");
-//         });
-//         tokio::try_join!(t2).unwrap();
-//         trace!("线程-心跳与链接-结束");
-//
-//         Ok(())
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************数据解析*****************************************************/
-//     /*******************************************************************************************************/
-//     //数据解析-Text
-//     pub fn message_text(text: String) -> Option<ResponseData> {
-//         let response_data = Self::ok_text(text);
-//         Option::from(response_data)
-//     }
-//     //数据解析-ping
-//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析-pong
-//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析
-//     pub fn ok_text(text: String) -> ResponseData
-//     {
-//         // trace!("原始数据:{}", text);
-//         // trace!("大小:{}", text.capacity());
-//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-//
-//         // {"event":"login","code":0}
-//         if json_value.get("event").is_some() && json_value["event"].as_str() == Option::from("login") {
-//             if json_value.get("code").is_some() && json_value["code"] == 0 {
-//                 res_data.message = format!("登录成功");
-//             } else {
-//                 res_data.message = format!("登录失败:({},{})", json_value.get("code").as_ref().unwrap(), json_value.get("msg").as_ref().unwrap());
-//             }
-//             res_data.channel = format!("login");
-//             res_data.code = "-200".to_string();
-//             res_data
-//         } else if json_value.get("event").is_some() && json_value["event"].as_str() == Option::from("subscribe") {
-//             // trace!("解析-订阅反馈:{}", text);
-//             res_data.code = "-201".to_string();
-//             res_data.data = text;
-//             res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-//             res_data
-//         } else if json_value.get("action").is_some() {
-//             // trace!("解析-推送数据:{}", text);
-//             res_data.data = json_value["data"].to_string();
-//             if res_data.data == "[]" {
-//                 res_data.code = "".to_string();
-//             } else {
-//                 res_data.code = "200".to_string();
-//             }
-//             res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-//             res_data.reach_time = json_value["ts"].as_i64().unwrap() * 1000;
-//             res_data
-//         } else {
-//             res_data
-//         }
-//     }
-// }

+ 0 - 394
exchanges/src/bitget_swap_rest.rs

@@ -1,394 +0,0 @@
-use std::collections::BTreeMap;
-use std::str::FromStr;
-use reqwest::Client;
-use reqwest::header::HeaderMap;
-use rust_decimal::Decimal;
-use tracing::info;
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-use ring::hmac;
-use rust_decimal::prelude::FromPrimitive;
-use serde_json::Value;
-
-#[derive(Clone, Debug)]
-pub struct BitgetSwapRest {
-    pub label: String,
-    base_url: String,
-    client: Client,
-    login_param: BTreeMap<String, String>,                  // 登录参数
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl BitgetSwapRest {
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSwapRest {
-        return BitgetSwapRest::new_label("default-BitgetSwapRest".to_string(), is_colo, login_param)
-    }
-
-    // 构造Bitget,可以自定义label
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BitgetSwapRest {
-        let base_url = if is_colo {
-            "https://api.bitget.com".to_string()
-        } else {
-            "https://api.bitget.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道", base_url);
-        } else {
-            info!("走普通通道:{}", base_url);
-        }
-
-        BitgetSwapRest {
-            label,
-            base_url,
-            client: Client::new(),
-            login_param,
-            delays: vec![],
-            max_delay: 0,
-            avg_delay: Decimal::ZERO,
-        }
-    }
-
-    //获取行情信息
-    pub async fn get_contracts(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol": symbol,
-            "productType": "USDT-FUTURES"
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/mix/market/contracts".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //获取行情信息
-    pub async fn get_tickers(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "symbol": symbol,
-            "productType": "USDT-FUTURES"
-         });
-        let data = self.request("GET".to_string(),
-                                "/api/v2".to_string(),
-                                "/mix/market/ticker".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    // 获取服务器时间
-    pub async fn get_server_time(&mut self) -> ResponseData {
-        let params = serde_json::json!({});
-        self.request("GET".to_string(),
-                     "/api/v2".to_string(),
-                     "/public/time".to_string(),
-                     false,
-                     params.to_string(),
-        ).await
-    }
-
-    // 获取账户信息
-    pub async fn get_account_info(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "productType": "USDT-FUTURES"
-        });
-
-        self.request("GET".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/account/accounts".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 获取仓位信息(单个)
-    pub async fn get_single_position(&mut self, params: Value) -> ResponseData {
-        self.request("GET".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/position/single-position".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 获取所有仓位
-    pub async fn get_all_position(&mut self, params: Value) -> ResponseData {
-        self.request("GET".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/position/all-position".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 下单
-    pub async fn swap_order(&mut self, params: Value) -> ResponseData {
-        self.request("POST".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/order/place-order".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 撤单
-    pub async fn cancel_order(&mut self, params: Value) -> ResponseData {
-        self.request("POST".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/order/cancel-order".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 获取订单详情
-    pub async fn get_order(&mut self, params: Value) -> ResponseData {
-        self.request("GET".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/order/detail".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 获取当前未成交订单
-    pub async fn get_pending_orders(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "productType": "USDT-FUTURES"
-        });
-
-        self.request("GET".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/order/orders-pending".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 调整杠杆
-    pub async fn set_leverage(&mut self, params: Value) -> ResponseData {
-        self.request("POST".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/account/set-leverage".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 调整持仓模式(单向、双向)
-    pub async fn set_position_mode(&mut self, params: Value) -> ResponseData {
-        self.request("POST".to_string(),
-                     "/api/v2".to_string(),
-                     "/mix/account/set-position-mode".to_string(),
-                     true,
-                     params.to_string(),
-        ).await
-    }
-
-    // 发送请求
-    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 passphrase = "".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") {
-            passphrase = self.login_param.get("pass_key").unwrap().to_string();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" || passphrase == "" {
-            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());
-        headers.insert("locale", "en-US".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(),
-                );
-                //组装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(
-            format!("{}{}", prefix_url.clone(), request_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 res_data_analysis(result: Result<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-        match result {
-            Ok(res_data) => {
-                if res_data.code != 200 {
-                    let json_value = res_data.data;
-                    let error = ResponseData::new("".to_string(),
-                                                  res_data.code,
-                                                  format!("请求地址:{}, 请求参数:{}, 响应结果:{}", base_url, params, res_data.message),
-                                                  json_value);
-                    error
-                } else {
-                    let json_value = res_data.data;
-
-
-                    let code = json_value["code"].as_str().unwrap();
-                    if code == "00000" {
-                        let data = serde_json::to_string(&json_value["data"]).unwrap();
-                        let success = ResponseData::new("".to_string(), 200, "success".to_string(), data.parse().unwrap());
-                        success
-                    } else {
-                        let code_num = i16::from_str(json_value["code"].as_str().unwrap()).unwrap();
-                        let error = ResponseData::new("".to_string(), code_num,
-                                                      format!("请求地址:{}, 请求参数:{}, 响应结果:{}", base_url, params, json_value.as_str().unwrap()),
-                                                      json_value);
-                        error
-                    }
-                }
-            }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
-                error
-            }
-        }
-    }
-
-    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 fn headers(sign: String, timestamp: String, passphrase: String, access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("ACCESS-KEY", access_key.parse().unwrap());
-        headers.insert("ACCESS-SIGN", sign.parse().unwrap());
-        headers.insert("ACCESS-TIMESTAMP", timestamp.parse().unwrap());
-        headers.insert("ACCESS-PASSPHRASE", passphrase.parse().unwrap());
-        headers
-    }
-
-
-    async fn http_tool(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-        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 params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-        // trace!("params_json:{}",params_json);
-        // trace!("headers:{:?}",headers);
-
-        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(&params),
-            _ => 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, "success".to_string(), body.parse().unwrap());
-        } else {
-            let body = response.text().await?;
-            res_data = ResponseData::error(self.label.clone(), body.to_string())
-        }
-
-        Ok(res_data)
-    }
-
-    // 对请求进行签名处理
-    pub fn sign(secret_key: String,
-            method: String, prefix_url: String, request_url: String,
-            params: String, body: String, timestamp: String) -> String {
-        let url_param_str = RestTool::parse_params_to_str(params);
-        let base_url = if method == "GET" && url_param_str.len() > 0 {
-            format!("{}{}?{}", prefix_url, request_url, url_param_str)
-        } else {
-            format!("{}{}", prefix_url, request_url)
-        };
-
-        // 时间戳 + 请求类型+ 请求参数字符串
-        let message = format!("{}{}{}{}", timestamp, method, base_url, body);
-        // trace!("message:{}",message);
-
-        // 做签名
-        let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-        let result = hmac::sign(&hmac_key, &message.as_bytes());
-        let sign = base64::encode(result);
-        sign
-    }
-}

+ 0 - 316
exchanges/src/bitget_swap_ws.rs

@@ -1,316 +0,0 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use chrono::{Utc};
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use serde_json::{json, Value};
-use tracing::{error, info, trace};
-use ring::hmac;
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-pub enum BitgetSwapWsType {
-    Public,
-    Private,
-}
-
-#[derive(Clone)]
-pub enum BitgetSwapSubscribeType {
-    PuTrade,
-    PuBooks1,
-
-    PrAccount,
-    PrPosition,
-    PrOrders,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BitgetSwapLogin {
-    pub api_key: String,
-    pub secret_key: String,
-    pub passphrase_key: String,
-}
-
-#[derive(Clone)]
-pub struct BitgetSwapWs {
-    label: String,                                              // 类型
-    address_url: String,                                        // 地址
-    login_param: Option<BitgetSwapLogin>,                       // 账号
-    symbol_s: Vec<String>,                                      // 币对
-    subscribe_types: Vec<BitgetSwapSubscribeType>,              // 订阅
-    heartbeat_time: u64,                                        // 心跳间隔
-}
-
-impl BitgetSwapWs {
-    pub fn new(is_colo: bool, login_param: Option<BitgetSwapLogin>, ws_type: BitgetSwapWsType) -> BitgetSwapWs {
-        return BitgetSwapWs::new_label("default-BitgetSwapWs".to_string(), is_colo, login_param, ws_type);
-    }
-
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<BitgetSwapLogin>, ws_type: BitgetSwapWsType) -> BitgetSwapWs {
-        let address_url = match ws_type {
-            BitgetSwapWsType::Public => {
-                "wss://ws.bitget.com/v2/ws/public".to_string()
-            }
-            BitgetSwapWsType::Private => {
-                "wss://ws.bitget.com/v2/ws/private".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        BitgetSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 10
-        }
-    }
-
-    // 添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<BitgetSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-
-    // 手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 小写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("-", "");
-            *symbol = symbol.replace("_", "");
-        }
-        self.symbol_s = b_array;
-    }
-
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                BitgetSwapSubscribeType::PuTrade => false,
-                BitgetSwapSubscribeType::PuBooks1 => false,
-
-                BitgetSwapSubscribeType::PrAccount => true,
-                BitgetSwapSubscribeType::PrOrders => true,
-                BitgetSwapSubscribeType::PrPosition => true
-            } {
-                return true;
-            }
-        }
-        false
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数*******************************************************/
-    /*******************************************************************************************************/
-    // 枚举解析成json
-    pub fn enum_to_json(symbol: String, subscribe_type: BitgetSwapSubscribeType) -> Value {
-        match subscribe_type {
-            // 公共订阅
-            BitgetSwapSubscribeType::PuTrade => {
-                json!({
-                    "instType": "USDT-FUTURES",
-                    "channel": "trade",
-                    "instId": symbol,
-                })
-            },
-            BitgetSwapSubscribeType::PuBooks1 => {
-                json!({
-                    "instType": "USDT-FUTURES",
-                    "channel": "books1",
-                    "instId": symbol,
-                })
-            },
-
-            // 私有订阅
-            BitgetSwapSubscribeType::PrAccount => {
-                json!({
-                    "instType": "USDT-FUTURES",
-                    "channel": "account",
-                    "coin": "default",
-                })
-            },
-            BitgetSwapSubscribeType::PrPosition => {
-                json!({
-                    "instType": "USDT-FUTURES",
-                    "channel": "positions",
-                    "instId": "default"
-                })
-            },
-            BitgetSwapSubscribeType::PrOrders => {
-                json!({
-                    "instType": "USDT-FUTURES",
-                    "channel": "orders",
-                    "instId": "default"
-                })
-            },
-        }
-    }
-
-    // 订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut params = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_json(symbol.clone(), subscribe_type.clone());
-                params.push(ty_str);
-            }
-        }
-        let str = json!({
-            "op": "subscribe",
-            "args": params
-        });
-
-        str.to_string()
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    pub async fn ws_connect_async<F, Future>(&mut self,
-                                            is_shutdown_arc: Arc<AtomicBool>,
-                                            handle_function: F,
-                                            write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                            write_to_socket_rx: UnboundedReceiver<Message>) -> Result<(), Error>
-        where
-            F: Fn(ResponseData) -> Future + Clone + Send + 'static + Sync,
-            Future: std::future::Future<Output=()> + Send + 'static, // 确保 Fut 是一个 Future,且输出类型为 ()
-    {
-        let login_is = self.contains_pr();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.heartbeat_time.clone();
-
-        // 设置订阅
-        let subscription = self.get_subscription();
-        let subscribe_array = vec![subscription.to_string()];
-        info!(?subscribe_array);
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            let ping_str = json!("ping");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Custom(ping_str.as_str().unwrap().to_string()), heartbeat_time).await;
-        });
-
-        //链接
-        let login_param = self.login_param.clone();
-        let write_tx_clone2 = Arc::clone(write_tx_am);
-        let t2 = tokio::spawn(async move {
-            let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
-
-            loop {
-                info!("bitget_usdt_swap socket 连接中……");
-
-                // 登录相关
-                if login_is {
-                    let login_param_c = login_param.clone().unwrap();
-                    let timestamp = Utc::now().timestamp().to_string();
-                    // 时间戳 + 请求类型+ 请求参数字符串
-                    let message = format!("{}GET{}", timestamp, "/user/verify");
-                    let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, login_param_c.secret_key.as_bytes());
-                    let result = hmac::sign(&hmac_key, &message.as_bytes());
-                    let sign = base64::encode(result);
-
-                    let login_json = json!({
-                        "op": "login",
-                        "args": [{
-                            "apiKey": login_param_c.api_key,
-                            "passphrase": login_param_c.passphrase_key,
-                            "timestamp": timestamp,
-                            "sign": sign
-                        }]
-                    });
-                    let login_str = login_json.to_string();
-                    info!("发起ws登录: {}", login_str);
-                    let write_tx_c = Arc::clone(&write_tx_clone2);
-                    AbstractWsMode::send_subscribe(write_tx_c, Message::Text(login_str)).await;
-                }
-
-                // ws层重连
-                AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
-                                                 login_is, label.clone(), subscribe_array.clone(), write_to_socket_rx_arc.clone(),
-                                                 Self::message_text, Self::message_ping, Self::message_pong, Self::message_binary).await;
-
-                error!("bitget_usdt_swap socket 断连,重连中……");
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************数据解析*******************************************************/
-    /******************************************************************************************************/
-    // 数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    // 数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -300, "success".to_string(), Value::Null));
-    }
-    // 数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -301, "success".to_string(), Value::Null));
-    }
-    //数据解析-二进制
-    pub fn message_binary(_po: Vec<u8>) -> Option<ResponseData> {
-        //二进制WebSocket消息
-        let message_str = format!("Binary:{:?}", _po);
-        Option::from(ResponseData::new("".to_string(), 2, message_str, Value::Null))
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData {
-        let mut res_data = ResponseData::new("".to_string(), 200, text.clone(), Value::Null);
-        match text.as_str() {
-            "pong" => {
-                res_data.code = -301;
-                res_data.channel = "pong".to_string();
-                res_data.message = "success".to_string();
-            },
-            _ => {
-                let json_value: Value = serde_json::from_str(&text).unwrap();
-
-                if json_value.get("event").is_some() && json_value["event"].as_str() == Some("login") {
-                    if json_value.get("code").is_some() && json_value["code"] == 0 {
-                        res_data.message = "登陆成功".to_string();
-                    } else {
-                        res_data.message = format!("登陆失败:({},{})", json_value.get("code").as_ref().unwrap(), json_value.get("msg").as_ref().unwrap());
-                    }
-                    res_data.channel = "login".to_string();
-                    res_data.code = -200;
-                    res_data.data = json_value;
-                } else if json_value.get("event").is_some() && json_value["event"].as_str() == Some("subscribe") {
-                    res_data.code = -201;
-                    res_data.data = json_value.clone();
-                    res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-                    res_data.message = "success".to_string();
-                } else if json_value.get("action").is_some() {
-                    res_data.data = json_value["data"].clone();
-                    if res_data.data == "[]" {
-                        res_data.code = -1;
-                    } else {
-                        res_data.code = 200;
-                    }
-                    res_data.message = "success".to_string();
-                    res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-                    res_data.reach_time = json_value["ts"].as_i64().unwrap() * 1000;
-                }
-            }
-        }
-
-        res_data
-    }
-}

+ 0 - 481
exchanges/src/bybit_swap_rest.rs

@@ -1,481 +0,0 @@
-use std::collections::BTreeMap;
-
-use reqwest::Client;
-use reqwest::header::HeaderMap;
-use ring::hmac;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use serde_json::Value;
-use tracing::{info, trace};
-
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-
-#[derive(Clone, Debug)]
-pub struct BybitSwapRest {
-    pub label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //登录所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl BybitSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> BybitSwapRest
-    {
-        return BybitSwapRest::new_label("default-BybitSwapRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> BybitSwapRest {
-        let base_url = if is_colo {
-            "https://api.bytick.com".to_string()
-        } else {
-            "https://api.bytick.com".to_string()
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",base_url);
-        } else {
-            info!("走普通通道:{}",base_url);
-        }
-        /*****返回结构体*******/
-        BybitSwapRest {
-            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(),
-                                "/v5".to_string(),
-                                "/market/time".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢最新行情信息
-    pub async fn get_tickers(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-               "category":"linear",
-                "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/market/tickers".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢市場價格K線數據
-    pub async fn get_kline(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-               "category":"linear",
-                "symbol":symbol,
-                "interval":"1",
-                "limit":"200"
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/market/kline".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢公告
-    pub async fn get_announcements(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "locale":"zh-TW"
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/announcements/index".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢可交易產品的規格信息
-    pub async fn get_instruments_info(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "category":"linear",
-            "symbol":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/market/instruments-info".to_string(),
-                                false,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //查看持仓信息
-    pub async fn get_positions(&mut self, symbol: String, settle_coin: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "category":"linear",
-         });
-        if symbol.len() > 0 {
-            params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
-        }
-        if settle_coin.len() > 0 {
-            params.as_object_mut().unwrap().insert("settleCoin".parse().unwrap(), serde_json::Value::from(settle_coin));
-        }
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/position/list".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //设置持仓模式
-    pub async fn set_position_mode(&mut self, symbol: String, mode: i64) -> ResponseData {
-        let params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-             "mode": mode,
-         });
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/position/switch-mode".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //設置槓桿
-    pub async fn set_leverage(&mut self, symbol: String,
-                              lever: String) -> ResponseData {
-        let params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-             "buyLeverage": lever,
-             "sellLeverage": lever,
-         });
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/position/set-leverage".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-
-    //查詢錢包餘額
-    pub async fn get_account_balance(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-            "accountType":"UNIFIED",
-            "coin":symbol
-         });
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/account/wallet-balance".to_string(),
-                                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(),
-                                "/v5".to_string(),
-                                "/order/create".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-    //查詢實時委託單
-    pub async fn get_order(&mut self, symbol: String, order_id: String, order_link_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-            "category":"linear",
-            "symbol":symbol,
-         });
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        if order_link_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderLinkId".parse().unwrap(), serde_json::Value::from(order_link_id));
-        }
-        let data = self.request("GET".to_string(),
-                                "/v5".to_string(),
-                                "/order/realtime".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //撤单
-    pub async fn cancel_order(&mut self, symbol: String, order_id: String, order_link_id: String) -> ResponseData {
-        let mut params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-         });
-        if order_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderId".parse().unwrap(), serde_json::Value::from(order_id));
-        }
-        if order_link_id.len() > 0 {
-            params.as_object_mut().unwrap().insert("orderLinkId".parse().unwrap(), serde_json::Value::from(order_link_id));
-        }
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/order/cancel".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-    //撤銷所有訂單
-    pub async fn cancel_orders(&mut self, symbol: String) -> ResponseData {
-        let params = serde_json::json!({
-             "category": "linear",
-             "symbol": symbol,
-         });
-        let data = self.request("POST".to_string(),
-                                "/v5".to_string(),
-                                "/order/cancel-all".to_string(),
-                                true,
-                                params.to_string(),
-        ).await;
-        data
-    }
-
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        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 passphrase = "".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") {
-        //     passphrase = self.login_param.get("pass_key").unwrap().to_string();
-        // }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" {
-            is_login_param = false
-        }
-
-
-        //请求头配置-如果需要登录则存在额外配置
-        let mut body = "".to_string();
-        let timestamp = Self::get_timestamp();
-        let mut headers = HeaderMap::new();
-        headers.insert("Content-Type", "application/json; charset=utf-8".parse().unwrap());
-        headers.insert("X-BAPI-RECV-WINDOW", "5000".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(
-                    access_key.clone(),
-                    secret_key.clone(),
-                    method.clone(),
-                    params.clone(),
-                    timestamp.clone(),
-                );
-                //组装header
-                headers.extend(Self::headers(sing, timestamp, access_key));
-            }
-        }
-
-
-        // trace!("headers:{:?}", headers);
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let response_data = self.http_tool(
-            format!("{}{}", prefix_url.clone(), request_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();
-
-        response_data
-    }
-
-    pub fn headers(sign: String, timestamp: String, access_key: String) -> HeaderMap {
-        let mut headers = HeaderMap::new();
-        headers.insert("X-BAPI-SIGN-TYPE", "2".parse().unwrap());
-        headers.insert("X-BAPI-API-KEY", access_key.parse().unwrap());
-        headers.insert("X-BAPI-TIMESTAMP", timestamp.parse().unwrap());
-        headers.insert("X-BAPI-SIGN", sign.parse().unwrap());
-        // headers.insert("X-Referer", passphrase.parse().unwrap());
-        headers
-    }
-    pub fn sign(access_key: String,
-                secret_key: String,
-                method: String,
-                params: String, timestamp: String) -> String
-    {
-        /*签名生成*/
-        let url_param_str = RestTool::parse_params_to_str(params.clone());
-        let parameters = if method == "GET" {
-            url_param_str
-        } else {
-            params
-        };
-
-        let message = format!("{}{}5000{}", timestamp, access_key, parameters);
-        trace!("message:{}",message);
-
-        // 做签名
-        let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-        let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-        let sign = hex::encode(result.as_ref());
-        sign
-    }
-
-    async fn http_tool(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> 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()))
-        };
-
-        let request_builder = match request_type.as_str() {
-            "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(url.clone()).body(params.clone()).headers(headers),
-            "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => {
-                panic!("{}", format!("错误的请求类型:{}", request_type.clone()))
-            }
-        };
-
-        let response = request_builder.send().await.unwrap();
-        return if response.status().is_success() {
-            // 读取响应的内容
-            let body = response.text().await.unwrap();
-
-            self.on_success_data(&body, &addrs_url, &params)
-        } else {
-            let body = response.text().await.unwrap();
-
-            ResponseData::error(self.label.clone(), body)
-        }
-    }
-
-    pub fn on_success_data(&mut self, text: &String, base_url: &String, params: &String) -> ResponseData {
-        let json_value: Value = serde_json::from_str(text.as_str()).unwrap();
-
-        let code: i64 = if json_value["retCode"].as_i64().is_some() {
-            json_value["retCode"].as_i64().unwrap()
-        } else if json_value["ret_code"].as_i64().is_some() {
-            json_value["ret_code"].as_i64().unwrap()
-        } else {
-            -1
-        };
-
-        if code == 0 {
-            let data = serde_json::to_string(&json_value["result"]).unwrap();
-            let mut success = ResponseData::new("".to_string(), 200, "success".to_string(), data.parse().unwrap());
-            success.time = json_value["time"].as_i64().unwrap();
-            success
-        } else {
-            let msg: &str = if json_value["retMsg"].as_str().is_some() {
-                json_value["retMsg"].as_str().unwrap()
-            } else if json_value["ret_msg"].as_str().is_some() {
-                json_value["ret_msg"].as_str().unwrap()
-            } else {
-                ""
-            };
-
-            let error = ResponseData::new("".to_string(),
-                                          code as i16,
-                                          format!("请求地址:{}, 请求参数:{}, 消息原文:{}。", base_url, params, msg),
-                                          Value::Null);
-            error
-        }
-    }
-
-    fn get_timestamp() -> String {
-        chrono::Utc::now().timestamp_millis()
-            .to_string()
-    }
-}

+ 0 - 353
exchanges/src/bybit_swap_ws.rs

@@ -1,353 +0,0 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::Duration;
-
-use chrono::Utc;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use serde_json::{json, Value};
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{error, info, trace};
-
-use ring::hmac;
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum BybitSwapWsType {
-    Public,
-    Private,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum BybitSwapSubscribeType {
-    PuOrderBook1,
-    PuOrderBook50,
-    PuBlicTrade,
-    PuTickers,
-    PuKline(String),
-
-    PrPosition,
-    PrExecution,
-    PrOrder,
-    PrWallet,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BybitSwapLogin {
-    pub api_key: String,
-    pub secret_key: String,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BybitSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号
-    login_param: Option<BybitSwapLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<BybitSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl BybitSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<BybitSwapLogin>, ws_type: BybitSwapWsType) -> BybitSwapWs {
-        return BybitSwapWs::new_label("default-BybitSwapWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<BybitSwapLogin>, ws_type: BybitSwapWsType) -> BybitSwapWs {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            BybitSwapWsType::Public => {
-                "wss://stream.bybit.com/v5/public/linear?max_alive_time=1m".to_string()
-            }
-            BybitSwapWsType::Private => {
-                "wss://stream.bybit.com/v5/private?max_alive_time=1m".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        BybitSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 10,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<BybitSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "");
-            *symbol = symbol.replace("-", "");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                BybitSwapSubscribeType::PuOrderBook1 => false,
-                BybitSwapSubscribeType::PuOrderBook50 => false,
-                BybitSwapSubscribeType::PuBlicTrade => false,
-                BybitSwapSubscribeType::PuTickers => false,
-                BybitSwapSubscribeType::PuKline(_) => false,
-
-                BybitSwapSubscribeType::PrPosition => true,
-                BybitSwapSubscribeType::PrExecution => true,
-                BybitSwapSubscribeType::PrOrder => true,
-                BybitSwapSubscribeType::PrWallet => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: BybitSwapSubscribeType) -> String {
-        match subscribe_type {
-            BybitSwapSubscribeType::PuOrderBook1 => {
-                format!("orderbook.1.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuOrderBook50 => {
-                format!("orderbook.50.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuBlicTrade => {
-                format!("publicTrade.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuTickers => {
-                format!("tickers.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuKline(t) => {
-                format!("kline.{}.{}", t, symbol)
-            }
-
-            BybitSwapSubscribeType::PrPosition => {
-                format!("position")
-            }
-            BybitSwapSubscribeType::PrExecution => {
-                format!("execution")
-            }
-            BybitSwapSubscribeType::PrOrder => {
-                format!("order")
-            }
-            BybitSwapSubscribeType::PrWallet => {
-                format!("wallet")
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut params = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                params.push(ty_str);
-            }
-        }
-
-        let str = json!({
-                "op": "subscribe",
-                "args": params
-            });
-        str.to_string()
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async<F, Future>(&mut self,
-                                             is_shutdown_arc: Arc<AtomicBool>,
-                                             handle_function: F,
-                                             write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                             write_to_socket_rx: UnboundedReceiver<Message>) -> Result<(), Error>
-        where
-            F: Fn(ResponseData) -> Future + Clone + Send + 'static + Sync,
-            Future: std::future::Future<Output=()> + Send + 'static, // 确保 Fut 是一个 Future,且输出类型为 ()
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let login_param = self.login_param.clone();
-        let (api_key, secret_key) = match login_param {
-            None => { ("".to_string(), "".to_string()) }
-            Some(p) => {
-                (p.api_key.clone().to_string(), p.secret_key.clone().to_string())
-            }
-        };
-        let heartbeat_time = self.heartbeat_time.clone();
-        trace!("{:?}",format!("{}",subscription));
-
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
-
-            loop {
-                info!("bybit_usdt_swap socket 连接中……");
-
-                //设置订阅
-                let mut subscribe_array = vec![];
-                if login_is {
-                    let timestamp = Utc::now().timestamp_millis();
-                    let expires = timestamp + 1000;
-                    let message = format!("GET/realtime{}", expires);
-
-                    let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-                    let result = hmac::sign(&hmac_key, &message.as_bytes());
-                    let signature = hex::encode(result.as_ref());
-
-                    //登录相关
-                    let str = json!({
-                        "op": "auth",
-                        "args": [api_key, expires, signature]
-                    });
-                    subscribe_array.push(str.to_string());
-                }
-                subscribe_array.push(subscription.to_string());
-
-                // ws网络层重连
-                AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
-                                                 false, label.clone(), subscribe_array, write_to_socket_rx_arc.clone(),
-                                                 Self::message_text, Self::message_ping, Self::message_pong, Self::message_binary).await;
-
-                error!("bybit_usdt_swap socket 断连,1s以后重连……");
-                tokio::time::sleep(Duration::from_secs(1)).await;
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -300, "success".to_string(), Value::Null));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -301, "success".to_string(), Value::Null));
-    }
-    //数据解析-二进制
-    pub fn message_binary(_po: Vec<u8>) -> Option<ResponseData> {
-        //二进制WebSocket消息
-        let message_str = format!("Binary:{:?}", _po);
-        Option::from(ResponseData::new("".to_string(), 2, message_str, Value::Null))
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData {
-        // trace!("原始数据");
-        // trace!(?text);
-        let mut res_data = ResponseData::new("".to_string(), 200, "success".to_string(), Value::Null);
-        let json_value: Value = serde_json::from_str(&text).unwrap();
-        if json_value.get("success").is_some() {
-            info!("bybit_swap_ws订阅结果:{:?}", json_value);
-            //订阅内容
-            let success = json_value["success"].as_bool().unwrap();
-            // let ret_msg = json_value["ret_msg"].as_str().unwrap();
-            let op = json_value["op"].as_str().unwrap();
-            let success_error = if success {
-                "成功"
-            } else {
-                "失败"
-            };
-
-            if op == "auth" {
-                res_data.code = -200;
-                res_data.message = format!("登录{}", success_error);
-            } else if op == "subscribe" {
-                res_data.message = format!("订阅{}", success_error);
-                res_data.code = -201;
-            } else {
-                res_data.code = -1;
-                res_data.channel = "未知订阅".to_string();
-            }
-        } else if json_value.get("topic").is_some() && json_value.get("data").is_some() {
-            let channel = json_value["topic"].to_string();
-            res_data.data = json_value["data"].clone();
-
-            res_data.code = 200;
-
-            if channel.contains("orderbook") {
-                res_data.channel = "orderbook".to_string();
-                res_data.data_type = json_value["type"].as_str().unwrap().to_string();
-                // bybit 时间在data块外
-                res_data.reach_time = json_value.get("ts").unwrap().as_i64().unwrap_or(0i64);
-            } else if channel.contains("publicTrade") {
-                res_data.channel = "trade".to_string();
-                res_data.data_type = json_value["type"].as_str().unwrap().to_string();
-            } else if channel.contains("tickers") {
-                res_data.channel = "tickers".to_string();
-                res_data.data["ts"] = json_value["ts"].clone();
-            } else if channel.contains("kline") {
-                res_data.channel = "kline".to_string();
-            } else if channel.contains("position") {
-                res_data.channel = "position".to_string();
-            } else if channel.contains("execution") {
-                res_data.channel = "execution".to_string();
-            } else if channel.contains("order") {
-                res_data.channel = "order".to_string();
-            } else if channel.contains("wallet") {
-                res_data.channel = "wallet".to_string();
-            } else {
-                res_data.code = -1;
-                res_data.channel = "未知的频道".to_string();
-            }
-        } else {
-            //推送数据
-            res_data.code = -1;
-            res_data.channel = "未知的频道".to_string();
-        }
-
-        res_data
-    }
-}

+ 0 - 696
exchanges/src/coinex_swap_rest.rs

@@ -1,696 +0,0 @@
-use std::collections::BTreeMap;
-use std::error::Error;
-use std::time::{SystemTime, UNIX_EPOCH};
-use reqwest::header::{HeaderMap, HeaderValue};
-use hex;
-use reqwest::Client;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use serde_json::Value;
-use crate::http_tool::RestTool;
-use crate::response_base::ResponseData;
-use sha2::{Digest, Sha256};
-use tracing::{error};
-
-#[derive(Clone)]
-pub struct CoinexSwapRest {
-    label: String,
-    base_url: String,
-    client: Client,
-    /*******参数*/
-    //登陆所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl CoinexSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(login_param: BTreeMap<String, String>) -> CoinexSwapRest
-    {
-        return CoinexSwapRest::new_label("default-CoinexSwapRest".to_string(), login_param);
-    }
-    pub fn new_label(label: String, login_param: BTreeMap<String, String>) -> CoinexSwapRest
-    {
-        let base_url: String = String::from("https://api.coinex.com");
-
-        /*****返回结构体*******/
-        CoinexSwapRest {
-            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 data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/time".to_string(),
-                                false,
-                                None,
-                                None,
-        ).await;
-        data
-    }
-    //查询个人交易费率
-    pub async fn wallet_fee(&mut self) -> ResponseData {
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/account/trade-fee-rate".to_string(),
-                                true,
-                                None,
-                                None,
-        ).await;
-        data
-    }
-    //查询合约账户
-    pub async fn get_account(&mut self) -> ResponseData {
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/assets/futures/balance".to_string(),
-                                true,
-                                None,
-                                None,
-        ).await;
-        data
-    }
-
-    //查询现货账户
-    pub async fn get_spot_account(&mut self) -> ResponseData {
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/assets/spot/balance".to_string(),
-                                true,
-                                None,
-                                None,
-        ).await;
-        data
-    }
-
-    //指定币对仓位列表
-    pub async fn get_position(&mut self, market: String) -> ResponseData {
-        let params = serde_json::json!({
-            "market": market,
-            "market_type": "FUTURES"
-        });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/pending-position".to_string(),
-                                true,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-
-    //用户仓位列表
-    pub async fn get_user_position(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "market_type": "FUTURES"
-        });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/pending-position".to_string(),
-                                true,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-
-    //获取所有合约交易行情统计 market 市场名列表,多个市场名之间使用英文","分隔,空字符串或不传表示查询全部市场,限制最多10个市场
-    pub async fn get_ticker(&mut self, market: String) -> ResponseData {
-        let params = serde_json::json!({
-            "market": market
-         });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/ticker".to_string(),
-                                false,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-    //查询所有的合约信息
-    pub async fn get_market_details(&mut self, market: String) -> ResponseData {
-        let params = serde_json::json!({
-            "market": market
-         });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/market".to_string(),
-                                false,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-    //查询单个订单详情  /spot/order-status?market=CETUSDT&order_id=13400
-    pub async fn get_order_details(&mut self, order_id: String, market: String) -> ResponseData {
-        let params = serde_json::json!({
-            "market": market,
-            "order_id": order_id
-         });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/order-status".to_string(),
-                                true,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-    //查询未完成合约订单 /futures/pending-order?market=CETUSDT&market_type=FUTURES&side=buy&page=1&limit=10
-    pub async fn get_pending_order(&mut self, client_id: String) -> ResponseData {
-        let params = serde_json::json!({
-            "market_type": "FUTURES",
-            "client_id": client_id,
-            "limit": 10
-         });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/pending-order".to_string(),
-                                true,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-
-    pub async fn get_pending_orders(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "market_type": "FUTURES",
-            "limit": 100
-         });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/pending-order".to_string(),
-                                true,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-
-    pub async fn get_finished_orders(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "market_type": "FUTURES",
-            "limit": 100
-         });
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/finished-order".to_string(),
-                                true,
-                                Some(params.to_string()),
-                                None,
-        ).await;
-        data
-    }
-
-    //下单
-    //  coinex swap 平仓需考虑最小下单量 只能通过close_position和position_id来平仓
-    pub async fn order(&mut self,
-                       market: String,
-                       pos_side: String,
-                       side: String,
-                       size: Decimal,
-                       price: Decimal,
-                       client_id: String,
-    ) -> ResponseData
-    {
-        // 默认为限价单
-        let mut type_y = "limit".to_string();
-        // 0为市价单,
-        if price == Decimal::ZERO {
-            type_y = "market".to_string();
-        }
-        let data;
-
-
-        match format!("{}_{}", pos_side, side).as_str() {
-            "long_buy" => {//开多
-                data = self.swap_order(market, side, type_y, size, price, client_id, false).await;
-            }
-            "long_sell" => {//平多
-                data = self.close_position(market, type_y, price, client_id, false).await;
-            }
-            "short_buy" => {//平空
-                data = self.close_position(market, type_y, price, client_id, false).await;
-            }
-            "short_sell" => {//开空
-                data = self.swap_order(market, side, type_y, size, price, client_id, false).await;
-            }
-            _ => {
-                // 处理未知请求类型
-                error!("下单失败,数量异常! size: {}", size);
-                data = ResponseData::error(self.label.clone(), format!("下单失败, 下单参数: <market: {:?}, pos_side: {:?}, side: {:?}, size: {}, price: {:?}, client_id: {:?}>", market, pos_side, side, size, price, client_id));
-            }
-        };
-        data
-    }
-
-    // 平仓下单
-    pub async fn close_position(&mut self, market: String, type_y: String, price: Decimal, client_id: String, is_hide: bool) -> ResponseData {
-        // 数量不传为全平
-        let param = serde_json::json!({
-            "market":market,
-            "market_type": "FUTURES",
-            "type": type_y,
-            "price":price,
-            "client_id":client_id,
-            "is_hide": is_hide
-        });
-
-        let data = self.request("POST".to_string(),
-                                "/v2".to_string(),
-                                "/futures/close-position".to_string(),
-                                true,
-                                None,
-                                Some(param.to_string()),
-        ).await;
-        data
-    }
-
-    //合约交易开仓下单
-    pub async fn swap_order(&mut self, market: String, side: String, type_y: String, amount: Decimal, price: Decimal, client_id: String, is_hide: bool) -> ResponseData {
-        let param = serde_json::json!({
-            "market":market,
-            "market_type": "FUTURES",
-            "side": side,
-            "type": type_y,
-            "amount":amount,
-            "price":price,
-            "client_id":client_id,
-            "is_hide": is_hide
-        });
-
-        let data = self.request("POST".to_string(),
-                                "/v2".to_string(),
-                                "/futures/order".to_string(),
-                                true,
-                                None,
-                                Some(param.to_string()),
-        ).await;
-        data
-    }
-
-    //设置持仓模式
-    pub async fn setting_dual_mode(&mut self) -> ResponseData {
-        ResponseData::error(self.label.clone(), "设置双向持仓失败, coinex没有设置双向持仓".to_string())
-    }
-    //更新双仓模式下的杠杆
-    pub async fn setting_dual_leverage(&mut self, market: String, leverage: i32) -> ResponseData {
-        let params = serde_json::json!({
-                "market": market,
-                "market_type": "FUTURES",
-                // cross: 全仓。全仓模式下,合约账户的全部可用余额都可用作当前全部仓位的共享保证金,系统会使用合约账户中的可用余额自动追加保证金,以避免仓位被强平
-                //isolated: 逐仓。逐仓模式下,仓位保证金不会共享,单个仓位的保证金仅用于当前仓位,系统不会自动追加保证金,需要手动追加。
-                "margin_mode": "cross",
-                "leverage":leverage,
-             });
-        let data = self.request("POST".to_string(),
-                                "/v2".to_string(),
-                                "/futures/adjust-position-leverage".to_string(),
-                                true,
-                                None,
-                                Some(params.to_string()),
-        ).await;
-        data
-    }
-
-    //撤销单个订单
-    pub async fn cancel_order(&mut self, market: String, order_id: &str, client_id: &str) -> ResponseData {
-        if order_id != "" {  // 如果真实订单id不为空,则用真实订单id取消订单
-            let id = order_id.parse::<i64>().unwrap();
-            let params = serde_json::json!({
-                "market": market,
-                "market_type": "FUTURES",
-                "order_id": id
-            });
-            let data = self.request("POST".to_string(),
-                                    "/v2".to_string(),
-                                    "/futures/cancel-order".to_string(),
-                                    true,
-                                    None,
-                                    Some(params.to_string()),
-            ).await;
-            data
-        } else if client_id != "" {  // 如果客户端id不为空,则用客户端id取消订单
-            let params = serde_json::json!({
-                "market": market,
-                "market_type": "FUTURES",
-                "client_id": client_id
-            });
-
-            let mut data = self.request("POST".to_string(),
-                                        "/v2".to_string(),
-                                        "/futures/cancel-order-by-client-id".to_string(),
-                                        true,
-                                        None,
-                                        Some(params.to_string()),
-            ).await;
-            // 非空的
-            if data.code == 200 && !data.data.is_null() {
-                data.data = data.data.as_array().unwrap()[0]["data"].clone();
-            }
-            data
-        } else {
-            // 否则返回错误
-            error!("取消订单失败失败,id异常");
-            ResponseData::error(self.label.clone(), format!("取消订单失败失败, orderId:{:?}, clientId: {:?} ", order_id, client_id))
-        }
-    }
-
-    // 撤销所有挂单
-    pub async fn cancel_order_all(&mut self, market: String) -> ResponseData {
-        let params = serde_json::json!({
-            "market": market,
-            "market_type": "FUTURES"
-        });
-        let data = self.request("POST".to_string(),
-                                "/v2".to_string(),
-                                "/futures/cancel-all-order".to_string(),
-                                true,
-                                None,
-                                Some(params.to_string()),
-        ).await;
-        data
-    }
-
-    //查询个人成交记录
-    pub async fn my_trades(&mut self, market: String, limit: i64) -> ResponseData {
-        let mut params = serde_json::json!({
-            "market": market,
-            "market_type": "FUTURES",
-            "limit": 1000
-        });
-        if limit > 0 {
-            params["limit"] = serde_json::json!(limit);
-        }
-
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/futures/user-deals".to_string(),
-                                true,
-                                Some(params.to_string()), None).await;
-        data
-    }
-
-    //查询合约账户变更历史
-    pub async fn account_book(&mut self) -> ResponseData {
-        error!("查询合约账户变更历史失败,无实现");
-        ResponseData::error(self.label.clone(), "查询合约账户变更历史失败,接口没实现".to_string())
-    }
-
-
-    //查询子账号列表
-    pub async fn account_get(&mut self) -> ResponseData {
-        let params = serde_json::json!({
-            "is_frozen":false,
-            "page":1,
-            "limit":100,
-        });
-
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/account/subs".to_string(),
-                                true,
-                                Some(params.to_string()), None).await;
-        data
-    }
-
-
-    //根据子账号,生成子账号 APIKEY
-    pub async fn account_subs_api(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/v2".to_string(),
-                                "/account/subs/api".to_string(),
-                                true,
-                                None,
-                                Some(params.to_string())).await;
-        data
-    }
-
-    //获取子账号 APIKEY 列表
-    pub async fn account_get_apikey(&mut self, params: Value) -> ResponseData {
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/account/subs/api".to_string(),
-                                true,
-                                Some(params.to_string()), None).await;
-        data
-    }
-
-    //获取子账号 APIKEY 详情
-    pub async fn account_get_detail(&mut self, params: Value) -> ResponseData {
-        let data = self.request("GET".to_string(),
-                                "/v2".to_string(),
-                                "/account/subs/api-detail".to_string(),
-                                true,
-                                Some(params.to_string()), None).await;
-        data
-    }
-
-    //编辑子账号 APIKEY
-    pub async fn account_get_update(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/v2".to_string(),
-                                "/account/subs/edit-api".to_string(),
-                                true,
-                                None,  Some(params.to_string())).await;
-        data
-    }
-
-    //删除子账号 APIKEY
-    pub async fn account_del_apikey(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/v2".to_string(),
-                                "/account/subs/delete-api".to_string(),
-                                true,
-                                None,
-                                Some(params.to_string())).await;
-        data
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        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();
-    // }
-
-    //调用请求
-    async fn request(&mut self,
-                     request_type: String,
-                     prefix_url: String,
-                     request_url: String,
-                     is_login: bool,
-                     params: Option<String>,
-                     body: Option<String>) -> ResponseData
-    {
-        // trace!("login_param:{:?}", self.login_param);
-        //解析账号信息
-        let mut access_key = "".to_string();
-        let mut secret_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();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" {
-            is_login_param = false
-        }
-
-        let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis().to_string();
-        // url
-        let mut url_and_query = format!("{}{}", prefix_url.clone(), request_url.clone());
-        let mut headers = HeaderMap::new();
-        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
-        headers.insert(
-            "X-COINEX-KEY",
-            HeaderValue::from_str(&self.login_param.get("access_key").unwrap()).unwrap(),
-        );
-        headers.insert(
-            "X-COINEX-TIMESTAMP",
-            HeaderValue::from_str(&timestamp).unwrap(),
-        );
-
-        if let Some(params) = params {
-            let query = RestTool::parse_params_to_str(params);
-            url_and_query = format!("{}?{}", url_and_query, query);
-        }
-        let body_s = if let Some(body) = body {
-            body
-        } else {
-            "".to_string()
-        };
-
-        //是否需要登陆-- 组装sing
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登陆参数错误!".to_string());
-                return e;
-            } else {//需要登陆-且登陆参数齐全
-                //组装sing
-                let sing = Self::sign(
-                    &request_type,
-                    &url_and_query,
-                    &body_s,
-                    timestamp.clone(),
-                    &secret_key,
-                );
-                // trace!("sing:{}", sing);
-                //组装header
-                headers.insert("X-COINEX-SIGN", HeaderValue::from_str(&sing.unwrap()).unwrap());
-            }
-        }
-
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let response = self.http_toll(
-            url_and_query,
-            request_type,
-            body_s.clone(),
-            headers,
-        ).await;
-
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        // self.get_delay_info();
-
-        response
-    }
-    fn sign(
-        method: &String,
-        path: &String,
-        body: &String,
-        timestamp: String,
-        secret_key: &String,
-    ) -> Result<String, Box<dyn Error>> {
-        let prepared_str = format!(
-            "{}{}{}{}{}",
-            method, path, body, timestamp, secret_key
-        );
-        let hash = Sha256::digest(prepared_str.as_bytes());
-        Ok(hex::encode(hash))
-    }
-
-    async fn http_toll(&mut self, request_path: String, request_type: String, body: String, headers: HeaderMap) -> ResponseData {
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-
-
-        let request_builder = match request_type.as_str() {
-            "GET" => self.client.get(&url).headers(headers),
-            "POST" => self.client.post(&url).body(body.clone()).headers(headers),
-            "DELETE" => self.client.delete(&url).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => {
-                panic!("{}", format!("错误的请求类型:{}", request_type.clone()))
-            }
-        };
-
-        // 读取响应的内容
-        let res = request_builder.send().await;
-        match res {
-            Ok(response) => {
-                let is_success = response.status().is_success(); // 先检查状态码
-                let text_result = response.text().await;
-                match text_result {
-                    Ok(text) => {
-                        let data_json_str: Result<Value, serde_json::Error> = serde_json::from_str(text.as_str());
-                        match data_json_str {
-                            Ok(data_json) => {
-                                return if is_success && data_json["code"].to_string() == "0" {
-                                    self.on_success_data(data_json["data"].clone())
-                                } else {
-                                    self.on_error_data(&text, &url, &body)
-                                }
-                            }
-                            Err(e) => {
-                                error!("{} 请求完成,解析响应内容JSON失败 {} {}", url, text.as_str(), e);
-                                self.on_error_data(&e.to_string(), &url, &body)
-                            }
-                        }
-                    }
-                    Err(e) => {
-                        error!("{} 请求完成,解析响应内容失败 {}", url, e);
-                        self.on_error_data(&e.to_string(), &url, &body)
-                    }
-                }
-            }
-            Err(e) => {
-                // 异常情况
-                error!("{} 请求失败,网络错误 {}", url, e);
-                self.on_error_data(&e.to_string(), &url, &body)
-            }
-        }
-    }
-
-    pub fn on_success_data(&mut self, text: Value) -> ResponseData {
-        ResponseData::new(self.label.clone(),
-                          200,
-                          "success".to_string(),
-                          text)
-    }
-
-    pub fn on_error_data(&mut self, text: &String, base_url: &String, params: &String) -> ResponseData {
-        let json_value = serde_json::from_str::<Value>(&text);
-
-        match json_value {
-            Ok(data) => {
-                let message;
-                if !data["message"].is_null() {
-                    message = format!("{}:{}", data["code"].to_string(), data["message"].as_str().unwrap());
-                } else {
-                    message = data["code"].to_string();
-                }
-                let mut error = ResponseData::error(self.label.clone(), message);
-                error.message = format!("请求地址:{}, 请求参数:{}, 报错内容:{}。", base_url, params, error.message);
-                error
-            }
-            Err(e) => {
-                error!("解析错误:{:?}", e);
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", e, text));
-                error
-            }
-        }
-    }
-}

+ 0 - 414
exchanges/src/coinex_swap_ws.rs

@@ -1,414 +0,0 @@
-use std::io::Read;
-use std::str::from_utf8;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::{Duration, SystemTime, UNIX_EPOCH};
-
-use flate2::bufread::GzDecoder;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-
-use once_cell::sync::Lazy;  // 使用线程安全的版本
-use hex::encode;
-use serde_json::{json, Value};
-use sha2::{Digest, Sha256};
-use tokio::sync::Mutex;
-use tokio::task;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{error, info, trace};
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-// struct LoginData {
-//     pub is_need_login: bool,
-//     pub is_login: bool
-// }
-
-pub(crate) static LOGIN_DATA: Lazy<Mutex<(bool, bool)>> = Lazy::new(|| {
-    println!("初始化...");
-    // 0: 需要登录, 1:是否已经登录
-    Mutex::new((false, false))
-});
-
-//订阅频道
-#[derive(Clone)]
-pub enum CoinexSwapSubscribeType {
-    // 深度
-    PuFuturesDepth,
-    // 公开成交
-    PuFuturesDeals,
-
-    // 订单
-    PrFuturesOrders,
-    // 仓位
-    PrFuturesPositions,
-    // 余额
-    PrFuturesBalances,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct CoinexSwapLogin {
-    pub api_key: String,
-    pub secret: String,
-}
-
-#[derive(Clone)]
-pub struct CoinexSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号信息
-    login_param: Option<CoinexSwapLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<CoinexSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64
-}
-
-
-impl CoinexSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************实例化一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(login_param: Option<CoinexSwapLogin>) -> CoinexSwapWs {
-        return CoinexSwapWs::new_label("default-CoinexSwapWs".to_string(), login_param);
-    }
-
-    pub fn new_label(label: String, login_param: Option<CoinexSwapLogin>) -> CoinexSwapWs
-    {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = "wss://socket.coinex.com/v2/futures".to_string();
-        info!("走普通通道(不支持colo通道):{}", address_url);
-        CoinexSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 10
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<CoinexSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("-", "_");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                CoinexSwapSubscribeType::PuFuturesDepth => false,
-                CoinexSwapSubscribeType::PuFuturesDeals => false,
-
-                CoinexSwapSubscribeType::PrFuturesOrders => true,
-                CoinexSwapSubscribeType::PrFuturesPositions => true,
-                CoinexSwapSubscribeType::PrFuturesBalances => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: CoinexSwapSubscribeType, _login_param: Option<CoinexSwapLogin>) -> Value {
-        // let access_key;
-        // let secret_key;
-        // match login_param {
-        //     None => {
-        //         access_key = "".to_string();
-        //         secret_key = "".to_string();
-        //     }
-        //     Some(param) => {
-        //         access_key = param.api_key.clone();
-        //         secret_key = param.secret.clone();
-        //     }
-        // }
-
-        match subscribe_type {
-            CoinexSwapSubscribeType::PuFuturesDepth => {
-                json!({
-                    "method": "depth.subscribe",
-                    "params": {
-                        "market_list": [
-                            [symbol, 50, "0.000000001", true]
-                        ]
-                    },
-                    "id": 1
-                })
-            }
-            CoinexSwapSubscribeType::PuFuturesDeals => {
-                json!({
-                    "method": "deals.subscribe",
-                    "params": {"market_list": [symbol]},
-                    "id": 1
-                })
-            }
-
-            CoinexSwapSubscribeType::PrFuturesOrders => {
-                json!({
-                  "method": "order.subscribe",
-                  "params": {"market_list": [symbol]},
-                  "id": 1
-                })
-            }
-            CoinexSwapSubscribeType::PrFuturesPositions => {
-                json!({
-                  "method": "position.subscribe",
-                  "params": {"market_list": [symbol]},
-                  "id": 1
-                })
-            }
-            CoinexSwapSubscribeType::PrFuturesBalances => {
-                json!({
-                    "method": "balance.subscribe",
-                    "params": {"ccy_list": ["USDT"]}, // 目前只用u 所以写死
-                    "id": 1
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> Vec<Value> {
-        let mut args = vec![];
-        // 只获取第一个
-        let symbol = self.symbol_s.get(0).unwrap().replace("_", "").to_uppercase();
-
-        for subscribe_type in &self.subscribe_types {
-            let ty_str = Self::enum_to_string(symbol.clone(),
-                                              subscribe_type.clone(),
-                                              self.login_param.clone(),
-            );
-            args.push(ty_str);
-        }
-        args
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async<F, Future>(&mut self,
-                                             is_shutdown_arc: Arc<AtomicBool>,
-                                             handle_function: F,
-                                             write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                             write_to_socket_rx: UnboundedReceiver<Message>) -> Result<(), Error>
-        where
-            F: Fn(ResponseData) -> Future + Clone + Send + 'static + Sync,
-            Future: std::future::Future<Output=()> + Send + 'static, // 确保 Fut 是一个 Future,且输出类型为 ()
-    {
-        let login_is = self.contains_pr();
-        let login_param_clone = self.login_param.clone();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.heartbeat_time.clone();
-
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = Arc::clone(write_tx_am);
-        let write_tx_clone2 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            let ping_str = json!({
-                "method": "server.ping",
-                "params": {},
-                "id": 1
-            });
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Custom(ping_str.to_string()), heartbeat_time).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-
-
-        for s in subscription {
-            subscribe_array.push(s.to_string());
-        }
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
-
-            info!("启动连接");
-            loop {
-                info!("coinex_usdt_swap socket 连接中……");
-                // 需要登录
-                if login_is {
-                    let login_param = login_param_clone.clone().unwrap();
-                    let mut login_data = LOGIN_DATA.lock().await;
-                    login_data.0 = true;
-                    let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
-                    //登录相关
-                    let prepared_str = format!("{}{}", time, login_param.secret);
-                    // 创建SHA256哈希器实例
-                    let mut hasher = Sha256::new();
-                    // 加密字符串
-                    hasher.update(prepared_str);
-                    // 计算哈希值
-                    let result = hasher.finalize();
-                    // 将哈希值转换为十六进制小写字符串
-                    let hex_str = encode(result).to_lowercase();
-
-                    let login_param = json!({
-                        "method": "server.sign",
-                        "params": {
-                            "access_id": login_param.api_key,
-                            "signed_str": hex_str,
-                            "timestamp": time
-                        },
-                        "id": 1
-                    });
-                    let login_str = login_param.to_string();
-                    info!("发起ws登录: {}", login_str);
-                    let write_tx_c = Arc::clone(&write_tx_clone2);
-                    AbstractWsMode::send_subscribe(write_tx_c, Message::Text(login_str)).await;
-                } else {
-                    info!("coinex 不需登录");
-                }
-
-                AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
-                                                 login_is, label.clone(), subscribe_array.clone(), write_to_socket_rx_arc.clone(),
-                                                 Self::message_text_sync, Self::message_ping, Self::message_pong, Self::message_binary_sync).await;
-                let mut login_data = LOGIN_DATA.lock().await;
-                // 断联后 设置为没有登录
-                login_data.1 = false;
-                info!("coinex_usdt_swap socket 断连,1s以后重连……");
-                error!("coinex_usdt_swap socket 断连,1s以后重连……");
-                tokio::time::sleep(Duration::from_secs(1)).await;
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub async fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text).await;
-        Option::from(response_data)
-    }
-    pub fn message_text_sync(text: String) -> Option<ResponseData> {
-        // 使用 tokio::task::block_in_place 来等待异步函数的结果
-        task::block_in_place(|| {
-            tokio::runtime::Handle::current().block_on(Self::message_text(text))
-        })
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -300, "success".to_string(), Value::Null));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -301, "success".to_string(), Value::Null));
-    }
-    //数据解析-二进制
-    pub async fn message_binary(binary: Vec<u8>) -> Option<ResponseData> {
-        //二进制WebSocket消息
-        let message_str = Self::parse_zip_data(binary);
-        let response_data = Self::ok_text(message_str).await;
-        Option::from(response_data)
-    }
-    pub fn message_binary_sync(binary: Vec<u8>) -> Option<ResponseData> {
-        // 使用 tokio::task::block_in_place 来等待异步函数的结果
-        task::block_in_place(|| {
-            tokio::runtime::Handle::current().block_on(Self::message_binary(binary))
-        })
-    }
-    //数据解析
-    pub async fn ok_text(text: String) -> ResponseData
-    {
-        // trace!("原始数据:{}", text);
-        let mut res_data = ResponseData::new("".to_string(), 200, "success".to_string(), Value::Null);
-        let json_value: Value = serde_json::from_str(&text).unwrap();
-
-        let obj = json_value["method"].as_str();
-        match obj {
-            Some(v)=> {
-                res_data.channel = format!("{}", v);
-                res_data.code = 200;
-                res_data.data = json_value["data"].clone();
-            },
-            None => {
-                // 认证的响应没有method,只能通过id和code判断
-                match json_value["id"].as_i64() {
-                    Some(1) => {
-                        match json_value["code"].as_i64() {
-                            Some(0) =>{
-                                match json_value["data"].as_str() {
-                                    None => {
-                                        // 登录成功逻辑处理
-                                        let mut login_data = LOGIN_DATA.lock().await;
-                                        if login_data.0 { // 需要登录
-                                            if !login_data.1{
-                                                login_data.1 = true;
-                                                res_data.channel = "server.sign".to_string();
-                                                res_data.code = -200;
-                                            }else {
-                                                res_data.code = 400;
-                                            }
-                                        }  else { // 不需要登录
-                                            res_data.code = 200;
-                                        }
-                                    }
-                                    _ =>{
-                                        res_data.code = 400;
-                                    }
-                                }
-                            }
-                            _ => {
-                                res_data.code = 400;
-                            }
-                        }
-                    }
-                    _ => {
-                        res_data.code = 400;
-                    }
-                }
-                res_data.data = json_value;
-            }
-        }
-        res_data
-    }
-
-    fn parse_zip_data(p0: Vec<u8>) -> String{
-        // 创建一个GzDecoder的实例,将压缩数据作为输入
-        let mut decoder = GzDecoder::new(&p0[..]);
-
-        // 创建一个缓冲区来存放解压缩后的数据
-        let mut decompressed_data = Vec::new();
-
-        // 读取解压缩的数据到缓冲区中
-        decoder.read_to_end(&mut decompressed_data).expect("解压缩失败");
-        let result = from_utf8(&decompressed_data)
-            .expect("解压缩后的数据不是有效的UTF-8");
-
-        // info!("解压缩数据 {:?}", result);
-        result.to_string()
-    }
-}
-

+ 0 - 285
exchanges/src/crypto_spot_ws.rs

@@ -1,285 +0,0 @@
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-//
-// use chrono::Utc;
-// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-// use serde_json::json;
-// use tokio::sync::Mutex;
-// use tokio_tungstenite::tungstenite::{Error, Message};
-// use tracing::{info, trace};
-//
-// use crate::response_base::ResponseData;
-// use crate::socket_tool::AbstractWsMode;
-//
-// //类型
-// pub enum CryptoSpotWsType {
-//     Public,
-//     Private,
-// }
-//
-// //订阅频道
-// #[derive(Clone)]
-// pub enum CryptoSpotSubscribeType {
-//     PuBook,
-//     PuTicker,
-//     PuTrade,
-//     PuCandlestick,
-// }
-//
-// //账号信息
-// #[derive(Clone)]
-// #[allow(dead_code)]
-// pub struct CryptoSpotLogin {
-//     pub api_key: String,
-//     pub api_secret: String,
-// }
-//
-// #[derive(Clone)]
-// #[allow(dead_code)]
-// pub struct CryptoSpotWs {
-//     //类型
-//     label: String,
-//     //地址
-//     address_url: String,
-//     //账号
-//     login_param: Option<CryptoSpotLogin>,
-//     //币对
-//     symbol_s: Vec<String>,
-//     //订阅
-//     subscribe_types: Vec<CryptoSpotSubscribeType>,
-//     //心跳间隔
-//     heartbeat_time: u64,
-// }
-//
-// impl CryptoSpotWs {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//     pub fn new(is_colo: bool, login_param: Option<CryptoSpotLogin>, ws_type: CryptoSpotWsType) -> CryptoSpotWs {
-//         return CryptoSpotWs::new_label("default-CryptoSpotWs".to_string(), is_colo, login_param, ws_type);
-//     }
-//     pub fn new_label(label: String, is_colo: bool, login_param: Option<CryptoSpotLogin>, ws_type: CryptoSpotWsType) -> CryptoSpotWs {
-//         /*******公共频道-私有频道数据组装*/
-//         let address_url = match ws_type {
-//             CryptoSpotWsType::Public => {
-//                 "wss://stream.crypto.com/exchange/v1/market".to_string()
-//             }
-//             CryptoSpotWsType::Private => {
-//                 "wss://stream.crypto.com/exchange/v1/user".to_string()
-//             }
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",address_url);
-//         } else {
-//             info!("走普通通道:{}",address_url);
-//         }
-//
-//         CryptoSpotWs {
-//             label,
-//             address_url,
-//             login_param,
-//             symbol_s: vec![],
-//             subscribe_types: vec![],
-//             heartbeat_time: 1000 * 3,
-//         }
-//     }
-//
-//     /*******************************************************************************************************/
-//     /*****************************************订阅函数********************************************************/
-//     /*******************************************************************************************************/
-//     //手动添加订阅信息
-//     pub fn set_subscribe(&mut self, subscribe_types: Vec<CryptoSpotSubscribeType>) {
-//         self.subscribe_types.extend(subscribe_types);
-//     }
-//     //手动添加币对
-//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-//         for symbol in b_array.iter_mut() {
-//             // 大写
-//             *symbol = symbol.to_uppercase();
-//             // 字符串替换
-//             *symbol = symbol.replace("_", "");
-//             *symbol = symbol.replace("-", "");
-//         }
-//         self.symbol_s = b_array;
-//     }
-//     //频道是否需要登录
-//     fn contains_pr(&self) -> bool {
-//         for t in self.subscribe_types.clone() {
-//             if match t {
-//                 CryptoSpotSubscribeType::PuBook => false,
-//                 CryptoSpotSubscribeType::PuTicker => false,
-//                 CryptoSpotSubscribeType::PuTrade => false,
-//                 CryptoSpotSubscribeType::PuCandlestick => false,
-//             } {
-//                 return true;
-//             }
-//         }
-//         false
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************工具函数********************************************************/
-//     /*******************************************************************************************************/
-//     //订阅枚举解析
-//     pub fn enum_to_string(symbol: String, subscribe_type: CryptoSpotSubscribeType) -> String {
-//         match subscribe_type {
-//             CryptoSpotSubscribeType::PuBook => {
-//                 format!("book.{}-PERP", symbol)
-//             }
-//             CryptoSpotSubscribeType::PuTicker => {
-//                 format!("ticker.{}-PERP", symbol)
-//             }
-//             CryptoSpotSubscribeType::PuTrade => {
-//                 format!("trade.{}-PERP", symbol)
-//             }
-//             CryptoSpotSubscribeType::PuCandlestick => {
-//                 format!("candlestick.M1.{}-PERP", symbol)
-//             }
-//         }
-//     }
-//     //订阅信息生成
-//     pub fn get_subscription(&self) -> String {
-//         let mut params = vec![];
-//         for symbol in &self.symbol_s {
-//             for subscribe_type in &self.subscribe_types {
-//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-//                 params.push(ty_str);
-//             }
-//         }
-//
-//         let nonce = Utc::now().timestamp_millis();
-//         let str = json!({
-//                   "id": 1,
-//                   "method": "subscribe",
-//                   "params": {
-//                     "channels":params
-//                   },
-//                   "nonce": nonce
-//                 });
-//
-//         if params.len() > 0 {
-//             str.to_string()
-//         } else {
-//             "".to_string()
-//         }
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************socket基本*****************************************************/
-//     /*******************************************************************************************************/
-//     //链接
-//     pub async fn ws_connect_async(&mut self,
-//                                   is_shutdown_arc: Arc<AtomicBool>,
-//                                   _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-//                                   write_rx: UnboundedReceiver<Message>,
-//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-//     {
-//         let login_is = self.contains_pr();
-//         let subscription = self.get_subscription();
-//         let address_url = self.address_url.clone();
-//         let label = self.label.clone();
-//         // let heartbeat_time = self.heartbeat_time.clone();
-//
-//
-//         //心跳-- 方法内部线程启动
-//         // let write_tx_clone1 = Arc::clone(write_tx_am);
-//         // tokio::spawn(async move {
-//         //     trace!("线程-异步心跳-开始");
-//         //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Pong, heartbeat_time).await;
-//         //     trace!("线程-异步心跳-结束");
-//         // });
-//
-//         //设置订阅
-//         let mut subscribe_array = vec![];
-//         if login_is {
-//             //登录相关
-//         }
-//         subscribe_array.push(subscription.to_string());
-//
-//         //链接
-//         let t2 = tokio::spawn(async move {
-//             trace!("线程-异步链接-开始");
-//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
-//                                                    label.clone(), subscribe_array,
-//                                                    write_rx, read_tx,
-//                                                    Self::message_text,
-//                                                    Self::message_ping,
-//                                                    Self::message_pong,
-//             ).await {
-//                 Ok(_) => { trace!("线程-异步链接-结束"); }
-//                 Err(e) => { trace!("发生异常:crypt-期货链接关闭-{:?}",e); }
-//             }
-//         });
-//         tokio::try_join!(t2).unwrap();
-//         trace!("线程-心跳与链接-结束");
-//
-//         Ok(())
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************数据解析*****************************************************/
-//     /*******************************************************************************************************/
-//     //数据解析-Text
-//     pub fn message_text(text: String) -> Option<ResponseData> {
-//         let response_data = Self::ok_text(text);
-//         Option::from(response_data)
-//     }
-//     //数据解析-ping
-//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析-pong
-//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析
-//     pub fn ok_text(text: String) -> ResponseData {
-//         // trace!("原始数据");
-//         // trace!(?text);
-//
-//         let mut res_data = ResponseData::new("".to_string(), "".to_string(), "success".to_string(), "".to_string());
-//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-//
-//         if json_value.get("id").is_some() && json_value.get("method").is_some() && json_value.get("code").is_some() {
-//             let id = json_value["id"].as_i64().unwrap();
-//             let method = json_value["method"].as_str().unwrap();
-//             let code = json_value["code"].as_i64().unwrap();
-//
-//             if method == "public/heartbeat" {
-//                 if code == 0 {
-//                     res_data.code = "-302".to_string();
-//                     let str = json!({
-//                   "id": id,
-//                   "method": "public/respond-heartbeat"
-//                 });
-//                     res_data.message = "服务器主动心跳检测,客户端回应~!".to_string();
-//                     res_data.data = str.to_string();
-//                 } else {
-//                     res_data.message = "心跳异常~!".to_string();
-//                 }
-//             } else if method == "subscribe" && json_value.get("channel").is_some() {
-//                 //订阅反馈
-//                 if code == 0 {
-//                     res_data.code = "-201".to_string();
-//                     res_data.channel = json_value["channel"].as_str().unwrap().to_string();
-//                 } else {
-//                     res_data.message = "订阅失败~!".to_string();
-//                     res_data.data = json_value["data"].to_string()
-//                 }
-//             } else if method == "subscribe" && json_value.get("result").is_some() {
-//                 if code == 0 {
-//                     let subscription = json_value["result"]["subscription"].as_str().unwrap();
-//                     res_data.channel = subscription.to_string();
-//                     res_data.code = "200".to_string();
-//                     res_data.data = json_value["result"]["data"].to_string()
-//                 } else {
-//                     res_data.message = "推送数据异常~!".to_string();
-//                     res_data.data = json_value["result"]["data"].to_string()
-//                 }
-//             } else {
-//                 res_data.message = "未知解析!!".to_string();
-//             }
-//         } else {
-//             res_data.message = "错误解析!!".to_string();
-//         }
-//         res_data
-//     }
-// }

+ 0 - 15
exchanges/src/gate_spot_rest.rs

@@ -1,15 +0,0 @@
-use std::collections::BTreeMap;
-
-#[derive(Clone)]
-pub struct GateSpotRest {}
-
-impl GateSpotRest {
-    pub fn new(_is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotRest
-    {
-        return GateSpotRest::new_label("default-GateSpotRest".to_string(), _is_colo, _login_param);
-    }
-    pub fn new_label(_label: String, _is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotRest
-    {
-        GateSpotRest {}
-    }
-}

+ 0 - 15
exchanges/src/gate_spot_ws.rs

@@ -1,15 +0,0 @@
-// use std::collections::BTreeMap;
-//
-// #[derive(Clone)]
-// pub struct GateSpotWs {}
-//
-// impl GateSpotWs {
-//     pub fn new(_is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotWs
-//     {
-//         return GateSpotWs::new_label("default-GateSpotWs".to_string(), _is_colo, _login_param);
-//     }
-//     pub fn new_label(_label: String, _is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotWs
-//     {
-//         GateSpotWs {}
-//     }
-// }

+ 0 - 508
exchanges/src/htx_swap_rest.rs

@@ -1,508 +0,0 @@
-use std::collections::BTreeMap;
-
-use chrono::Utc;
-use percent_encoding::{AsciiSet, CONTROLS, utf8_percent_encode};
-use reqwest::Client;
-use reqwest::header::HeaderMap;
-use ring::hmac;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use serde_json::Value;
-use tracing::{error, info, trace};
-
-use crate::response_base::ResponseData;
-
-// 定义用于 URL 编码的字符集
-pub const FRAGMENT: &AsciiSet = &CONTROLS
-    .add(b' ')
-    .add(b':')
-    .add(b'=')
-    .add(b'+')
-    .add(b'/').add(b'?').add(b'#')
-    .add(b'[').add(b']').add(b'@').add(b'!').add(b'$').add(b'&')
-    .add(b'\'').add(b'(').add(b')').add(b'*').add(b',')
-    .add(b';').add(b'"').add(b'%')
-;
-
-
-#[derive(Clone)]
-pub struct HtxSwapRest {
-    label: String,
-    base_url: String,
-    client: reqwest::Client,
-    /*******参数*/
-    //登录所需参数
-    login_param: BTreeMap<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl HtxSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> HtxSwapRest
-    {
-        return HtxSwapRest::new_label("default-HtxSwapRest".to_string(), is_colo, login_param);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> HtxSwapRest
-    {
-        let base_url: String = String::from("https://api.hbdm.vn");
-        info!("走普通通道:{}",base_url);
-
-        if is_colo {} else {}
-        /*****返回结构体*******/
-        HtxSwapRest {
-            label,
-            base_url: base_url.to_string(),
-            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(),
-                                format!("/timestamp"),
-                                false,
-                                params,
-        ).await;
-        data
-    }
-
-
-    //行情 (【通用】获取聚合行情)
-    pub async fn get_ticker(&mut self, params: Value) -> ResponseData {
-        let data = self.request("GET".to_string(),
-                                "/linear-swap-ex/market".to_string(),
-                                format!("/detail/merged"),
-                                false,
-                                params,
-        ).await;
-        data
-    }
-
-    //合约信息 (【通用】获取合约信息)
-    pub async fn get_market(&mut self, params: Value) -> ResponseData {
-        let data = self.request("GET".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_contract_info"),
-                                false,
-                                params,
-        ).await;
-        data
-    }
-
-    //查询合约账户 (【全仓】获取用户账户信息)
-    pub async fn get_account(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_account_info"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-    //用户仓位列表(【全仓】获取用户持仓信息)
-    pub async fn get_user_position(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_position_info"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-    //查询合约订单列表 (【全仓】获取合约订单信息)
-    pub async fn get_orders(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_order_info"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-
-    //查询单个订单详情 (【全仓】获取订单明细信息)
-    pub async fn get_order_details(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_order_info"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-    //合约交易下单 (【全仓】合约下单)
-    pub async fn swap_order(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_order"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-    // 全部撤单(【全仓】全部撤单)
-    pub async fn cancel_price_order(&mut self, params: Value) -> ResponseData {
-        self.request("POST".to_string(),
-                     "/linear-swap-api/v1".to_string(),
-                     format!("/swap_cross_cancelall"),
-                     true,
-                     params,
-        ).await
-    }
-
-    //撤销单个订单 (【全仓】撤销订单)
-    pub async fn cancel_order(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_cancel"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-    //设置持仓模式 (【全仓】切换持仓模式)
-    pub async fn setting_dual_mode(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_switch_position_mode"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-    //设置杠杆(【全仓】切换杠杆)
-    pub async fn setting_dual_leverage(&mut self, params: Value) -> ResponseData {
-        let data = self.request("POST".to_string(),
-                                "/linear-swap-api/v1".to_string(),
-                                format!("/swap_cross_switch_lever_rate"),
-                                true,
-                                params,
-        ).await;
-        data
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    pub fn get_delays(&self) -> Vec<i64> {
-        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();
-    }
-    //调用请求
-    async fn request(&mut self,
-                     requesst_type: String,
-                     prefix_url: String,
-                     request_url: String,
-                     is_login: bool,
-                     params: Value) -> ResponseData
-    {
-        // trace!("login_param:{:?}", self.login_param);
-        //解析账号信息
-        let mut access_key = "".to_string();
-        let mut secret_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();
-        }
-        let mut is_login_param = true;
-        if access_key == "" || secret_key == "" {
-            is_login_param = false
-        }
-
-        //请求头配置-如果需要登录则存在额外配置
-        let mut body = "".to_string();
-
-        let mut headers = HeaderMap::new();
-        if requesst_type == "GET" {
-            headers.insert("Content-type", "application/x-www-form-urlencoded".parse().unwrap());
-            headers.insert("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ".parse().unwrap());
-        } else {
-            headers.insert("Accept", "application/json".parse().unwrap());
-            headers.insert("Content-Type", "application/json".parse().unwrap());
-        }
-
-        let utc_now = Utc::now();
-        let timestamp = utc_now.format("%Y-%m-%dT%H:%M:%S").to_string();
-        let mut params_str = "".to_string();
-        //是否需要登录-- 组装sing
-        let mut sing = "".to_string();
-        if is_login {
-            if !is_login_param {
-                let e = ResponseData::error(self.label.clone(), "登录参数错误!".to_string());
-                return e;
-            } else {//需要登录-且登录参数齐全
-                let mut login_param = serde_json::json!({});
-                login_param["AccessKeyId"] = Value::from(access_key);
-                login_param["SignatureMethod"] = Value::from("HmacSHA256");
-                login_param["SignatureVersion"] = Value::from("2");
-                login_param["Timestamp"] = Value::from(timestamp);
-
-                //如果是get 所有参所也要参与校验,如果是post 只有校验参数需要校验
-                let mut verify_param = serde_json::json!({});
-                if requesst_type == "GET" {
-                    merge_json(&mut verify_param, &params);
-                    merge_json(&mut verify_param, &login_param);
-                    body = "{}".to_string();
-                } else if requesst_type == "POST" {
-                    merge_json(&mut verify_param, &login_param);
-                    body = params.to_string();
-                }
-                trace!("需要校验参数:\n{}", verify_param.to_string());
-
-
-                //4. ASCII码的顺序对参数名进行排序
-                let verify_param_str = json_to_query_string(verify_param);
-                trace!("排序后的拼接参数:\n{}", verify_param_str);
-                params_str = verify_param_str.to_string().clone();
-
-                //组装sing
-                sing = Self::sign(secret_key.clone(),
-                                  requesst_type.clone(),
-                                  prefix_url.clone(),
-                                  request_url.clone(),
-                                  verify_param_str.clone(),
-                );
-                // sing = utf8_percent_encode(sing.as_str(), FRAGMENT).to_string();
-                // sing = sing.to_uppercase();
-                sing = utf8_percent_encode(&sing, FRAGMENT).to_string();
-                trace!("sing:{}", sing);
-                // ?AccessKeyId=e2xxxxxx-99xxxxxx-84xxxxxx-7xxxx&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2017-05-11T15%3A19%3A30&Signature=    4F65x5A2bLyMWVQj3Aqp%2BB4w%2BivaA7n5Oi2SuYtCJ9o%3D
-                // ?AccessKeyId=58edb6bb-qz5c4v5b6n-24498508-c5919&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2024-04-29T07%3A26%3A39&Signature=  R0SAEWSEC+A6HS5URSHZIFOZBYQBRCLH0DTDSAL0HLS=
-                //                                                                                                                                             4F65x5A2bLyMWVQj3Aqp+B4w+ivaA7n5Oi2SuYtCJ9o=
-            }
-        } else {
-            if requesst_type == "GET" {
-                let verify_param_str = json_to_query_string(params);
-                params_str = verify_param_str.to_string().clone();
-                body = "{}".to_string();
-            } else if requesst_type == "POST" {
-                body = params.to_string();
-            }
-        }
-
-        // trace!("headers:{:?}", headers);
-        let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
-        let start_time = chrono::Utc::now().timestamp_millis();
-        let response = self.http_tool(
-            base_url.clone(),
-            requesst_type.to_string(),
-            params_str,
-            body.clone(),
-            sing.clone(),
-            headers,
-        ).await;
-
-        let time_array = chrono::Utc::now().timestamp_millis() - start_time;
-        self.delays.push(time_array);
-        self.get_delay_info();
-
-        response
-    }
-
-    // pub fn headers(access_key: String, timestamp: String, sign: String) -> HeaderMap {
-    //     let mut headers = HeaderMap::new();
-    //     // headers.insert("KEY", access_key.clone().parse().unwrap());
-    //     // headers.insert("Timestamp", timestamp.clone().parse().unwrap());
-    //     // headers.insert("SIGN", sign.clone().parse().unwrap());
-    //     headers
-    // }
-    pub fn sign(secret_key: String, requesst_type: String,
-                prefix_url: String, request_url: String,
-                verify_param: String) -> String
-    {
-        let message = format!("{}\napi.hbdm.vn\n{}{}\n{}",
-                              requesst_type,
-                              prefix_url, request_url,
-                              verify_param
-        );
-        // trace!("**********", );
-        trace!("组装数据:\n{}", message);
-        // trace!("**********", );
-
-        let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-        let result = hmac::sign(&hmac_key, &message.as_bytes());
-        let sign = base64::encode(result);
-        sign
-    }
-
-
-    async fn http_tool(&mut self, request_path: String,
-                       request_type: String,
-                       params: String,
-                       body: String,
-                       sing: String, headers: HeaderMap) -> ResponseData {
-        /****请求接口与 地址*/
-        let url = format!("{}{}", self.base_url.to_string(), request_path);
-        let request_type = request_type.clone().to_uppercase();
-        let params_str = if sing.len() > 0 {
-            format!("{}&Signature={}", params.clone(), sing)
-        } else {
-            format!("{}", params.clone())
-        };
-        let addrs_url = if params_str.len() > 0 {
-            format!("{}?{}", url.clone(), params_str)
-        } else {
-            format!("{}", url.clone())
-        };
-
-        trace!("url-----:???{}",url.clone());
-        trace!("addrs_url-----:???{}",addrs_url.clone());
-        trace!("param-----:???{}",params.clone());
-        trace!("param_str-----:???{}",params_str.clone());
-        trace!("body-----:???{}",body.clone());
-
-        let request_builder = match request_type.as_str() {
-            "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(addrs_url.clone()).body(body).headers(headers),
-            // "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
-            // "PUT" => self.client.put(url.clone()).json(&params),
-            _ => {
-                panic!("{}", format!("错误的请求类型:{}", request_type.clone()))
-            }
-        };
-
-        // 读取响应的内容
-        let response = request_builder.send().await.unwrap();
-        let is_success = response.status().is_success(); // 先检查状态码
-        let text = response.text().await.unwrap();
-        // trace!("text:???{:?}",text);
-        return if is_success {
-            self.on_success_data(&text)
-        } else {
-            self.on_error_data(&text, &addrs_url, &params)
-        };
-    }
-
-    pub fn on_success_data(&mut self, text: &String) -> ResponseData {
-        let json_value = serde_json::from_str::<Value>(&text).unwrap();
-        // return  ResponseData::new(self.label.clone(), 200, "success".to_string(), json_value);
-
-        let status = json_value["status"].as_str().unwrap();
-        match status {
-            "ok" => {
-                //判断是否有code ,没有表示特殊接口,直接返回
-                if json_value.get("data").is_some() {
-                    let data = json_value.get("data").unwrap();
-                    ResponseData::new(self.label.clone(), 200, "success".to_string(), data.clone())
-                } else {
-                    ResponseData::new(self.label.clone(), 200, "success".to_string(), json_value)
-                }
-            }
-            _ => {
-                ResponseData::new(self.label.clone(), 400, "error".to_string(), json_value)
-            }
-        }
-    }
-
-    pub fn on_error_data(&mut self, text: &String, base_url: &String, params: &String) -> ResponseData {
-        let json_value = serde_json::from_str::<Value>(&text);
-
-        match json_value {
-            Ok(data) => {
-                let message;
-
-                if !data["message"].is_null() {
-                    message = format!("{}:{}", data["label"].as_str().unwrap(), data["message"].as_str().unwrap());
-                } else {
-                    message = data["label"].to_string();
-                }
-
-                let mut error = ResponseData::error(self.label.clone(), message);
-                error.message = format!("请求地址:{}, 请求参数:{}, 报错内容:{}。", base_url, params, error.message);
-                error
-            }
-            Err(e) => {
-                error!("解析错误:{:?}", e);
-                let error = ResponseData::error("".to_string(),
-                                                format!("json 解析失败:{},相关参数:{}", e, text));
-                error
-            }
-        }
-    }
-}
-
-
-// 合并两个 JSON 对象的函数
-fn merge_json(a: &mut Value, b: &Value) {
-    match (a, b) {
-        (Value::Object(ref mut a_map), Value::Object(b_map)) => {
-            for (k, v) in b_map {
-                merge_json(a_map.entry(k.clone()).or_insert(Value::Null), v);
-            }
-        }
-        (a, b) => {
-            *a = b.clone();
-        }
-    }
-}
-
-
-// 函数:将 JSON 对象转换为排序后的查询字符串
-fn json_to_query_string(value: Value) -> String {
-    let mut params = BTreeMap::new();
-
-    if let Value::Object(obj) = value {
-        for (k, v) in obj {
-            // 确保只处理字符串值
-            if let Value::String(v_str) = v {
-                params.insert(k, v_str);
-            } else {
-                // 对于非字符串值,我们可以转换为字符串或执行其他处理
-                params.insert(k, v.to_string());
-            }
-        }
-    }
-
-    // 拼接键值对为查询字符串
-    params.iter()
-        .map(|(k, v)| format!("{}={}", utf8_percent_encode(k, FRAGMENT), utf8_percent_encode(v, FRAGMENT)))
-        .collect::<Vec<String>>()
-        .join("&")
-}

+ 0 - 467
exchanges/src/htx_swap_ws.rs

@@ -1,467 +0,0 @@
-use std::io::Read;
-use std::str::from_utf8;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::Duration;
-
-use chrono::Utc;
-use flate2::bufread::GzDecoder;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use once_cell::sync::Lazy;
-use ring::hmac;
-use serde_json::{json, Value};
-use tokio::sync::Mutex;
-use tokio::task;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{error, info, trace};
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::AbstractWsMode;
-
-pub(crate) static LOGIN_DATA: Lazy<Mutex<(bool, bool)>> = Lazy::new(|| {
-    println!("初始化...");
-    // 0: 需要登录, 1:是否已经登录
-    Mutex::new((false, false))
-});
-
-
-pub enum HtxSwapWsType {
-    Public,
-    Private,
-}
-
-
-//订阅频道
-#[derive(Clone)]
-pub enum HtxSwapSubscribeType {
-    // 深度
-    PuFuturesDepth,
-    // // 公开成交
-    // PuFuturesDeals,
-
-    // 订单
-    PrFuturesOrders,
-    // 仓位
-    PrFuturesPositions,
-    // 余额
-    PrFuturesBalances,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct HtxSwapLogin {
-    pub api_key: String,
-    pub secret: String,
-}
-
-#[derive(Clone)]
-pub struct HtxSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号信息
-    login_param: Option<HtxSwapLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<HtxSwapSubscribeType>,
-    //心跳间隔
-    _heartbeat_time: u64,
-}
-
-
-impl HtxSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************实例化一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(login_param: Option<HtxSwapLogin>, ws_type: HtxSwapWsType) -> HtxSwapWs {
-        return HtxSwapWs::new_label("default-HtxSwapWs".to_string(), login_param, ws_type);
-    }
-
-    pub fn new_label(label: String, login_param: Option<HtxSwapLogin>, ws_type: HtxSwapWsType) -> HtxSwapWs
-    {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            HtxSwapWsType::Public => {
-                let url = "wss://api.hbdm.vn/linear-swap-ws".to_string();
-                info!("走普通通道(不支持colo通道):{}", url);
-                url
-            }
-            HtxSwapWsType::Private => {
-                let url = "wss://api.hbdm.vn/linear-swap-notification".to_string();
-                info!("走普通通道(不支持colo通道):{}", url);
-                url
-            }
-        };
-
-        HtxSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            _heartbeat_time: 1000 * 10,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<HtxSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "-");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                HtxSwapSubscribeType::PuFuturesDepth => false,
-                // HtxSwapSubscribeType::PuFuturesDeals => false,
-                //
-                HtxSwapSubscribeType::PrFuturesOrders => true,
-                HtxSwapSubscribeType::PrFuturesPositions => true,
-                HtxSwapSubscribeType::PrFuturesBalances => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: HtxSwapSubscribeType, _login_param: Option<HtxSwapLogin>) -> Value {
-        // let access_key;
-        // let secret_key;
-        // match login_param {
-        //     None => {
-        //         access_key = "".to_string();
-        //         secret_key = "".to_string();
-        //     }
-        //     Some(param) => {
-        //         access_key = param.api_key.clone();
-        //         secret_key = param.secret.clone();
-        //     }
-        // }
-        // let cid = "";
-
-        match subscribe_type {
-            HtxSwapSubscribeType::PuFuturesDepth => {
-                json!({
-                      "sub":format!("market.{}.depth.step0", symbol.to_uppercase()),
-                      "id": "id5"
-                })
-            }
-
-            HtxSwapSubscribeType::PrFuturesOrders => {
-                json!({
-                        "op":"sub",
-                        "topic":format!("orders_cross.{}", symbol.to_lowercase())
-                })
-            }
-            HtxSwapSubscribeType::PrFuturesPositions => {
-                json!({
-                        "op":"sub",
-                        "topic":format!("positions_cross.{}", symbol.to_uppercase())
-                })
-            }
-            HtxSwapSubscribeType::PrFuturesBalances => {
-                json!({
-                        "op":"sub",
-                        "topic":format!("accounts_cross.USDT")
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> Vec<Value> {
-        let mut args = vec![];
-        // 只获取第一个
-        // let symbol = self.symbol_s.get(0).unwrap().replace("_", "-");
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(),
-                                                  subscribe_type.clone(),
-                                                  self.login_param.clone(),
-                );
-                args.push(ty_str);
-            }
-        }
-        args
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async<F, Future>(&mut self,
-                                             is_shutdown_arc: Arc<AtomicBool>,
-                                             handle_function: F,
-                                             write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                             write_to_socket_rx: UnboundedReceiver<Message>) -> Result<(), Error>
-        where
-            F: Fn(ResponseData) -> Future + Clone + Send + 'static + Sync,
-            Future: std::future::Future<Output=()> + Send + 'static, // 确保 Fut 是一个 Future,且输出类型为 ()
-    {
-        let login_is = self.contains_pr();
-        let login_param = self.login_param.clone();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        // let heartbeat_time = self.heartbeat_time.clone();
-
-
-        //心跳-- 方法内部线程启动
-        // let write_tx_clone1 = Arc::clone(write_tx_am);
-        let write_tx_clone2 = Arc::clone(write_tx_am);
-        // tokio::spawn(async move {
-        //     trace!("线程-异步心跳-开始");
-        //     let ping_str = json!({
-        //         "method": "server.ping",
-        //         "params": {},
-        //         "id": 1
-        //     });
-        //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Custom(ping_str.to_string()), heartbeat_time).await;
-        //     trace!("线程-异步心跳-结束");
-        // });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-
-
-        for s in subscription {
-            subscribe_array.push(s.to_string());
-        }
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
-
-            info!("启动连接");
-            loop {
-                info!("htx_usdt_swap socket 连接中……");
-                // 需要登录
-                if login_is {
-                    let mut login_data = LOGIN_DATA.lock().await;
-                    let login_param_real = login_param.clone().unwrap();
-                    login_data.0 = true;
-                    let utc_now = Utc::now();
-                    let timestamp = utc_now.format("%Y-%m-%dT%H:%M:%S").to_string();
-                    let timestamp_str = percent_encoding::utf8_percent_encode(timestamp.clone().as_str(), crate::htx_swap_rest::FRAGMENT).to_string();
-
-                    let access_key = login_param_real.api_key.clone();
-                    let secret_key = login_param_real.secret.clone();
-                    let param_str = format!("AccessKeyId={}&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp={}", access_key, timestamp_str);
-
-                    let signature = {
-                        let message = format!("GET\napi.hbdm.vn\n/linear-swap-notification\n{}", param_str);
-                        trace!("组装数据:\n{}", message);
-
-                        let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-                        let result = hmac::sign(&hmac_key, &message.as_bytes());
-                        let sign = base64::encode(result);
-                        sign
-                    };
-                    let login_param = json!({
-                        "op": "auth",
-                        "type": "api",
-                        "AccessKeyId": access_key,
-                        "SignatureMethod": "HmacSHA256",
-                        "SignatureVersion": "2",
-                        "Timestamp": timestamp,
-                        "Signature": signature,
-                    });
-                    let login_str = login_param.to_string();
-                    info!("发起ws登录: {}", login_str);
-                    let write_tx_c = Arc::clone(&write_tx_clone2);
-                    AbstractWsMode::send_subscribe(write_tx_c, Message::Text(login_str)).await;
-                }
-
-                AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
-                                                 login_is, label.clone(), subscribe_array.clone(), write_to_socket_rx_arc.clone(),
-                                                 Self::message_text_sync, Self::message_ping, Self::message_pong, Self::message_binary_sync,
-                ).await;
-                let mut login_data = LOGIN_DATA.lock().await;
-                // 断联后 设置为没有登录
-                login_data.1 = false;
-                info!("htx_usdt_swap socket 断连,1s以后重连……");
-                error!("htx_usdt_swap socket 断连,1s以后重连……");
-                tokio::time::sleep(Duration::from_secs(1)).await;
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub async fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text).await;
-        Option::from(response_data)
-    }
-    pub fn message_text_sync(text: String) -> Option<ResponseData> {
-        // 使用 tokio::task::block_in_place 来等待异步函数的结果
-        task::block_in_place(|| {
-            tokio::runtime::Handle::current().block_on(Self::message_text(text))
-        })
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -300, "success".to_string(), Value::Null));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -301, "success".to_string(), Value::Null));
-    }
-    //数据解析-二进制
-    pub async fn message_binary(binary: Vec<u8>) -> Option<ResponseData> {
-        //二进制WebSocket消息
-        let message_str = Self::parse_zip_data(binary);
-        let response_data = Self::ok_text(message_str).await;
-        Option::from(response_data)
-    }
-    pub fn message_binary_sync(binary: Vec<u8>) -> Option<ResponseData> {
-        // 使用 tokio::task::block_in_place 来等待异步函数的结果
-        task::block_in_place(|| {
-            tokio::runtime::Handle::current().block_on(Self::message_binary(binary))
-        })
-    }
-    //数据解析
-    pub async fn ok_text(text: String) -> ResponseData
-    {
-        trace!("原始数据:{}", text);
-        let mut res_data = ResponseData::new("".to_string(), 200, "success".to_string(), Value::Null);
-        let json_value: Value = serde_json::from_str(&text).unwrap();
-
-        /*公共:响应*/
-        //心跳包
-        let ping = json_value["ping"].as_i64();
-        match ping {
-            Some(ping_ts) => {
-                let pong = json!({
-                    "pong": ping_ts
-                });
-                return ResponseData::new("".to_string(), -302, "success".to_string(), pong);
-            }
-            None => {}
-        }
-        //推送数据
-        let status = json_value["status"].as_str();
-        match status {
-            Some(v) => {
-                match v {
-                    "ok" => {
-                        res_data.channel = format!("{}", v);
-                        res_data.code = -201;
-                        res_data.data = json_value["data"].clone();
-                    }
-                    "error" => {
-                        res_data.code = 400;
-                        res_data.message = format!("{}", json_value["err-msg"].as_str().unwrap());
-                        res_data.channel = format!("{}", json_value["id"].as_str().unwrap());
-                    }
-                    &_ => {}
-                }
-                return res_data;
-            }
-            None => {}
-        }
-        let ch = json_value["ch"].as_str();
-        match ch {
-            Some(channel) => {
-                res_data.channel = channel.parse().unwrap();
-                res_data.code = 200;
-                res_data.data = json_value["tick"].clone();
-                return res_data;
-            }
-            None => {}
-        }
-
-
-        /*私有:响应*/
-        let op = json_value["op"].as_str().unwrap();
-        match op {
-            "auth" => {
-                let op = json_value["err-code"].as_i64().unwrap();
-                res_data.channel = "auth".to_string();
-                if op == 0 {
-                    res_data.code = -200;
-                    res_data.message = "登录成功".to_string();
-                    res_data.data = json_value["data"].clone();
-                } else {
-                    res_data.code = 400;
-                    res_data.message = format!("登录失败:{}", json_value["err-msg"].as_str().unwrap());
-                }
-                return res_data;
-            }
-            "ping" => {
-                let ts = json_value["ts"].as_str().unwrap();
-                let pong = json!({
-                    "op": "pong",
-                    "ts": ts
-                });
-                return ResponseData::new("".to_string(), -302, "success".to_string(), pong);
-            }
-            "sub" => {
-                res_data.channel = json_value["topic"].as_str().unwrap().to_string();
-                res_data.code = -201;
-                res_data.message = "订阅成功".to_string();
-                return res_data;
-            }
-            "notify" => {
-                res_data.channel = json_value["topic"].as_str().unwrap().to_string();
-                res_data.code = 200;
-                res_data.message = "推送数据".to_string();
-                if json_value.get("data").is_some() {
-                    res_data.data = json_value["data"].clone();
-                } else {
-                    res_data.data = json_value.clone();
-                }
-
-                return res_data;
-            }
-            _ => {}
-        }
-
-
-        res_data.code = 400;
-        res_data.message = format!("未知响应内容");
-        res_data.data = text.parse().unwrap();
-        trace!("--------------------------------");
-        res_data
-    }
-
-    fn parse_zip_data(p0: Vec<u8>) -> String {
-        // 创建一个GzDecoder的实例,将压缩数据作为输入
-        let mut decoder = GzDecoder::new(&p0[..]);
-
-        // 创建一个缓冲区来存放解压缩后的数据
-        let mut decompressed_data = Vec::new();
-
-        // 读取解压缩的数据到缓冲区中
-        decoder.read_to_end(&mut decompressed_data).expect("解压缩失败");
-        let result = from_utf8(&decompressed_data)
-            .expect("解压缩后的数据不是有效的UTF-8");
-
-        // info!("解压缩数据 {:?}", result);
-        result.to_string()
-    }
-}
-

+ 0 - 521
exchanges/src/kucoin_spot_rest.rs

@@ -1,521 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::fmt::Debug;
-// 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;
-// use std::string::String;
-//
-//
-// #[derive(Clone, Debug)]
-// pub struct KucoinSpotRest {
-//     pub label: String,
-//     base_url: String,
-//     client: reqwest::Client,
-//     /*******参数*/
-//     //是否需要登录
-//     //登录所需参数
-//     login_param: BTreeMap<String, String>,
-//     delays: Vec<i64>,
-//     max_delay: i64,
-//     avg_delay: Decimal,
-//
-// }
-//
-// impl KucoinSpotRest {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//
-//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSpotRest
-//     {
-//         return KucoinSpotRest::new_label("default-KucoinSpotRest".to_string(), is_colo, login_param);
-//     }
-//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> KucoinSpotRest {
-//         let base_url = if is_colo {
-//             "https://api.kucoin.com".to_string()
-//         } else {
-//             "https://api.kucoin.com".to_string()
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",base_url);
-//         } else {
-//             info!("走普通通道:{}",base_url);
-//         }
-//         /*****返回结构体*******/
-//         KucoinSpotRest {
-//             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_order(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//              "status":"active",
-//              "tradeType":"TRADE",
-//              "type":"limit"
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 "/orders".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //獲取行情
-//     pub async fn get_level1(&mut self, symbol: String) -> ResponseData {
-//         let params = serde_json::json!({
-//              "symbol":symbol
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 "/market/orderbook/level1".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //通過orderId获取訂單詳情
-//     pub async fn get_order_by_order_id(&mut self, order_id: String) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 format!("/orders/{}", order_id),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //通過clientOid獲取訂單詳情
-//     pub async fn get_order_by_client_id(&mut self, client_id: String) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 format!("/order/client-order/{}", client_id),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //獲取賬戶列表 - 現貨/槓桿/現貨高頻
-//     pub async fn get_accounts(&mut self, currency: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "type":"trade",
-//          });
-//         if currency.len() > 0 {
-//             params.as_object_mut().unwrap().insert("currency".parse().unwrap(), serde_json::Value::from(currency));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 format!("/accounts"),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //獲取交易對列表
-//     pub async fn get_symbols(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v2".to_string(),
-//                                 format!("/symbols"),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //通過orderId撤單
-//     pub async fn cancel_order_by_order_id(&mut self, order_id: String) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("DELETE".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 format!("/orders/{}", order_id),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //通過clientOid撤單
-//     pub async fn cancel_order_by_client_id(&mut self, client_id: String) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("DELETE".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 format!("/order/client-order/{}", client_id),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //全部撤單
-//     pub async fn cancel_order_all(&mut self, symbol: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "tradeType":"TRADE"
-//          });
-//         if symbol.len() > 0 {
-//             params.as_object_mut().unwrap().insert("symbol".parse().unwrap(), serde_json::Value::from(symbol));
-//         }
-//         let data = self.request("DELETE".to_string(),
-//                                 "/api/v1".to_string(),
-//                                 format!("/orders"),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //现货下单-
-//     pub async fn spot_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 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 fn get_delays(&self) -> Vec<i64> {
-//         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::<Sha256>::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::<Sha256>::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<ResponseData, reqwest::Error> {
-//         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(&params),
-//             _ => 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<ResponseData, reqwest::Error>, 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
-//             }
-//         }
-//     }
-// }

+ 0 - 378
exchanges/src/kucoin_spot_ws.rs

@@ -1,378 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-//
-// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-// use tokio::sync::Mutex;
-// use tokio_tungstenite::tungstenite::{Error, Message};
-// use tracing::{error, info, trace};
-//
-// use crate::kucoin_spot_rest::KucoinSpotRest;
-// use crate::response_base::ResponseData;
-// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-//
-// //类型
-// pub enum KucoinSpotWsType {
-//     Public,
-//     Private,
-// }
-//
-// #[derive(Debug)]
-// #[derive(Clone)]
-// pub struct KucoinSpotWsParam {
-//     pub token: String,
-//     pub ws_url: String,
-//     pub ws_ping_interval: i64,
-//     pub ws_ping_timeout: i64,
-//     pub is_ok_subscribe: bool,
-// }
-//
-// //订阅频道
-// #[derive(Clone)]
-// pub enum KucoinSpotSubscribeType {
-//     PuSpotMarketLevel2Depth50,
-//     PuMarketMatch,
-//     PuMarketTicker,
-//
-//     PrSpotMarketTradeOrders,
-//     PrAccountBalance,
-// }
-//
-// //账号信息
-// #[derive(Clone, Debug)]
-// pub struct KucoinSpotLogin {
-//     pub access_key: String,
-//     pub secret_key: String,
-//     pub pass_key: String,
-// }
-//
-// #[derive(Clone)]
-// #[allow(dead_code)]
-// pub struct KucoinSpotWs {
-//     //类型
-//     label: String,
-//     //地址
-//     address_url: String,
-//     //代理信息
-//     login_param: Option<KucoinSpotLogin>,
-//     //登录数据
-//     ws_param: KucoinSpotWsParam,
-//     //币对
-//     symbol_s: Vec<String>,
-//     //订阅
-//     subscribe_types: Vec<KucoinSpotSubscribeType>,
-//     //心跳间隔
-//     heartbeat_time: u64,
-// }
-//
-// impl KucoinSpotWs {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//     pub async fn new(is_colo: bool, login_param: Option<KucoinSpotLogin>, ws_type: KucoinSpotWsType) -> KucoinSpotWs {
-//         return KucoinSpotWs::new_label("default-KucoinSpotWs".to_string(), is_colo, login_param, ws_type).await;
-//     }
-//     pub async fn new_label(label: String, is_colo: bool, login_param: Option<KucoinSpotLogin>, ws_type: KucoinSpotWsType) -> KucoinSpotWs {
-//         /*******公共频道-私有频道数据组装*/
-//         let mut ws_param = KucoinSpotWsParam {
-//             token: "".to_string(),
-//             ws_url: "".to_string(),
-//             ws_ping_interval: 0,
-//             ws_ping_timeout: 0,
-//             is_ok_subscribe: false,
-//         };
-//
-//         /*******公共频道-私有频道数据组装*/
-//         let res_data = KucoinSpotWs::get_rul_token(ws_type, login_param.clone()).await;
-//         let address_url = match res_data {
-//             Ok(param) => {
-//                 ws_param = param;
-//                 format!("{}?token={}", ws_param.ws_url, ws_param.token)
-//             }
-//             Err(error) => {
-//                 error!("-链接地址等参数错误:{:?}", error);
-//                 "".to_string()
-//             }
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",address_url);
-//         } else {
-//             info!("走普通通道:{}",address_url);
-//         }
-//
-//         KucoinSpotWs {
-//             label,
-//             address_url,
-//             login_param,
-//             ws_param,
-//             symbol_s: vec![],
-//             subscribe_types: vec![],
-//             heartbeat_time: 1000 * 18,
-//         }
-//     }
-//
-//     /*******************************************************************************************************/
-//     /*****************************************订阅函数********************************************************/
-//     /*******************************************************************************************************/
-//     //根据当前类型获取对应的频道 地址 与 token
-//     async fn get_rul_token(ws_type: KucoinSpotWsType, login_param: Option<KucoinSpotLogin>) -> Result<KucoinSpotWsParam, reqwest::Error> {
-//         let mut kucoin_exc = KucoinSpotRest::new(false, match login_param {
-//             None => {
-//                 let btree_map: BTreeMap<String, String> = BTreeMap::new();
-//                 btree_map
-//             }
-//             Some(d) => {
-//                 let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-//                 btree_map.insert("access_key".to_string(), d.access_key);
-//                 btree_map.insert("secret_key".to_string(), d.secret_key);
-//                 btree_map.insert("pass_key".to_string(), d.pass_key);
-//                 btree_map
-//             }
-//         });
-//         let res_data = match ws_type {
-//             KucoinSpotWsType::Public => {
-//                 kucoin_exc.get_public_token().await
-//             }
-//             KucoinSpotWsType::Private => {
-//                 kucoin_exc.get_private_token().await
-//             }
-//         };
-//
-//         trace!("kucoin-spot-rest 获取ws连接地址:{:?}",res_data);
-//
-//         if res_data.code == "200" {
-//             let mut ws_url = "".to_string();
-//             let mut ws_token = "".to_string();
-//             let mut ws_ping_interval: i64 = 0;
-//             let mut ws_ping_timeout: i64 = 0;
-//
-//
-//             //数据解析
-//             let parsed_json: serde_json::Value = serde_json::from_str(res_data.data.as_str()).unwrap();
-//             if let Some(value) = parsed_json.get("token") {
-//                 let formatted_value = match value {
-//                     serde_json::Value::String(s) => s.clone(),
-//                     _ => value.to_string()
-//                 };
-//                 ws_token = format!("{}", formatted_value);
-//             }
-//             if let Some(endpoint) = parsed_json["instanceServers"][0]["endpoint"].as_str() {
-//                 ws_url = format!("{}", endpoint);
-//             }
-//             if let Some(ping_interval) = parsed_json["instanceServers"][0]["pingInterval"].as_i64() {
-//                 ws_ping_interval = ping_interval;
-//             }
-//             if let Some(ping_timeout) = parsed_json["instanceServers"][0]["pingTimeout"].as_i64() {
-//                 ws_ping_timeout = ping_timeout;
-//             }
-//
-//
-//             Ok(KucoinSpotWsParam { ws_url, token: ws_token, ws_ping_interval, ws_ping_timeout, is_ok_subscribe: false })
-//         } else {
-//             error!("公共/私有-频道获取失败:{:?}", res_data);
-//             panic!("公共/私有-频道获取失败:{:?}", res_data);
-//         }
-//     }
-//     //手动添加订阅信息
-//     pub fn set_subscribe(&mut self, subscribe_types: Vec<KucoinSpotSubscribeType>) {
-//         self.subscribe_types.extend(subscribe_types);
-//     }
-//     //手动添加币对
-//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-//         for symbol in b_array.iter_mut() {
-//             // 大写
-//             *symbol = symbol.to_uppercase();
-//             // 字符串替换
-//             *symbol = symbol.replace("_", "-");
-//         }
-//         self.symbol_s = b_array;
-//     }
-//     fn contains_pr(&self) -> bool {
-//         for t in self.subscribe_types.clone() {
-//             if match t {
-//                 KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50 => false,
-//                 KucoinSpotSubscribeType::PuMarketMatch => false,
-//                 KucoinSpotSubscribeType::PuMarketTicker => false,
-//
-//                 KucoinSpotSubscribeType::PrSpotMarketTradeOrders => true,
-//                 KucoinSpotSubscribeType::PrAccountBalance => true
-//             } {
-//                 return true;
-//             }
-//         }
-//         false
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************工具函数********************************************************/
-//     /*******************************************************************************************************/
-//     //订阅枚举解析
-//     pub fn enum_to_string(symbol: String, subscribe_type: KucoinSpotSubscribeType) -> serde_json::Value {
-//         match subscribe_type {
-//             KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50 => {//level2
-//                 serde_json::json!({
-//                      "topic": format!("/spotMarket/level2Depth50:{}", symbol),
-//                      "type": "subscribe",
-//                      "response": true
-//                 })
-//             }
-//             KucoinSpotSubscribeType::PuMarketMatch => {//match
-//                 serde_json::json!({
-//                      "topic": format!("/market/match:{}", symbol),
-//                      "type": "subscribe",
-//                      "response": true
-//                 })
-//             }
-//             KucoinSpotSubscribeType::PuMarketTicker => {//ticker
-//                 serde_json::json!({
-//                      "topic": format!("/market/ticker:{}", symbol),
-//                      "type": "subscribe",
-//                      "response": true
-//                 })
-//             }
-//
-//             KucoinSpotSubscribeType::PrSpotMarketTradeOrders => {//market.tradeOrders
-//                 serde_json::json!({
-//                     "type": "subscribe",
-//                     "topic": "/spotMarket/tradeOrders",
-//                     "privateChannel":true,
-//                     "response":true,
-//                 })
-//             }
-//             KucoinSpotSubscribeType::PrAccountBalance => {//account.balance
-//                 serde_json::json!({
-//                     "type": "subscribe",
-//                     "topic": "/account/balance",
-//                     "privateChannel":true,
-//                     "response":true,
-//                 })
-//             }
-//         }
-//     }
-//     //订阅信息生成
-//     pub fn get_subscription(&self) -> Vec<String> {
-//         let mut array = vec![];
-//         for symbol in &self.symbol_s {
-//             for subscribe_type in &self.subscribe_types {
-//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-//                 array.push(ty_str.to_string());
-//             }
-//         }
-//         array
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************socket基本*****************************************************/
-//     /*******************************************************************************************************/
-//     //链接
-//     pub async fn ws_connect_async(&mut self,
-//                                   is_shutdown_arc: Arc<AtomicBool>,
-//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-//                                   write_rx: UnboundedReceiver<Message>,
-//                                   read_tx: UnboundedSender<ResponseData>,
-//     ) -> Result<(), Error>
-//     {
-//         let login_is = self.contains_pr();
-//         let subscription = self.get_subscription();
-//         let address_url = self.address_url.clone();
-//         let label = self.label.clone();
-//         let heartbeat_time = self.ws_param.ws_ping_interval;
-//
-//         //心跳-- 方法内部线程启动
-//         let write_tx_clone1 = write_tx_am.clone();
-//         tokio::spawn(async move {
-//             trace!("线程-异步心跳-开始");
-//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time as u64).await;
-//             trace!("线程-异步心跳-结束");
-//         });
-//
-//
-//         //设置订阅
-//         let subscribe_array = subscription.clone();
-//         if login_is {
-//             //登录相关
-//         }
-//         // let write_tx_clone2 = write_tx_am.clone();
-//         // tokio::spawn(async move {
-//         //     tokio::time::sleep(Duration::from_millis(3 * 1000)).await;
-//         //     for su in subscription.clone(){
-//         //         let write_tx_clone = write_tx_clone2.lock().await;
-//         //         let message = Message::Text(su.clone());
-//         //         write_tx_clone.unbounded_send(message).unwrap();
-//         //     }
-//         // });
-//
-//
-//         //1 链接
-//
-//         let t2 = tokio::spawn(async move {
-//             trace!("线程-异步链接-开始");
-//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
-//                                                    label.clone(), subscribe_array.clone(),
-//                                                    write_rx, read_tx,
-//                                                    Self::message_text,
-//                                                    Self::message_ping,
-//                                                    Self::message_pong,
-//             ).await {
-//                 Ok(_) => { trace!("线程-异步链接-结束"); }
-//                 Err(e) => { trace!("发生异常:kucoin-现货链接关闭-{:?}",e); }
-//             }
-//         });
-//         tokio::try_join!(t2).unwrap();
-//         trace!("线程-心跳与链接-结束");
-//
-//
-//         Ok(())
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************数据解析*****************************************************/
-//     /*******************************************************************************************************/
-//     //数据解析-Text
-//     pub fn message_text(text: String) -> Option<ResponseData> {
-//         let response_data = Self::ok_text(text);
-//         Option::from(response_data)
-//     }
-//     //数据解析-ping
-//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析-pong
-//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-//     }
-//
-//     //数据解析
-//     pub fn ok_text(text: String) -> ResponseData
-//     {
-//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-//         //订阅 相应
-//         if json_value["type"].as_str() == Option::from("welcome") {
-//             //链接成功
-//             res_data.code = "-200".to_string();
-//             res_data.message = "链接成功,主动发起订阅".to_string();
-//             trace!("链接成功,主动发起订阅:");
-//         } else if json_value["type"].as_str() == Option::from("ack") {
-//             res_data.code = "-201".to_string();
-//             res_data.message = "订阅成功".to_string();
-//         } else if json_value["type"].as_str() == Option::from("error") {
-//             res_data.code = format!("{}", json_value["code"]);
-//             res_data.message = format!("{}", json_value["data"].as_str().unwrap());
-//         } else if json_value.get("topic").is_some() {
-//             res_data.channel = format!("{}", json_value["subject"].as_str().unwrap());
-//
-//             if json_value["topic"].as_str() == Option::from("/contractAccount/wallet") {
-//                 res_data.code = "".to_string();
-//                 if json_value["subject"].as_str() == Option::from("availableBalance.change") {
-//                     res_data.code = "200".to_string();
-//                     res_data.data = json_value["data"].to_string();
-//                 } else {}
-//             } else {
-//                 res_data.data = json_value["data"].to_string();
-//             }
-//         } else {
-//             res_data.code = "".to_string();
-//             res_data.message = "未知解析".to_string();
-//         }
-//         res_data
-//     }
-// }

+ 0 - 625
exchanges/src/kucoin_swap_rest.rs

@@ -1,625 +0,0 @@
-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<String, String>,
-    delays: Vec<i64>,
-    max_delay: i64,
-    avg_delay: Decimal,
-}
-
-impl KucoinSwapRest {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-
-    pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> 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<String, String>) -> 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<i64> {
-        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::<Sha256>::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::<Sha256>::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<ResponseData, reqwest::Error> {
-        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(&params),
-            _ => 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?;
-
-            let data = serde_json::from_str(body.as_str()).unwrap();
-            res_data = ResponseData::new(self.label.clone(), 200, "success".to_string(), data);
-        } 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<ResponseData, reqwest::Error>, 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 json_value = res_data.data;
-
-                    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.message = format!("请求地址:{},请求参数:{},响应:{}。", base_url, params, json_value.to_string());
-                        error
-                    } else {
-                        let data = serde_json::to_string(&json_value["data"]).unwrap();
-                        let success = ResponseData::new("".to_string(), 200, "success".to_string(), data.parse().unwrap());
-                        success
-                    }
-                }
-            }
-            Err(err) => {
-                let error = ResponseData::error("".to_string(), format!("json 解析失败:{},相关参数:{}", err, params));
-                error
-            }
-        }
-    }
-}

+ 0 - 403
exchanges/src/kucoin_swap_ws.rs

@@ -1,403 +0,0 @@
-use std::collections::BTreeMap;
-use std::str::FromStr;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::Duration;
-
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use serde_json::Value;
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{error, info, trace};
-
-use crate::kucoin_swap_rest::KucoinSwapRest;
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum KucoinSwapWsType {
-    Public,
-    Private,
-}
-
-
-#[derive(Debug)]
-#[derive(Clone)]
-pub struct KucoinSwapWsParam {
-    pub token: String,
-    pub ws_url: String,
-    pub ws_ping_interval: i64,
-    pub ws_ping_timeout: i64,
-    pub is_ok_subscribe: bool,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum KucoinSwapSubscribeType {
-    //买卖盘 快照,asks:卖,bids:买入
-    PuContractMarketLevel2Depth50,
-
-    PuContractMarketExecution,
-    PuContractMarkettickerV2,
-
-    PrContractAccountWallet,
-    PrContractPosition,
-    PrContractMarketTradeOrdersSys,
-    PrContractMarketTradeOrders,
-}
-
-//账号信息
-#[derive(Clone, Debug)]
-pub struct KucoinSwapLogin {
-    pub access_key: String,
-    pub secret_key: String,
-    pub pass_key: String,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct KucoinSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号
-    login_param: Option<KucoinSwapLogin>,
-    //登录数据
-    ws_param: KucoinSwapWsParam,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<KucoinSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl KucoinSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub async fn new(is_colo: bool, login_param: Option<KucoinSwapLogin>, ws_type: KucoinSwapWsType) -> KucoinSwapWs {
-        return Self::new_label("default-KucoinSwapWs".to_string(), is_colo, login_param, ws_type).await;
-    }
-    pub async fn new_label(label: String, is_colo: bool, login_param: Option<KucoinSwapLogin>, ws_type: KucoinSwapWsType) -> KucoinSwapWs {
-        /*******公共频道-私有频道数据组装*/
-        let mut ws_param = KucoinSwapWsParam {
-            token: "".to_string(),
-            ws_url: "".to_string(),
-            ws_ping_interval: 0,
-            ws_ping_timeout: 0,
-            is_ok_subscribe: false,
-        };
-
-        /*******公共频道-私有频道数据组装*/
-        let res_data = Self::get_rul_token(ws_type, login_param.clone()).await;
-        let address_url = match res_data {
-            Ok(param) => {
-                ws_param = param;
-                format!("{}?token={}", ws_param.ws_url, ws_param.token)
-            }
-            Err(error) => {
-                error!("-链接地址等参数错误:{:?}", error);
-                "".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        KucoinSwapWs {
-            label,
-            address_url,
-            login_param,
-            ws_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 18,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //根据当前类型获取对应的频道 地址 与 token
-    async fn get_rul_token(ws_type: KucoinSwapWsType, login_param: Option<KucoinSwapLogin>) -> Result<KucoinSwapWsParam, reqwest::Error> {
-        let mut kucoin_exc = KucoinSwapRest::new(false, match login_param {
-            None => {
-                let btree_map: BTreeMap<String, String> = BTreeMap::new();
-                btree_map
-            }
-            Some(d) => {
-                let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-                btree_map.insert("access_key".to_string(), d.access_key);
-                btree_map.insert("secret_key".to_string(), d.secret_key);
-                btree_map.insert("pass_key".to_string(), d.pass_key);
-                btree_map
-            }
-        });
-
-
-        let res_data = match ws_type {
-            KucoinSwapWsType::Public => {
-                kucoin_exc.get_public_token().await
-            }
-            KucoinSwapWsType::Private => {
-                kucoin_exc.get_private_token().await
-            }
-        };
-
-        trace!("kucoin-swap-rest 获取ws连接地址:{:?}",res_data);
-
-        if res_data.code == 200 {
-            let mut ws_url = "".to_string();
-            let mut ws_token = "".to_string();
-            let mut ws_ping_interval: i64 = 0;
-            let mut ws_ping_timeout: i64 = 0;
-
-
-            //数据解析
-            let parsed_json = res_data.data;
-            if let Some(value) = parsed_json.get("token") {
-                let formatted_value = match value {
-                    serde_json::Value::String(s) => s.clone(),
-                    _ => value.to_string()
-                };
-                ws_token = format!("{}", formatted_value);
-            }
-            if let Some(endpoint) = parsed_json["instanceServers"][0]["endpoint"].as_str() {
-                ws_url = format!("{}", endpoint);
-            }
-            if let Some(ping_interval) = parsed_json["instanceServers"][0]["pingInterval"].as_i64() {
-                ws_ping_interval = ping_interval;
-            }
-            if let Some(ping_timeout) = parsed_json["instanceServers"][0]["pingTimeout"].as_i64() {
-                ws_ping_timeout = ping_timeout;
-            }
-
-
-            Ok(KucoinSwapWsParam { ws_url, token: ws_token, ws_ping_interval, ws_ping_timeout, is_ok_subscribe: false })
-        } else {
-            error!("公共/私有-频道获取失败:{:?}", res_data);
-            panic!("公共/私有-频道获取失败:{:?}", res_data);
-        }
-    }
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<KucoinSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "");
-            *symbol = symbol.replace("-", "");
-        }
-        self.symbol_s = b_array;
-    }
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                KucoinSwapSubscribeType::PuContractMarketLevel2Depth50 => false,
-                KucoinSwapSubscribeType::PuContractMarketExecution => false,
-                KucoinSwapSubscribeType::PuContractMarkettickerV2 => false,
-
-                KucoinSwapSubscribeType::PrContractAccountWallet => true,
-                KucoinSwapSubscribeType::PrContractPosition => true,
-                KucoinSwapSubscribeType::PrContractMarketTradeOrdersSys => true,
-                KucoinSwapSubscribeType::PrContractMarketTradeOrders => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: KucoinSwapSubscribeType) -> serde_json::Value {
-        match subscribe_type {
-            KucoinSwapSubscribeType::PuContractMarketLevel2Depth50 => {//level2
-                serde_json::json!({
-                     "topic": format!("/contractMarket/level2Depth50:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSwapSubscribeType::PuContractMarketExecution => {//match
-                serde_json::json!({
-                     "topic": format!("/contractMarket/execution:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSwapSubscribeType::PuContractMarkettickerV2 => {//tickerV2
-                serde_json::json!({
-                     "topic": format!("/contractMarket/tickerV2:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSwapSubscribeType::PrContractAccountWallet => {//orderMargin.change
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": "/contractAccount/wallet",
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-            KucoinSwapSubscribeType::PrContractPosition => {//position.change
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": format!("/contract/position:{}", symbol),
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-            KucoinSwapSubscribeType::PrContractMarketTradeOrdersSys => {//orderChange
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": format!("/contractMarket/tradeOrders"),
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-            KucoinSwapSubscribeType::PrContractMarketTradeOrders => {//symbolOrderChange
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": format!("/contractMarket/tradeOrders:{}", symbol),
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> Vec<String> {
-        let mut array = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                array.push(ty_str.to_string());
-            }
-        }
-        array
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async<F, Future>(&mut self,
-                                             is_shutdown_arc: Arc<AtomicBool>,
-                                             handle_function: F,
-                                             write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                             write_to_socket_rx: UnboundedReceiver<Message>) -> Result<(), Error>
-        where
-            F: Fn(ResponseData) -> Future + Clone + Send + 'static + Sync,
-            Future: std::future::Future<Output=()> + Send + 'static, // 确保 Fut 是一个 Future,且输出类型为 ()
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.ws_param.ws_ping_interval.clone();
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = write_tx_am.clone();
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time as u64).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-
-        //设置订阅
-        let subscribe_array = subscription.clone();
-        if login_is {
-            //登录相关
-        }
-
-        //1 链接
-        let t2 = tokio::spawn(async move {
-            let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
-
-            loop {
-                info!("kucoin_usdt_swap socket 连接中……");
-                AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
-                                                 false, label.clone(), subscribe_array.clone(), write_to_socket_rx_arc.clone(),
-                                                 Self::message_text, Self::message_ping, Self::message_pong, Self::message_binary).await;
-
-                error!("kucoin_usdt_swap socket 断连,1s以后重连……");
-                tokio::time::sleep(Duration::from_secs(1)).await;
-            }
-        });
-
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -300, "success".to_string(), Value::Null));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), -301, "success".to_string(), Value::Null));
-    }
-    //数据解析-二进制
-    pub fn message_binary(_po: Vec<u8>) -> Option<ResponseData> {
-        //二进制WebSocket消息
-        let message_str = format!("Binary:{:?}", _po);
-        Option::from(ResponseData::new("".to_string(), 2, message_str, Value::Null))
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData
-    {
-        // trace!("原始数据:{:?}",text);
-        let mut res_data = ResponseData::new("".to_string(), 200, "success".to_string(), Value::Null);
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-
-        //订阅 相应
-        if json_value["type"].as_str() == Option::from("welcome") {
-            //链接成功
-            res_data.code = -200;
-            res_data.message = "链接成功,主动发起订阅".to_string();
-        } else if json_value["type"].as_str() == Option::from("ack") {
-            res_data.code = -201;
-            res_data.message = "订阅成功".to_string();
-        } else if json_value["type"].as_str() == Option::from("error") {
-            res_data.code = i16::from_str(json_value["code"].as_str().unwrap()).unwrap();
-            res_data.message = format!("{}", json_value["data"].as_str().unwrap());
-        } else if json_value.get("topic").is_some() {
-            res_data.channel = format!("{}", json_value["subject"].as_str().unwrap());
-
-            if json_value["topic"].as_str() == Option::from("/contractAccount/wallet") {
-                res_data.code = -1;
-                if json_value["subject"].as_str() == Option::from("availableBalance.change") {
-                    res_data.code = 200;
-                    res_data.data = json_value["data"].clone();
-                } else {}
-            } else {
-                res_data.data = json_value["data"].clone();
-            }
-        } else {
-            res_data.code = -1;
-            res_data.message = "未知解析".to_string();
-        }
-        res_data
-    }
-}

+ 0 - 23
exchanges/src/lib.rs

@@ -1,32 +1,9 @@
 pub mod proxy;
 pub mod proxy;
 pub mod response_base;
 pub mod response_base;
 pub mod http_tool;
 pub mod http_tool;
-pub mod binance_spot_rest;
-pub mod binance_spot_ws;
-pub mod gate_spot_rest;
-pub mod gate_spot_ws;
 pub mod gate_swap_ws;
 pub mod gate_swap_ws;
 pub mod gate_swap_rest;
 pub mod gate_swap_rest;
 pub mod socket_tool;
 pub mod socket_tool;
-pub mod kucoin_swap_rest;
-pub mod kucoin_swap_ws;
-pub mod okx_swap_ws;
-pub mod binance_swap_ws;
-pub mod okx_swap_rest;
-pub mod binance_swap_rest;
 mod utils;
 mod utils;
-pub mod bitget_spot_ws;
-pub mod bitget_spot_rest;
-pub mod bitget_swap_ws;
-pub mod bitget_swap_rest;
-pub mod kucoin_spot_ws;
-pub mod kucoin_spot_rest;
-pub mod crypto_spot_ws;
-pub mod bybit_swap_rest;
 pub mod xlsx_utils;
 pub mod xlsx_utils;
-pub mod bybit_swap_ws;
-pub mod coinex_swap_rest;
-pub mod coinex_swap_ws;
-pub mod htx_swap_ws;
-pub mod htx_swap_rest;
 
 

+ 0 - 580
exchanges/src/okx_swap_rest.rs

@@ -1,580 +0,0 @@
-// use std::collections::BTreeMap;
-// use reqwest::header::HeaderMap;
-// use reqwest::{Client};
-// use rust_decimal::Decimal;
-// use rust_decimal::prelude::FromPrimitive;
-// use rust_decimal_macros::dec;
-// use tracing::{info, trace};
-// use crate::http_tool::RestTool;
-// use crate::response_base::ResponseData;
-// use ring::hmac;
-//
-// #[derive(Clone, Debug)]
-// pub struct OkxSwapRest {
-//     pub label: String,
-//     base_url: String,
-//     client: reqwest::Client,
-//     /*******参数*/
-//     //是否需要登录
-//     //登录所需参数
-//     login_param: BTreeMap<String, String>,
-//     delays: Vec<i64>,
-//     max_delay: i64,
-//     avg_delay: Decimal,
-//
-// }
-//
-// impl OkxSwapRest {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//
-//     pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> OkxSwapRest
-//     {
-//         return OkxSwapRest::new_label("default-OkxSwapRest".to_string(), is_colo, login_param);
-//     }
-//     pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> OkxSwapRest {
-//         let base_url = if is_colo {
-//             "https://www.okx.com".to_string()
-//         } else {
-//             "https://www.okx.com".to_string()
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",base_url);
-//         } else {
-//             info!("走普通通道:{}",base_url);
-//         }
-//         /*****返回结构体*******/
-//         OkxSwapRest {
-//             label,
-//             base_url,
-//             client: Client::new(),
-//             login_param,
-//             delays: vec![],
-//             max_delay: 0,
-//             avg_delay: dec!(0.0),
-//         }
-//     }
-//
-//     /*******************************************************************************************************/
-//     /*****************************************rest请求函数********************************************************/
-//     /*******************************************************************************************************/
-//     //获取订单信息
-//     pub async fn get_order(&mut self, symbol: String, ord_id: String, cl_ord_id: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "instId":symbol
-//          });
-//         if ord_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("ordId".parse().unwrap(), serde_json::Value::from(ord_id));
-//         }
-//         if cl_ord_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("clOrdId".parse().unwrap(), serde_json::Value::from(cl_ord_id));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/trade/order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取未成交订单列表
-//     pub async fn get_incomplete_order(&mut self, symbol: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "instId":symbol
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/trade/orders-pending".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取系统时间
-//     pub async fn get_server_time(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/public/time".to_string(),
-//                                 false,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //查看持仓信息
-//     pub async fn get_positions(&mut self, inst_type: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//          });
-//         if inst_type.len() > 0 {
-//             params.as_object_mut().unwrap().insert("instType".parse().unwrap(), serde_json::Value::from(inst_type));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/account/positions".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取单个产品行情信息
-//     pub async fn get_ticker(&mut self, symbol: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "instId":symbol
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/market/ticker".to_string(),
-//                                 false,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //查看账户余额
-//     pub async fn get_balance(&mut self, ccy: String) -> ResponseData {
-//         let params = serde_json::json!({
-//             "ccy":ccy
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/account/balance".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取交易产品基础信息
-//     pub async fn get_instruments(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//            "instType":"SWAP"
-//          });
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/public/instruments".to_string(),
-//                                 false,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //获取成交明细(近三天)
-//     pub async fn get_trade_fills(&mut self, after: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//              "instType": "SWAP",
-//              "limit":"100"
-//          });
-//         if after.len() > 0 {
-//             params.as_object_mut().unwrap().insert("after".parse().unwrap(), serde_json::Value::from(after));
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/trade/fills".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //获取成交明细(近三个月)
-//     pub async fn get_trade_fills_history(&mut self, inst_id: String, begin: String, end: String, limit: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//             "instType": "SWAP",
-//             "instId":inst_id,
-//             "limit":100,
-//          });
-//
-//         if begin.len() > 0 {
-//             params["begin"] = serde_json::json!(begin);
-//         }
-//         if end.len() > 0 {
-//             params["end"] = serde_json::json!(end);
-//         }
-//         if limit.len() > 0 {
-//             params["limit"] = serde_json::json!(limit);
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/trade/fills-history".to_string(),
-//                                 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/v5".to_string(),
-//                                 "/trade/order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //撤单
-//     pub async fn cancel_order(&mut self, symbol: String, ord_id: String, cl_ord_id: String) -> ResponseData {
-//         let mut params = serde_json::json!({
-//              "instId": symbol
-//          });
-//         if ord_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("ordId".parse().unwrap(), serde_json::Value::from(ord_id));
-//         }
-//         if cl_ord_id.len() > 0 {
-//             params.as_object_mut().unwrap().insert("clOrdId".parse().unwrap(), serde_json::Value::from(cl_ord_id));
-//         }
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/trade/cancel-order".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //设置杠杆倍数-单币种保证金`账户在`全仓`交易模式下,设置`币币杠杆`的杠杆倍数(币对层面)
-//     pub async fn set_leverage(&mut self, symbol: String, lever: String) -> ResponseData {
-//         let params = serde_json::json!({
-//              "instId": symbol,
-//              "lever": lever,
-//              "mgnMode": "cross"
-//          });
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/account/set-leverage".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//     //设置持仓模式
-//     pub async fn set_position_mode(&mut self) -> ResponseData {
-//         let params = serde_json::json!({
-//              "posMode": "long_short_mode",
-//          });
-//         let data = self.request("POST".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/account/set-position-mode".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //获取历史订单记录(近七天)
-//     pub async fn get_orders_history(&mut self,
-//                                     sprd_id: String,
-//                                     ord_type: String,
-//                                     state: String,
-//                                     begin: String,
-//                                     end: String,
-//                                     limit: String,
-//     ) -> ResponseData {
-//         let mut params = serde_json::json!({
-//          });
-//         if sprd_id.len() > 0 {
-//             params["sprdId"] = serde_json::json!(sprd_id);
-//         }
-//         if ord_type.len() > 0 {
-//             params["ordType"] = serde_json::json!(ord_type);
-//         }
-//         if state.len() > 0 {
-//             params["state"] = serde_json::json!(state);
-//         }
-//         if begin.len() > 0 {
-//             params["begin"] = serde_json::json!(begin);
-//         }
-//         if end.len() > 0 {
-//             params["end"] = serde_json::json!(end);
-//         }
-//         if limit.len() > 0 {
-//             params["limit"] = serde_json::json!(limit);
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/sprd/orders-history".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     //获取历史成交数据(近七天)
-//     pub async fn get_trades(&mut self,
-//                             sprd_id: String,
-//                             trade_id: String,
-//                             ord_id: String,
-//                             begin: String,
-//                             end: String,
-//                             limit: String,
-//     ) -> ResponseData {
-//         let mut params = serde_json::json!({
-//          });
-//         if sprd_id.len() > 0 {
-//             params["sprdId"] = serde_json::json!(sprd_id);
-//         }
-//         if trade_id.len() > 0 {
-//             params["tradeId"] = serde_json::json!(trade_id);
-//         }
-//         if ord_id.len() > 0 {
-//             params["ordId"] = serde_json::json!(ord_id);
-//         }
-//         if begin.len() > 0 {
-//             params["begin"] = serde_json::json!(begin);
-//         }
-//         if end.len() > 0 {
-//             params["end"] = serde_json::json!(end);
-//         }
-//         if limit.len() > 0 {
-//             params["limit"] = serde_json::json!(limit);
-//         }
-//         let data = self.request("GET".to_string(),
-//                                 "/api/v5".to_string(),
-//                                 "/sprd/trades".to_string(),
-//                                 true,
-//                                 params.to_string(),
-//         ).await;
-//         data
-//     }
-//
-//     /*******************************************************************************************************/
-//     /*****************************************工具函数********************************************************/
-//     /*******************************************************************************************************/
-//     pub fn get_delays(&self) -> Vec<i64> {
-//         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 passphrase = "".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") {
-//             passphrase = self.login_param.get("pass_key").unwrap().to_string();
-//         }
-//         let mut is_login_param = true;
-//         if access_key == "" || secret_key == "" || passphrase == "" {
-//             is_login_param = false
-//         }
-//
-//
-//         //请求头配置-如果需要登录则存在额外配置
-//         let mut body = "".to_string();
-//         let timestamp = Self::get_timestamp();
-//         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(),
-//                 );
-//                 //组装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(
-//             format!("{}{}", prefix_url.clone(), request_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("OK-ACCESS-KEY", access_key.parse().unwrap());
-//         headers.insert("OK-ACCESS-SIGN", sign.parse().unwrap());
-//         headers.insert("OK-ACCESS-TIMESTAMP", timestamp.parse().unwrap());
-//         headers.insert("OK-ACCESS-PASSPHRASE", passphrase.parse().unwrap());
-//         headers
-//     }
-//     pub fn sign(secret_key: String,
-//                 method: String, prefix_url: String, request_url: String,
-//                 params: String, body: String, timestamp: String) -> String
-//     {
-//         /*签名生成*/
-//         let url_param_str = RestTool::parse_params_to_str(params);
-//         let base_url = if method == "GET" {
-//             format!("{}{}?{}", prefix_url, request_url, url_param_str)
-//         } else {
-//             format!("{}{}", prefix_url, request_url)
-//         };
-//
-//         // 时间戳 + 请求类型+ 请求参数字符串
-//         let message = format!("{}{}{}{}", timestamp, method, base_url, body);
-//         trace!("message:{}",message);
-//
-//         // 做签名
-//         let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-//         let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-//         let sign = base64::encode(result);
-//         sign
-//     }
-//
-//     async fn http_tool(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
-//         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 params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
-//         trace!("params_json:{}",params_json);
-//         trace!("headers:{:?}",headers);
-//
-//
-//         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(&params),
-//             _ => 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<ResponseData, reqwest::Error>, base_url: String, params: String) -> ResponseData {
-//         // trace!("原始数据:{:?}",result);
-//         match result {
-//             Ok(res_data) => {
-//                 if res_data.code != "200" {
-//                     // trace!("不等于200");
-//                     let message: String = res_data.message;
-//                     let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();
-//                     let code = json_value["code"].as_str().unwrap();
-//                     let msg = json_value["msg"].as_str().unwrap();
-//                     let error = ResponseData::new("".to_string(),
-//                                                   format!("{}", code),
-//                                                   format!("{}", msg),
-//                                                   format!("请求地址:{},请求参数:{}", base_url, params));
-//                     error
-//                 } else {
-//                     // trace!("等于200");
-//                     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 == "0" {
-//                         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
-//                     } else if code == "1" || code == "0" {
-//                         let msg = json_value["msg"].as_str().unwrap();
-//                         let data = serde_json::to_string(&json_value["data"]).unwrap();
-//
-//                         let data_json: serde_json::Value = serde_json::from_str(&data).unwrap();
-//                         let code_v = data_json[0]["sCode"].as_str().unwrap();
-//                         let msg_v = data_json[0]["sMsg"].as_str().unwrap();
-//                         // trace!("发生错误:??{:?}",data_json.to_string());
-//                         let error = ResponseData::new("".to_string(),
-//                                                       format!("{}", code_v),
-//                                                       format!("{}:{}", msg, msg_v),
-//                                                       format!("请求地址:{},请求参数:{}", base_url, params));
-//                         error
-//                     } else {
-//                         let msg = json_value["msg"].as_str().unwrap();
-//                         // trace!("发生错误:??{:?}",data_json.to_string());
-//                         let error = ResponseData::new("".to_string(),
-//                                                       format!("{}", code),
-//                                                       format!("{}", msg),
-//                                                       format!("请求地址:{},请求参数:{}", base_url, params));
-//                         error
-//                     }
-//                 }
-//             }
-//             Err(err) => {
-//                 let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
-//                 error
-//             }
-//         }
-//     }
-//     fn get_timestamp() -> String {
-//         chrono::Utc::now()
-//             .format("%Y-%m-%dT%H:%M:%S%.3fZ")
-//             .to_string()
-//     }
-// }

+ 0 - 371
exchanges/src/okx_swap_ws.rs

@@ -1,371 +0,0 @@
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// use std::time::Duration;
-//
-// use chrono::Utc;
-// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-// use ring::hmac;
-// use serde_json::{json, Value};
-// use tokio::sync::Mutex;
-// use tokio_tungstenite::tungstenite::{Error, Message};
-// use tracing::{info, trace};
-//
-// use crate::response_base::ResponseData;
-// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-//
-// //类型
-// pub enum OkxSwapWsType {
-//     //订阅频道类型
-//     Public,
-//     Private,
-//     Business,
-// }
-//
-// //订阅频道
-// #[derive(Clone)]
-// pub enum OkxSwapSubscribeType {
-//     PuIndexTickers,
-//     PuBooks5,
-//     Putrades,
-//     PuBooks50L2tbt,
-//
-//     BuIndexCandle30m,
-//
-//     PrBalanceAndPosition,
-//     PrAccount(String),
-//     PrOrders,
-//     PrPositions,
-//
-// }
-//
-// //账号信息
-// #[derive(Clone)]
-// #[allow(dead_code)]
-// pub struct OkxSwapLogin {
-//     pub api_key: String,
-//     pub secret_key: String,
-//     pub passphrase: String,
-// }
-//
-// #[derive(Clone)]
-// pub struct OkxSwapWs {
-//     //类型
-//     label: String,
-//     //地址
-//     address_url: String,
-//     //账号信息
-//     login_param: Option<OkxSwapLogin>,
-//     //币对
-//     symbol_s: Vec<String>,
-//     //订阅
-//     subscribe_types: Vec<OkxSwapSubscribeType>,
-//     //心跳间隔
-//     heartbeat_time: u64,
-// }
-//
-// impl OkxSwapWs {
-//     /*******************************************************************************************************/
-//     /*****************************************获取一个对象****************************************************/
-//     /*******************************************************************************************************/
-//     pub fn new(is_colo: bool, login_param: Option<OkxSwapLogin>, ws_type: OkxSwapWsType) -> OkxSwapWs {
-//         return OkxSwapWs::new_label("default-OkxSwapWs".to_string(), is_colo, login_param, ws_type);
-//     }
-//     pub fn new_label(label: String, is_colo: bool, login_param: Option<OkxSwapLogin>, ws_type: OkxSwapWsType) -> OkxSwapWs {
-//         /*******公共频道-私有频道数据组装*/
-//         let address_url = match ws_type {
-//             OkxSwapWsType::Public => {
-//                 "wss://ws.okx.com:8443/ws/v5/public".to_string()
-//             }
-//             OkxSwapWsType::Private => {
-//                 "wss://ws.okx.com:8443/ws/v5/private".to_string()
-//             }
-//             OkxSwapWsType::Business => {
-//                 "wss://ws.okx.com:8443/ws/v5/business".to_string()
-//             }
-//         };
-//
-//         if is_colo {
-//             info!("开启高速(未配置,走普通:{})通道",address_url);
-//         } else {
-//             info!("走普通通道:{}",address_url);
-//         }
-//         /*****返回结构体*******/
-//         OkxSwapWs {
-//             label,
-//             address_url,
-//             login_param,
-//             symbol_s: vec![],
-//             subscribe_types: vec![],
-//             heartbeat_time: 1000 * 10,
-//         }
-//     }
-//
-//     /*******************************************************************************************************/
-//     /*****************************************订阅函数********************************************************/
-//     /*******************************************************************************************************/
-//     //手动添加订阅信息
-//     pub fn set_subscribe(&mut self, subscribe_types: Vec<OkxSwapSubscribeType>) {
-//         self.subscribe_types.extend(subscribe_types);
-//     }
-//     //手动添加币对
-//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-//         for symbol in b_array.iter_mut() {
-//             // 小写
-//             *symbol = symbol.to_uppercase();
-//             // 字符串替换
-//             *symbol = symbol.replace("_", "-");
-//         }
-//         self.symbol_s = b_array;
-//     }
-//     //频道是否需要登录
-//     fn contains_pr(&self) -> bool {
-//         for t in self.subscribe_types.clone() {
-//             if match t {
-//                 OkxSwapSubscribeType::PuIndexTickers => false,
-//                 OkxSwapSubscribeType::PuBooks5 => false,
-//                 OkxSwapSubscribeType::Putrades => false,
-//                 OkxSwapSubscribeType::PuBooks50L2tbt => false,
-//
-//                 OkxSwapSubscribeType::BuIndexCandle30m => false,
-//
-//                 OkxSwapSubscribeType::PrBalanceAndPosition => true,
-//                 OkxSwapSubscribeType::PrAccount(_) => true,
-//                 OkxSwapSubscribeType::PrOrders => true,
-//                 OkxSwapSubscribeType::PrPositions => true,
-//             } {
-//                 return true;
-//             }
-//         }
-//         false
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************工具函数********************************************************/
-//     /*******************************************************************************************************/
-//     //订阅枚举解析
-//     pub fn enum_to_string(symbol: String, subscribe_type: OkxSwapSubscribeType) -> Value {
-//         match subscribe_type {
-//             OkxSwapSubscribeType::PuIndexTickers => {
-//                 json!({
-//                     "channel":"index-tickers",
-//                     "instId":symbol
-//                 })
-//             }
-//
-//             OkxSwapSubscribeType::PuBooks5 => {
-//                 json!({
-//                     "channel":"books5",
-//                     "instId":symbol
-//                 })
-//             }
-//             OkxSwapSubscribeType::Putrades => {
-//                 json!({
-//                     "channel":"trades",
-//                     "instId":symbol
-//                 })
-//             }
-//
-//             OkxSwapSubscribeType::BuIndexCandle30m => {
-//                 json!({
-//                     "channel":"index-candle30m",
-//                     "instId":symbol
-//                 })
-//             }
-//
-//             OkxSwapSubscribeType::PrAccount(ccy) => {
-//                 json!({
-//                     "channel":"account",
-//                     "ccy":ccy
-//                 })
-//             }
-//             OkxSwapSubscribeType::PuBooks50L2tbt => {
-//                 json!({
-//                     "channel":"books50-l2-tbt",
-//                     "instId":symbol
-//                 })
-//             }
-//             OkxSwapSubscribeType::PrBalanceAndPosition => {
-//                 json!({
-//                     "channel":"balance_and_position"
-//                 })
-//             }
-//             OkxSwapSubscribeType::PrOrders => {
-//                 json!({
-//                     "channel":"orders",
-//                     "instType":"SWAP",
-//                     "instFamily":symbol
-//                 })
-//             }
-//             OkxSwapSubscribeType::PrPositions => {
-//                 json!({
-//                     "channel":"positions",
-//                     "instType":"SWAP",
-//                 })
-//             }
-//         }
-//     }
-//     //订阅信息生成
-//     pub fn get_subscription(&self) -> String {
-//         let mut args = vec![];
-//         for symbol in &self.symbol_s {
-//             for subscribe_type in &self.subscribe_types {
-//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-//                 args.push(ty_str);
-//             }
-//         }
-//         let str = json!({
-//             "op": "subscribe",
-//             "args": args
-//         });
-//
-//         // trace!("订阅信息:{}", str.to_string());
-//
-//         str.to_string()
-//     }
-//     //登录组装
-//     fn log_in_to_str(login_param: Option<OkxSwapLogin>) -> String {
-//         let mut login_json_str = "".to_string();
-//
-//         let mut access_key: String = "".to_string();
-//         let mut secret_key: String = "".to_string();
-//         let mut passphrase: String = "".to_string();
-//
-//
-//         if let Some(param) = login_param {
-//             access_key = param.api_key;
-//             secret_key = param.secret_key;
-//             passphrase = param.passphrase;
-//         }
-//
-//         if access_key.len() > 0 || secret_key.len() > 0 || passphrase.len() > 0 {
-//             let timestamp = Utc::now().timestamp().to_string();
-//             // 时间戳 + 请求类型+ 请求参数字符串
-//             let message = format!("{}GET{}", timestamp, "/users/self/verify");
-//             let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-//             let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-//             let sign = base64::encode(result);
-//
-//             let login_json = json!({
-//                               "op": "login",
-//                                 "args": [{
-//                                 "apiKey": access_key,
-//                                 "passphrase": passphrase,
-//                                 "timestamp": timestamp,
-//                                 "sign": sign  }]
-//                         });
-//
-//             trace!("---login_json:{0}", login_json.to_string());
-//             trace!("--登录:{}", login_json.to_string());
-//             login_json_str = login_json.to_string();
-//         }
-//         login_json_str
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************socket基本*****************************************************/
-//     /*******************************************************************************************************/
-//     //链接
-//     pub async fn ws_connect_async(&mut self,
-//                                   is_shutdown_arc: Arc<AtomicBool>,
-//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-//                                   write_rx: UnboundedReceiver<Message>,
-//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-//     {
-//         let login_is = self.contains_pr();
-//         let subscription = self.get_subscription();
-//         let address_url = self.address_url.clone();
-//         let label = self.label.clone();
-//         let heartbeat_time = self.heartbeat_time.clone();
-//
-//
-//         //心跳-- 方法内部线程启动
-//         let write_tx_clone1 = Arc::clone(write_tx_am);
-//         tokio::spawn(async move {
-//             trace!("线程-异步心跳-开始");
-//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
-//             trace!("线程-异步心跳-结束");
-//         });
-//
-//         //设置订阅
-//         let  subscribe_array = vec![];
-//         if login_is {
-//             let write_tx_clone2 = Arc::clone(write_tx_am);
-//             let login_str = Self::log_in_to_str(self.login_param.clone());
-//             tokio::spawn(async move {
-//                 //登录相关
-//                 AbstractWsMode::send_subscribe(write_tx_clone2, Message::Text(login_str)).await;
-//             });
-//         }
-//         let write_tx_clone3 = Arc::clone(write_tx_am);
-//         tokio::spawn(async move {
-//             tokio::time::sleep(Duration::from_millis(3 * 1000)).await;
-//             //登录相关
-//             AbstractWsMode::send_subscribe(write_tx_clone3, Message::Text(subscription)).await;
-//         });
-//
-//         //链接
-//         let t2 = tokio::spawn(async move {
-//             trace!("线程-异步链接-开始");
-//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
-//                                              label.clone(), subscribe_array,
-//                                              write_rx, read_tx,
-//                                              Self::message_text,
-//                                              Self::message_ping,
-//                                              Self::message_pong,
-//             ).await{
-//                 Ok(_) => { trace!("线程-异步链接-结束"); }
-//                 Err(e) => { trace!("发生异常:okx-期货链接关闭-{:?}",e); }
-//             }
-//         });
-//         tokio::try_join!(t2).unwrap();
-//         trace!("线程-心跳与链接-结束");
-//
-//         Ok(())
-//     }
-//     /*******************************************************************************************************/
-//     /*****************************************数据解析*****************************************************/
-//     /*******************************************************************************************************/
-//     //数据解析-Text
-//     pub fn message_text(text: String) -> Option<ResponseData> {
-//         let  response_data = Self::ok_text(text);
-//         Option::from(response_data)
-//     }
-//     //数据解析-ping
-//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析-pong
-//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-//     }
-//     //数据解析
-//     pub fn ok_text(text: String) -> ResponseData
-//     {
-//         // trace!("元数据:{}",text);
-//         let mut res_data = ResponseData::new("".to_string(), "".to_string(), "success".to_string(), "".to_string());
-//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-//         if json_value.get("event").is_some() {//订阅返回
-//             if json_value["event"].as_str() == Option::from("login") &&
-//                 json_value["code"].as_str() == Option::from("0") {
-//                 res_data.code = "-200".to_string();
-//                 res_data.message = format!("登录成功!");
-//             } else if json_value["event"].as_str() == Option::from("error") {
-//                 res_data.code = json_value["code"].to_string();
-//                 res_data.message = format!("订阅失败:{}", json_value["msg"].to_string());
-//             } else if json_value["event"].as_str() == Option::from("subscribe") {
-//                 res_data.code = "-201".to_string();
-//                 res_data.data = text;
-//                 res_data.message = format!("订阅成功!");
-//             }
-//         } else {
-//             if json_value.get("arg").is_some() && json_value.get("data").is_some() {
-//                 res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-//                 res_data.data = json_value["data"].to_string();
-//                 res_data.code = "200".to_string();
-//                 // res_data.reach_time = json_value["data"][0]["ts"].as_str().unwrap().parse().unwrap()
-//             } else {
-//                 res_data.data = text;
-//                 res_data.channel = "未知频道".to_string();
-//             }
-//         }
-//         res_data
-//     }
-// }

+ 0 - 94
exchanges/tests/binance_spot_test.rs

@@ -1,94 +0,0 @@
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// use std::time::Duration;
-// use futures_util::StreamExt;
-//
-// use tokio::sync::Mutex;
-// use tokio_tungstenite::tungstenite::Message;
-// use tracing::trace;
-//
-// use exchanges::binance_spot_ws::{BinanceSpotLogin, BinanceSpotSubscribeType, BinanceSpotWs, BinanceSpotWsType};
-// use exchanges::socket_tool::AbstractWsMode;
-//
-// // 账号密码
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-//
-//
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-// async fn ws_custom_subscribe() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//     let login_param = BinanceSpotLogin {
-//         api_key: ACCESS_KEY.to_string(),
-//         api_secret: SECRET_KEY.to_string(),
-//     };
-//     let mut ws = get_ws(None);
-//     ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         // BinanceSpotSubscribeType::PuBookTicker,
-//         // BinanceSpotSubscribeType::PuAggTrade,
-//         BinanceSpotSubscribeType::PuDepth20levels100ms,
-//     ]);
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-//
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-// fn get_ws(login_param: Option<BinanceSpotLogin>) -> BinanceSpotWs {
-//     let binance_ws = BinanceSpotWs::new(false,
-//                                         login_param, BinanceSpotWsType::PublicAndPrivate,
-//     );
-//     binance_ws
-// }
-//

+ 0 - 246
exchanges/tests/binance_swap_test.rs

@@ -1,246 +0,0 @@
-// use std::cmp::max;
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-//
-// use tokio::sync::Mutex;
-// use tracing::{info, trace};
-//
-// use exchanges::binance_swap_rest::BinanceSwapRest;
-// use exchanges::binance_swap_ws::{BinanceSwapLogin, BinanceSwapSubscribeType, BinanceSwapWs, BinanceSwapWsType};
-// use exchanges::response_base::ResponseData;
-// use global::trace_stack::TraceStack;
-//
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-//
-//
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-// async fn ws_custom_subscribe() {
-//     global::log_utils::init_log_with_trace();
-//
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
-//
-//     // let (write_tx, write_rx) = tokio::sync::broadcast::channel::<Message>(10);
-//     // let (read_tx, mut read_rx) = tokio::sync::broadcast::channel::<ResponseData>(10);
-//
-//
-//     let mut ws = get_ws(None);
-//     ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         BinanceSwapSubscribeType::PuBookTicker,
-//         // BinanceSwapSubscribeType::PuAggTrade,
-//         // BinanceSwapSubscribeType::PuDepth20levels100ms,
-//     ]);
-//
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         let mut max_delay = 0i64;
-//         loop {
-//             // 从通道中接收并丢弃所有的消息,直到通道为空
-//             while let Ok(Some(data)) = read_rx.try_next() {
-//                 // 消息被忽略
-//                 let mut trace_stack = TraceStack::new(0, Instant::now());
-//                 trace_stack.on_before_unlock_core();
-//                 trace_stack.on_after_network(data.time);
-//
-//                 let delay = trace_stack.before_unlock_core - trace_stack.after_network;
-//                 max_delay = max(max_delay, delay);
-//                 info!("{}us, max={}us", delay, max_delay);
-//
-//                 // 从通道中接收并丢弃所有的消息,直到通道为空
-//                 while let Ok(Some(_)) = read_rx.try_next() {
-//                     // 消息被忽略
-//                 }
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-//
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-//
-//     //************************************
-//     //************************************
-//     //************************************
-//     //************************************
-//     //************************************
-//     //************************************
-//     //************************************
-//     //11 点31 分
-//
-//     // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//     // //创建读写通道
-//     // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//     // // 封装 write_tx 到 Arc 和 Mutex
-//     // let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     //
-//     // //对象
-//     // let mut ws = get_ws(None);
-//     // // 币对
-//     // ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     // //订阅
-//     // ws.set_subscribe(vec![
-//     //     BinanceSwapSubscribeType::PuBookTicker,
-//     //     BinanceSwapSubscribeType::PuAggTrade,
-//     //     BinanceSwapSubscribeType::PuDepth20levels100ms,
-//     // ]);
-//     //
-//     //
-//     // //模拟业务场景 开启链接
-//     // let is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone1 = Arc::clone(&write_tx_am);
-//     // let t1 = tokio::spawn(async move {
-//     //     ws.ws_connect_async(is_shutdown_arc_clone, write_tx_clone1, write_rx, &read_tx).await.unwrap();
-//     //     trace!("ws_connect_async 完成");
-//     // });
-//     //
-//     // //模拟业务场景 一直监听数据
-//     // let t2 = tokio::spawn(async move {
-//     //     loop {
-//     //         if let Some(data) = read_rx.next().await {
-//     //             trace!("读取数据data:{:?}",data)
-//     //         }
-//     //     }
-//     //     trace!("数据读取退出 完成");
-//     // });
-//     //
-//     //
-//     // //模拟用户主动写入数据
-//     // // let write_tx_clone2 = Arc::clone(&write_tx_am);
-//     // // let t3 = tokio::spawn(async move {
-//     // //     //模拟心跳
-//     // //     loop {
-//     // //         tokio::time::sleep(Duration::from_millis(5000)).await;
-//     // //         let mut write_tx_clone = write_tx_clone2.lock().unwrap();
-//     // //         match write_tx_clone.unbounded_send(Message::Pong(Vec::from("pong"))) {
-//     // //             Ok(_) => {
-//     // //                 trace!("发送心跳");
-//     // //                 continue;
-//     // //             }
-//     // //             Err(_) => {
-//     // //                 break;
-//     // //             }
-//     // //         }
-//     // //     }
-//     // //     trace!("主动推出 完成");
-//     // // });
-//     // // tokio::try_join!(y,y1,y2).unwrap();
-//     // tokio::try_join!(t1,t2).unwrap();
-//     // trace!("323123213");
-// }
-//
-// //rest-获取服务器时间
-// #[tokio::test]
-// async fn rest_get_server_time_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_server_time().await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-获取交易规则和交易对
-// #[tokio::test]
-// async fn rest_get_exchange_info_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_exchange_info().await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-账户信息
-// #[tokio::test]
-// async fn rest_get_account_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_account().await;
-//     trace!(?rep_data)
-// }
-//
-//
-// //rest-根据币对 撤销全部订单
-// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-// async fn rest_cancel_order_all_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//
-//     let rep_data1 = rest.get_server_time().await;
-//     trace!(?rep_data1);
-//
-//     trace!("开始时间:{:?}",chrono::Utc::now().timestamp_millis().to_string());
-//     let rep_data = rest.cancel_order_all("BTCUSDT".to_string()).await;
-//     trace!(?rep_data);
-//     trace!("结束时间:{:?}",chrono::Utc::now().timestamp_millis().to_string());
-// }
-//
-// //rest-账户成交历史
-// #[tokio::test]
-// async fn rest_get_user_trades_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_user_trades("BTCUSDT".to_string(), -1, -1, 500).await;
-//     trace!(?rep_data)
-// }
-//
-//
-// fn get_ws(btree_map: Option<BinanceSwapLogin>) -> BinanceSwapWs {
-//     let binance_ws = BinanceSwapWs::new(false,
-//                                         btree_map,
-//                                         BinanceSwapWsType::PublicAndPrivate);
-//     binance_ws
-// }
-//
-// fn get_rest() -> BinanceSwapRest {
-//     let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-//     btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//
-//     let ba_exc = BinanceSwapRest::new(false, btree_map);
-//     ba_exc
-// }

+ 0 - 515
exchanges/tests/bitget_spot_test.rs

@@ -1,515 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// 
-// use futures_util::StreamExt;
-// use tokio::sync::Mutex;
-// use tracing::trace;
-// 
-// use exchanges::bitget_spot_rest::BitgetSpotRest;
-// use exchanges::bitget_spot_ws::{BitgetSpotLogin, BitgetSpotSubscribeType, BitgetSpotWs, BitgetSpotWsType};
-// 
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-// const PASS_KEY: &str = "";
-// 
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-// async fn ws_custom_subscribe_pu() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-// 
-//     let  is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//     let mut ws = get_ws(None, BitgetSpotWsType::Public).await;
-//     ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         BitgetSpotSubscribeType::PuTicker,
-//         BitgetSpotSubscribeType::PuCandle1m,
-//         BitgetSpotSubscribeType::PuTrade,
-//         BitgetSpotSubscribeType::PuBooks5,
-//     ]);
-// 
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-// 
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-// 
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-// 
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-// 
-// //ws-订阅私有频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-// async fn ws_custom_subscribe_pr() {
-//     global::log_utils::init_log_with_trace();
-// 
-// 
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-// 
-//     let login_param = BitgetSpotLogin {
-//         api_key: ACCESS_KEY.to_string(),
-//         secret_key: SECRET_KEY.to_string(),
-//         passphrase_key: PASS_KEY.to_string(),
-//     };
-//     let mut ws = get_ws(None, BitgetSpotWsType::Private).await;
-//     ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         BitgetSpotSubscribeType::PuTicker,
-//         BitgetSpotSubscribeType::PuCandle1m,
-//         BitgetSpotSubscribeType::PuTrade,
-//         BitgetSpotSubscribeType::PuBooks5,
-//     ]);
-// 
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-// 
-// //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-// 
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-// 
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-// 
-// 
-// //rest-获取系统时间
-// #[tokio::test]
-// async fn rest_get_server_time_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_server_time().await;
-//     trace!(?rep_data)
-// }
-// 
-// 
-// //rest-获取账户信息
-// #[tokio::test]
-// async fn rest_get_account_info_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_account_info().await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取账户币种资产
-// #[tokio::test]
-// async fn rest_get_account_assets_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_account_assets().await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取币种信息
-// #[tokio::test]
-// async fn rest_get_coins_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_coins("USDT".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取交易对信息
-// #[tokio::test]
-// async fn rest_get_symbols_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_symbols("BTCUSDT".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取现货VIP费率
-// #[tokio::test]
-// async fn rest_get_vip_fee_rate_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_vip_fee_rate().await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取行情信息
-// #[tokio::test]
-// async fn rest_get_tickers_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_tickers("BTCUSDT".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取合并交易深度
-// #[tokio::test]
-// async fn rest_get_merge_depth_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_merge_depth("BTCUSDT".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取K线数据
-// #[tokio::test]
-// async fn rest_get_candles_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_candles("BTCUSDT".to_string(), "1min".to_string(), "1697701550192".to_string(), "1697701556192".to_string(), "100".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取历史K线数据
-// #[tokio::test]
-// async fn rest_get_history_candles_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_history_candles("BTCUSDT".to_string(), "1min".to_string(), "1697701556192".to_string(), "100".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取最近成交数据
-// #[tokio::test]
-// async fn rest_get_market_fills_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_market_fills("BTCUSDT".to_string(), "100".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取历史成交数据
-// #[tokio::test]
-// async fn rest_get_fills_history_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_market_fills_history("BTCUSDT".to_string(), "1697701550192".to_string(), "1697701556192".to_string(), "100".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-下单
-// #[tokio::test]
-// async fn rest_spot_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     //市价单
-//     let mut rest = get_rest();
-//     let params = serde_json::json!({
-//             // "symbol":"CELRUSDT",
-//             // "side":"sell",
-//             // "orderType":"market",
-//             // "force":"fok",
-//             // "size":"887",
-//             // "clientOid":"7d8zd4d_3",
-//          });
-// 
-//     //限价单
-//     let params = serde_json::json!({
-//             // "symbol":"CELRUSDT",
-//             // "side":"buy",
-//             // "orderType":"limit",
-//             // "force":"gtc",
-//             // "price":"0.01001",
-//             // "size":"10",
-//             // "clientOid":"7d8zd4d_z1",
-//          });
-// 
-//     let rep_data = rest.spot_order(params).await;
-//     trace!(?rep_data)
-// }
-// 
-// 
-// //rest-撤单
-// #[tokio::test]
-// async fn rest_spot_cancel_order_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.spot_cancel_order("CELRUSDT".to_string(), "".to_string(), "1".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-批量撤单
-// #[tokio::test]
-// async fn rest_spot_cancel_orders_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let v = serde_json::json!({
-//             "orderId":"1073370944162058240",
-//             "clientOid":"1073370944162058240"
-//         });
-//     let rep_data = rest.spot_cancel_orders("CELRUSDT".to_string(), vec![v]).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-按币对撤单
-// #[tokio::test]
-// async fn rest_spot_cancel_symbol_orders_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.spot_cancel_symbol_orders("CELRUSDT".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取订单详情
-// #[tokio::test]
-// async fn rest_get_order_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_order("".to_string(), "1".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取当前委托列表
-// #[tokio::test]
-// async fn rest_get_unfilled_orders_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_unfilled_orders("CELRUSDT".to_string(),
-//                                             "".to_string(),
-//                                             "".to_string(),
-//                                             "".to_string(),
-//                                             "".to_string(),
-//                                             "".to_string(),
-//     ).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取历史委托列表
-// #[tokio::test]
-// async fn rest_get_history_orders_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_history_orders("CELRUSDT".to_string(),
-//                                            "".to_string(),
-//                                            "".to_string(),
-//                                            "".to_string(),
-//                                            "".to_string(),
-//                                            "".to_string(),
-//     ).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取成交明细
-// #[tokio::test]
-// async fn rest_get_fills_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_fills("CELRUSDT".to_string(),
-//                                   "1".to_string(),
-//                                   "".to_string(),
-//                                   "".to_string(),
-//                                   "".to_string(),
-//                                   "".to_string(),
-//     ).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取成交明细
-// #[tokio::test]
-// async fn rest_spot_place_plan_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     //限价-委托单
-//     let params = serde_json::json!({
-//          });
-// 
-//     let rep_data = rest.spot_place_plan_order(params).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-修改计划委托
-// #[tokio::test]
-// async fn rest_update_place_plan_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     //限价-委托单
-//     let params = serde_json::json!({
-//          });
-// 
-//     let rep_data = rest.update_place_plan_order(params).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-撤销计划委托
-// #[tokio::test]
-// async fn rest_cancel_plan_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.cancel_plan_order("32131".to_string(), "3211".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取当前计划委托
-// #[tokio::test]
-// async fn rest_get_current_plan_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_current_plan_order("CELRUSDT".to_string(),
-//                                                "1".to_string(),
-//                                                "".to_string(),
-//                                                "".to_string(),
-//                                                "".to_string(),
-//     ).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取历史计划委托
-// #[tokio::test]
-// async fn rest_get_history_plan_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_history_plan_order("CELRUSDT".to_string(),
-//                                                "1697701550192".to_string(),
-//                                                "1697701580192".to_string(),
-//                                                "100".to_string(),
-//     ).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-批量撤销计划委托
-// #[tokio::test]
-// async fn rest_cancel_plan_orders_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut rest = get_rest();
-//     let rep_data = rest.cancel_plan_orders(vec![]).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-划转
-// #[tokio::test]
-// async fn rest_wallet_transfer_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.wallet_transfer("".to_string(),
-//                                         "".to_string(),
-//                                         "".to_string(),
-//                                         "".to_string(),
-//                                         "".to_string(),
-//                                         "".to_string()).await;
-//     trace!(?rep_data)
-// }
-// 
-// //rest-获取账单流水
-// #[tokio::test]
-// async fn rest_get_account_bills_test() {
-//     global::log_utils::init_log_with_trace();
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_account_bills("".to_string(),
-//                                           "".to_string(),
-//                                           "".to_string(),
-//                                           "".to_string(), ).await;
-//     trace!(?rep_data)
-// }
-// 
-// 
-// async fn get_ws(btree_map: Option<BitgetSpotLogin>, type_v: BitgetSpotWsType) -> BitgetSpotWs {
-//     let mut ku_ws = BitgetSpotWs::new(false, btree_map.clone(), type_v);
-//     ku_ws
-// }
-// 
-// fn get_rest() -> BitgetSpotRest {
-//     let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-//     // btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     // btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//     btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//     btree_map.insert("pass_key".to_string(), PASS_KEY.to_string());
-// 
-//     let mut ku_exc = BitgetSpotRest::new(false, btree_map);
-//     ku_exc
-// }

+ 0 - 145
exchanges/tests/bitget_swap_test.rs

@@ -1,145 +0,0 @@
-use std::collections::BTreeMap;
-use serde_json::json;
-use tracing::{info};
-use exchanges::bitget_swap_rest::BitgetSwapRest;
-
-const ACCESS_KEY: &str = "";
-const SECRET_KEY: &str = "";
-const PASS_KEY: &str = "";
-
-// 测试账户信息获取
-#[tokio::test]
-async fn rest_get_account_info_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-    let rep_data = rest.get_account_info().await;
-    info!(?rep_data)
-}
-
-// 下单测试
-#[tokio::test]
-async fn post_order_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-    let params = json!({
-        "symbol": "BTCUSDT",
-        "productType": "USDT-FUTURES",
-        "marginMode": "crossed",
-        "marginCoin": "USDT",
-        "size": "0.001",
-        "side": "buy",
-        "tradeSide": "close",
-        "orderType": "market",
-        "clientOid": "1130615113245"
-    });
-    let response = rest.swap_order(params).await;
-
-    info!(?response)
-}
-
-// 撤单测试
-#[tokio::test]
-async fn cancel_order_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-    let params = json!({
-        "symbol": "ethusdt",
-        "productType": "USDT-FUTURES",
-        "clientOid": "1130615111",
-    });
-    let response = rest.cancel_order(params).await;
-
-    info!(?response)
-}
-
-// 获取订单详情测试
-#[tokio::test]
-async fn get_order_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-    let params = json!({
-        "symbol": "ETHUSDT",
-        "productType": "USDT-FUTURES",
-        "clientOid": "1130615132",
-    });
-    let response = rest.get_order(params).await;
-
-    info!(?response)
-}
-
-// 获取当前的pending订单
-#[tokio::test]
-async fn get_pending_orders_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-    let response = rest.get_pending_orders().await;
-
-    info!(?response)
-}
-
-// 设置杠杆测试
-#[tokio::test]
-async fn set_leverage_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-
-
-    let params = json!({
-        "symbol": "ETHUSDT",
-        "productType": "USDT-FUTURES",
-        "marginCoin": "USDT",
-        "leverage": "5"
-    });
-    let response = rest.set_leverage(params).await;
-
-    info!(?response)
-}
-
-// 设置持仓模式
-#[tokio::test]
-async fn set_position_mode_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-
-
-    let params = json!({
-        "productType": "USDT-FUTURES",
-        "posMode": "hedge_mode",
-    });
-    let response = rest.set_position_mode(params).await;
-
-    info!(?response)
-}
-
-// 获取仓位信息
-#[tokio::test]
-async fn get_single_position_test() {
-    global::log_utils::init_log_with_info();
-
-    let mut rest = get_rest();
-    let params = json!({
-        "productType": "USDT-FUTURES",
-        "symbol": "ETHUSDT",
-        "marginCoin": "USDT"
-    });
-    let response = rest.get_single_position(params).await;
-
-    info!(?response)
-}
-
-fn get_rest() -> BitgetSwapRest {
-    let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-
-    btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-    btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-    btree_map.insert("pass_key".to_string(), PASS_KEY.to_string());
-
-    BitgetSwapRest::new(false, btree_map)
-}

+ 0 - 320
exchanges/tests/bybit_swap_test.rs

@@ -1,320 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// use futures_util::StreamExt;
-// use tokio::sync::Mutex;
-// use tracing::trace;
-//
-// use exchanges::bybit_swap_rest::BybitSwapRest;
-// use exchanges::bybit_swap_ws::{BybitSwapLogin, BybitSwapSubscribeType, BybitSwapWs, BybitSwapWsType};
-//
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-//
-//
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_custom_subscribe_pu() {
-//     global::log_utils::init_log_with_trace();
-//
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//
-//     let mut ws = get_ws(None, BybitSwapWsType::Public).await;
-//     ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         // BybitSwapSubscribeType::PuOrderBook1,
-//         // BybitSwapSubscribeType::PuOrderBook50,
-//         // BybitSwapSubscribeType::PuBlicTrade,
-//         BybitSwapSubscribeType::PuTickers,
-//     ]);
-//
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-//
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-//
-// //ws-订阅私有频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_custom_subscribe_pr() {
-//     global::log_utils::init_log_with_trace();
-//
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//     let logparam = BybitSwapLogin {
-//         api_key: ACCESS_KEY.to_string(),
-//         secret_key: SECRET_KEY.to_string(),
-//     };
-//
-//     let mut ws = get_ws(Option::from(logparam), BybitSwapWsType::Private).await;
-//     ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         BybitSwapSubscribeType::PrPosition,
-//         // BybitSwapSubscribeType::PrExecution,
-//         // BybitSwapSubscribeType::PrOrder,
-//         // BybitSwapSubscribeType::PrWallet,
-//     ]);
-//
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-//
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-//
-// //rest-服務器時間
-// #[tokio::test]
-// async fn rest_get_server_time_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_server_time().await;
-//     println!("Bybit--服務器時間--{:?}", req_data);
-// }
-//
-// //rest-查詢最新行情信息
-// #[tokio::test]
-// async fn rest_get_tickers_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_tickers("DOGEUSDT".to_string()).await;
-//     println!("Bybit--查詢最新行情信息--{:?}", req_data);
-// }
-//
-// //rest-查詢市場價格K線數據
-// #[tokio::test]
-// async fn rest_get_kline_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_kline("DOGEUSDT".to_string()).await;
-//     println!("Bybit--查詢市場價格K線數據--{:?}", req_data);
-// }
-//
-//
-// //rest-查詢公告
-// #[tokio::test]
-// async fn rest_get_announcements_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_announcements().await;
-//     println!("Bybit--查詢公告--{:?}", req_data);
-// }
-//
-// //rest-查詢可交易產品的規格信息
-// #[tokio::test]
-// async fn rest_get_instruments_info_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_instruments_info("BTCUSDT".to_string()).await;
-//     println!("Bybit--查詢可交易產品的規格信息--{:?}", req_data);
-// }
-//
-//
-// //rest-查詢錢包餘額
-// #[tokio::test]
-// async fn rest_get_account_balance_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_account_balance("USDT".to_string()).await;
-//     println!("Bybit--查詢錢包餘額--{:?}", req_data);
-// }
-//
-// //rest-查看持仓信息
-// #[tokio::test]
-// async fn rest_get_positions_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_positions("DOGEUSDT".to_string(), "".to_string()).await;
-//     println!("Bybit--查看持仓信息--{:?}", req_data);
-// }
-//
-// //rest-设置持仓模式
-// #[tokio::test]
-// async fn rest_set_position_mode_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.set_position_mode("DOGEUSDT".to_string(), 3).await;
-//     println!("Bybit--设置持仓模式--{:?}", req_data);
-// }
-//
-// //rest-設置槓桿
-// #[tokio::test]
-// async fn rest_set_leverage_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.set_leverage(
-//         "DOGEUSDT".to_string(), "1".to_string()).await;
-//     println!("Bybit--設置槓桿--{:?}", req_data);
-// }
-//
-//
-// //rest-創建委託單
-// #[tokio::test]
-// async fn rest_swap_order_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let params = serde_json::json!({
-//             "category":"linear",
-//             "symbol":"DOGEUSDT",
-//             "orderType":"Limit",
-//             "side":"Buy",
-//             "qty":"1",
-//             "price":"0.085",
-//          });
-//     let req_data = ret.swap_order(params).await;
-//     println!("Bybit--創建委託單--{:?}", req_data);
-// }
-//
-//
-// //rest-查詢實時委託單
-// #[tokio::test]
-// async fn rest_get_order_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.get_order("LINKUSDT".to_string(),
-//                                  "".to_string(), "".to_string()).await;
-//     println!("Bybit--查詢實時委託單--{:?}", req_data);
-// }
-//
-//
-// //rest-撤单
-// #[tokio::test]
-// async fn rest_cancel_order_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.cancel_order("DOGEUSDT".to_string(),
-//                                     "1d3ea16f-cf1c-4dab-9a79-d441a2dea549".to_string(), "".to_string()).await;
-//     println!("Bybit--撤单--{:?}", req_data);
-// }
-//
-// //rest-撤銷所有訂單
-// #[tokio::test]
-// async fn rest_cancel_orders_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut ret = get_rest();
-//     let req_data = ret.cancel_orders("DOGEUSDT".to_string()).await;
-//     println!("Bybit--撤銷所有訂單--{:?}", req_data);
-// }
-//
-//
-// async fn get_ws(btree_map: Option<BybitSwapLogin>, type_v: BybitSwapWsType) -> BybitSwapWs {
-//     let ku_ws = BybitSwapWs::new(false, btree_map, type_v);
-//     ku_ws
-// }
-//
-// fn get_rest() -> BybitSwapRest {
-//     let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-//     btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//
-//     let bybit_exc = BybitSwapRest::new(false, btree_map.clone());
-//     bybit_exc
-// }

+ 0 - 383
exchanges/tests/coinex_swap_test.rs

@@ -1,383 +0,0 @@
-use std::collections::BTreeMap;
-use std::str::FromStr;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use rust_decimal::Decimal;
-use serde_json::Value;
-use tokio::sync::Mutex;
-use tracing::{error, info, trace};
-use exchanges::coinex_swap_rest::CoinexSwapRest;
-use exchanges::coinex_swap_ws::{CoinexSwapLogin, CoinexSwapSubscribeType, CoinexSwapWs};
-use exchanges::response_base::ResponseData;
-use global::log_utils::{init_log_with_info, init_log_with_trace};
-
-
-const ACCESS_KEY: &str = "";
-const SECRET_KEY: &str = "";
-
-
-//ws-订阅公共频道信息
-#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-async fn ws_custom_subscribe() {
-    global::log_utils::init_log_with_trace();
-
-    let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-    let (_read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
-
-    // let (write_tx, write_rx) = tokio::sync::broadcast::channel::<Message>(10);
-    // let (read_tx, mut read_rx) = tokio::sync::broadcast::channel::<ResponseData>(10);
-
-
-    let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-
-    //读取
-    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-    let _tr = tokio::spawn(async move {
-        trace!("线程-数据读取-开启");
-        loop {
-            // 从通道中接收并丢弃所有的消息,直到通道为空
-            while let Ok(Some(_data)) = read_rx.try_next() {
-
-                // 从通道中接收并丢弃所有的消息,直到通道为空
-                while let Ok(Some(_)) = read_rx.try_next() {
-                    // 消息被忽略
-                }
-            }
-        }
-        // trace!("线程-数据读取-结束");
-    });
-
-    //写数据
-    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-    // let write_tx_clone = Arc::clone(&write_tx_am);
-    // let su = ws.get_subscription();
-    // let tw = tokio::spawn(async move {
-    //     trace!("线程-数据写入-开始");
-    //     loop {
-    //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-    //         // let close_frame = CloseFrame {
-    //         //     code: CloseCode::Normal,
-    //         //     reason: Cow::Borrowed("Bye bye"),
-    //         // };
-    //         // let message = Message::Close(Some(close_frame));
-    //
-    //
-    //         let message = Message::Text(su.clone());
-    //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-    //         trace!("发送指令成功");
-    //     }
-    //     trace!("线程-数据写入-结束");
-    // });
-
-    let fun = move |data: ResponseData| {
-        async move {
-            println!("{:?}", data);
-        }
-    };
-    let param = CoinexSwapLogin {
-        api_key: ACCESS_KEY.to_string(),
-        secret: SECRET_KEY.to_string(),
-    };
-    let t1 = tokio::spawn(async move {
-        let mut ws = get_ws(Option::from(param));
-        ws.set_symbols(vec!["FTM_USDT".to_string()]);
-        ws.set_subscribe(vec![
-            // CoinexSwapSubscribeType::PuFuturesDepth,
-            CoinexSwapSubscribeType::PrFuturesOrders
-        ]);
-        //链接
-        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-        ws.ws_connect_async(bool_v3_clone, fun, &write_tx_am, write_rx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-        trace!("test 唯一线程结束--");
-    });
-    tokio::try_join!(t1).unwrap();
-    trace!("当此结束");
-    trace!("重启!");
-    trace!("参考交易所关闭");
-    return;
-}
-
-fn get_ws(btree_map: Option<CoinexSwapLogin>) -> CoinexSwapWs {
-    let coinex_ws = CoinexSwapWs::new(btree_map);
-    coinex_ws
-}
-
-#[tokio::test]
-async fn rest_account_book_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_account().await;
-    let res_data_json: Value = req_data.data;
-    println!("coinex--查询合约账户--{:?}", res_data_json);
-    let result = res_data_json.as_array().unwrap().get(0).unwrap();
-    println!("coinex--查询合约账户--{:?}", result["ccy"]);
-}
-
-#[tokio::test]
-async fn rest_spot_account_book_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_spot_account().await;
-    let res_data_json: Value = req_data.data;
-    println!("coinex--查询现货账户--{:?}", res_data_json);
-    let result = res_data_json.as_array().unwrap().get(0).unwrap();
-    println!("coinex--查询现货账户--{:?}", result["ccy"]);
-}
-
-#[tokio::test]
-async fn rest_position_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_position("BOMEUSDT".to_string()).await;
-    println!("coinex--查询仓位--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_positions_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_user_position().await;
-    println!("coinex--查询用户所有仓位--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_ticker_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_ticker("BOMEUSDT".to_string()).await;
-    println!("coinex--查询ticker--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_market_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_market_details("BOMEUSDT".to_string()).await;
-    println!("coinex--查询market--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_market_list_test() {
-    let symbol = "DOGEUSDT".to_string();
-    let price = Decimal::from_str("0.15").unwrap();
-    let custom_id = "436265461";
-    let order_side;
-    let position_side;
-    let amount = Decimal::from_str("1769").unwrap();
-    let ct_val = Decimal::from_str("1").unwrap();
-    let origin_side = "kk";
-    let size = (amount / ct_val).floor();
-    match origin_side {
-        "kd" => {
-            position_side = "long";
-            order_side = "buy";
-        }
-        "pd" => {
-            position_side = "long";
-            order_side = "sell";
-        }
-        "kk" => {
-            position_side = "short";
-            order_side = "sell";
-        }
-        "pk" => {
-            position_side = "short";
-            order_side = "buy";
-        }
-        _ => {
-            error!("下单参数错误");
-            position_side = "error";
-            order_side = "error";
-        }
-    };
-    let mut ret = get_rest();
-    let req_data = ret.order(symbol, position_side.to_string(), order_side.to_string(), size, price, custom_id.to_string()).await;
-    println!("coinex--查询swap_order--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_cancel_order_test() {
-    let mut ret = get_rest();
-    let req_data = ret.cancel_order("DOGEUSDT".to_string(), "", "436265461").await;
-
-    println!("coinex--查询cancel_order--{} {:?}", req_data.data.is_null(), req_data);
-}
-
-#[tokio::test]
-async fn rest_cancel_all_order_test() {
-    let mut ret = get_rest();
-    let _ct_val = Decimal::ONE;
-    let orders_res_data = ret.get_pending_orders().await;
-    let mut result = vec![];
-    if orders_res_data.code == 200 {
-        let orders_res_data_json = orders_res_data.data.as_array().unwrap();
-        for order in orders_res_data_json {
-            let cancel_res_data = ret.cancel_order_all(order["market"].as_str().unwrap().to_string()).await;
-            if cancel_res_data.code == 200 {
-                result.push(order.clone())
-            }
-        }
-    }
-    println!("coinex--查询cancel_all_order--{:?}", result);
-}
-
-#[tokio::test]
-async fn rest_finish_order_list_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_finished_orders().await;
-    println!("coinex--查询finish_order--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_pending_order_list_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_pending_orders().await;
-    println!("coinex--查询pending_order--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_order_status_test() {
-    let mut ret = get_rest();
-    let req_data = ret.get_order_details("136925916412".to_string(), "DOGEUSDT".to_string()).await;
-    println!("coinex--查询pending_order--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_setting_dual_leverage_test() {
-    let mut ret = get_rest();
-    let req_data = ret.setting_dual_leverage("FTMUSDT".to_string(), 10).await;
-    println!("coinex--查询setting_dual_leverage--{:?}", req_data);
-}
-
-#[tokio::test]
-async fn rest_time() {
-    let mut ret = get_rest();
-    let res_data = ret.get_server_time().await;
-    let res_data_json: Value = res_data.data;
-    let result = res_data_json["timestamp"].to_string();
-    println!("coinex--time--{:?}", result);
-}
-
-#[tokio::test]
-async fn rest_account_get_test() {
-    let mut ret = get_rest();
-    let res_data = ret.account_get().await;
-    let res_data_json: Value = res_data.data;
-    if res_data_json.is_array() {
-        let array = res_data_json.as_array().unwrap();
-        for z in array {
-            trace!("coinex--查看子账号列表--{:?}", z);
-        }
-    }
-}
-
-#[tokio::test]
-async fn rest_account_subs_api_test() {
-    let mut ret = get_rest();
-    let params = serde_json::json!({
-            "sub_user_name":"2024050",
-            "ip_whitelist":[],
-            "trade_enabled":false,
-            "remark":"",
-        });
-    let res_data = ret.account_subs_api(params).await;
-    // let res_data_json: Value = res_data.data;
-    // let result = res_data_json["timestamp"].to_string();
-    println!("coinex--获取子账号的apikey--{:?}", res_data);
-}
-
-// 将主账号下的  子账号 都创建apikey
-#[tokio::test]
-async fn rest_account_get_and_api_test() {
-    let mut ret = get_rest();
-    let res_data = ret.account_get().await;
-    let res_data_json: Value = res_data.data;
-    if res_data_json.is_array() {
-        let array = res_data_json.as_array().unwrap();
-        for z in array {
-            let sub_user_name = z["sub_user_name"].as_str().unwrap();
-            info!("coinex--查看子账号列表--{:?}", z);
-
-
-            // //每个账号创建apiKey
-            // let params2 = serde_json::json!({
-            //     "sub_user_name":sub_user_name,
-            //     "ip_whitelist":[],
-            //     "trade_enabled":false,
-            //     "remark":"",
-            // });
-            // let res_data2 = ret.account_subs_api(params2).await;
-            // // info!("coinex--创建成功响应--{:?}", res_data2);
-            // let res_data_json2: Value = res_data2.data;
-            // let api_id = res_data_json2["api_id"].as_i64().unwrap();
-            // let access_id = res_data_json2["access_id"].as_str().unwrap();
-            // let secret_key = res_data_json2["secret_key"].as_str().unwrap();
-            // info!("sub_user_name:{:?} \tapi_id:{:?} \t access_id:{:?}\t secret_key:{:?}",sub_user_name,api_id,access_id,secret_key);
-
-        }
-    }
-}
-
-// 获取子账号 APIKEY 列表
-#[tokio::test]
-async fn rest_account_get_apikey_test() {
-    let str = "api_id access_id secret_key";
-    let mut ret = get_rest();
-    let res_data = ret.account_get().await;
-    let res_data_json: Value = res_data.data;
-    if res_data_json.is_array() {
-        let array = res_data_json.as_array().unwrap();
-        for z in array {
-            let sub_user_name = z["sub_user_name"].as_str().unwrap();
-            info!("coinex--查看子账号列表--{:?}", sub_user_name);
-
-            //每个账号创建apiKey
-            let params = serde_json::json!({
-                "sub_user_name":sub_user_name,
-            });
-            let res_data2 = ret.account_get_apikey(params).await;
-            // trace!("coinex--获取子账号的apikey--{:?}", res_data2);
-            let res_data_json2: Value = res_data2.data;
-            if res_data_json2.is_array() {
-                let array2 = res_data_json2.as_array().unwrap();
-                for z2 in array2 {
-                    let api_id = z2["api_id"].as_i64().unwrap();
-                    let access_id = z2["access_id"].as_str().unwrap();
-                    info!("sub_user_name:{:?} \tapi_id:{:?} \t access_id:{:?}\t ",sub_user_name,api_id,access_id);
-
-                    //查询详情
-                    let params3 = serde_json::json!({
-                       "api_id":api_id
-                    });
-                    let res_data3 = ret.account_get_detail(params3).await;
-                    info!("coinex--详情--{:?}", res_data3.data);
-
-                    //编辑子账号 APIKEY
-                    // let params4 = serde_json::json!({
-                    //     "sub_user_name":sub_user_name,
-                    //     "api_id":api_id,
-                    //     "trade_enabled":true
-                    // });
-                    // let res_data4 = ret.account_get_update(params4).await;
-                    // info!("coinex--编辑结果--{:?}", res_data4.data);
-
-
-                    //删除
-                    // let params2 = serde_json::json!({
-                    //     "api_id":api_id
-                    // });
-                    // let res_data23 = ret.account_del_apikey(params2).await;
-                    // info!("coinex--删除结果--{:?}", res_data23);
-                }
-            }
-        }
-    }
-    // info!("sub_user_name:{:?} \tapi_id:{:?} \t access_id:{:?}\t ",sub_user_name,api_id,access_id)
-}
-
-
-fn get_rest() -> CoinexSwapRest {
-    // init_log_with_trace();
-    init_log_with_info();
-    let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-    btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-    btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-
-    let ba_exc = CoinexSwapRest::new(btree_map);
-    ba_exc
-}

+ 0 - 86
exchanges/tests/crypto_spot_test.rs

@@ -1,86 +0,0 @@
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-//
-// use futures_util::StreamExt;
-// use tokio::sync::Mutex;
-// use tracing::trace;
-//
-// use exchanges::crypto_spot_ws::{CryptoSpotLogin, CryptoSpotSubscribeType, CryptoSpotWs, CryptoSpotWsType};
-//
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-//
-//
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_pu() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//     let mut ws = get_ws(None, CryptoSpotWsType::Public);
-//     ws.set_symbols(vec!["BTC_USD".to_string()]);
-//     ws.set_subscribe(vec![
-//         // CryptoSpotSubscribeType::PuBook,
-//         // CryptoSpotSubscribeType::PuTicker,
-//         // CryptoSpotSubscribeType::PuTrade,
-//         CryptoSpotSubscribeType::PuCandlestick,
-//     ]);
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-//
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-// fn get_ws(btree_map: Option<CryptoSpotLogin>, ws_type: CryptoSpotWsType) -> CryptoSpotWs {
-//     let binance_ws = CryptoSpotWs::new(false,
-//                                        btree_map,
-//                                        ws_type);
-//     binance_ws
-// }

+ 0 - 314
exchanges/tests/htx_swap_test.rs

@@ -1,314 +0,0 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-
-use serde_json::json;
-use tokio::sync::Mutex;
-use tracing::trace;
-
-use exchanges::htx_swap_rest::HtxSwapRest;
-use exchanges::htx_swap_ws::{HtxSwapLogin, HtxSwapSubscribeType, HtxSwapWs, HtxSwapWsType};
-use exchanges::proxy;
-use exchanges::response_base::ResponseData;
-
-const ACCESS_KEY: &str = "";
-const SECRET_KEY: &str = "";
-
-
-//ws-订阅公共频道信息
-#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-async fn ws_custom_subscribe() {
-    global::log_utils::init_log_with_trace();
-
-    let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-    let (_, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
-
-    // let (write_tx, write_rx) = tokio::sync::broadcast::channel::<Message>(10);
-    // let (read_tx, mut read_rx) = tokio::sync::broadcast::channel::<ResponseData>(10);
-
-
-    let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-
-    //读取
-    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-    let _tr = tokio::spawn(async move {
-        trace!("线程-数据读取-开启");
-        loop {
-            // 从通道中接收并丢弃所有的消息,直到通道为空
-            while let Ok(Some(_)) = read_rx.try_next() {
-
-                // 从通道中接收并丢弃所有的消息,直到通道为空
-                while let Ok(Some(_)) = read_rx.try_next() {
-                    // 消息被忽略
-                }
-            }
-        }
-        // trace!("线程-数据读取-结束");
-    });
-
-    //写数据
-    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-    // let write_tx_clone = Arc::clone(&write_tx_am);
-    // let su = ws.get_subscription();
-    // let tw = tokio::spawn(async move {
-    //     trace!("线程-数据写入-开始");
-    //     loop {
-    //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-    //         // let close_frame = CloseFrame {
-    //         //     code: CloseCode::Normal,
-    //         //     reason: Cow::Borrowed("Bye bye"),
-    //         // };
-    //         // let message = Message::Close(Some(close_frame));
-    //
-    //
-    //         let message = Message::Text(su.clone());
-    //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-    //         trace!("发送指令成功");
-    //     }
-    //     trace!("线程-数据写入-结束");
-    // });
-
-    let fun = move |data: ResponseData| {
-        async move {
-            trace!("---传入的方法~~~~{:?}", data);
-        }
-    };
-    let param = HtxSwapLogin {
-        api_key: ACCESS_KEY.to_string(),
-        secret: SECRET_KEY.to_string(),
-    };
-    let t1 = tokio::spawn(async move {
-        let mut ws = get_ws(Option::from(param), HtxSwapWsType::Public);
-        ws.set_symbols(vec!["BTC_USDT".to_string(),"ETC_USDT".to_string()]);
-        ws.set_subscribe(vec![
-            HtxSwapSubscribeType::PuFuturesDepth,
-            // HtxSwapSubscribeType::PrFuturesOrders
-
-            // HtxSwapSubscribeType::PrFuturesOrders,
-            // HtxSwapSubscribeType::PrFuturesPositions,
-            // HtxSwapSubscribeType::PrFuturesBalances,
-        ]);
-        //链接
-        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-        ws.ws_connect_async(bool_v3_clone, fun, &write_tx_am, write_rx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-        trace!("test 唯一线程结束--");
-    });
-    tokio::try_join!(t1).unwrap();
-    trace!("当此结束");
-    trace!("重启!");
-    trace!("参考交易所关闭");
-    return;
-}
-
-fn get_ws(btree_map: Option<HtxSwapLogin>, ws_type: HtxSwapWsType) -> HtxSwapWs {
-    let htx_ws = HtxSwapWs::new(btree_map, ws_type);
-    htx_ws
-}
-
-
-/*服务器时间戳*/
-#[tokio::test]
-async fn rest_get_server_time_test() {
-    global::log_utils::init_log_with_trace();
-    proxy_handle();
-
-    let mut ret = get_rest();
-    let req_data = ret.get_server_time().await;
-    trace!("htx--服务器时间戳--{:?}", req_data);
-    trace!("htx--服务器时间戳--{}", req_data.data);
-}
-
-
-/*获取聚合行情*/
-#[tokio::test]
-async fn rest_get_ticker_test() {
-    global::log_utils::init_log_with_trace();
-    proxy_handle();
-
-    let mut ret = get_rest();
-    let req_data = ret.get_ticker(json!({
-            "contract_type":"swap"
-         })
-    ).await;
-    trace!("htx--获取聚合行情--{:?}", req_data);
-    trace!("htx--获取聚合行情--{}", req_data.data);
-}
-
-
-
-/*合约信息*/
-#[tokio::test]
-async fn rest_get_market_test() {
-    global::log_utils::init_log_with_trace();
-    proxy_handle();
-
-    let mut ret = get_rest();
-    let req_data = ret.get_market(json!({
-            "contract_code":"BTC-USDT"
-         })
-    ).await;
-    trace!("htx--合约信息--{:?}", req_data);
-    trace!("htx--合约信息--{}", req_data.data);
-}
-
-
-/*查询合约账户*/
-#[tokio::test]
-async fn rest_get_account_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-    let req_data = ret.get_account(json!({
-            "valuation_asset":"USDT"
-         })
-    ).await;
-    trace!("htx--查询合约账户--{:?}", req_data);
-    trace!("htx--查询合约账户--{}", req_data.data);
-}
-
-/*用户仓位列表*/
-#[tokio::test]
-async fn rest_get_user_position_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-    let req_data = ret.get_user_position(
-   serde_json::json!({
-            "contract_type":"swap"
-         })
-    ).await;
-    trace!("htx--用户仓位列表--{:?}", req_data);
-    trace!("htx--用户仓位列表--{}", req_data.data);
-}
-
-/*查询合约订单列表*/
-#[tokio::test]
-async fn rest_get_orders_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-    let req_data = ret.get_orders(json!({
-    })).await;
-    trace!("htx--查询合约订单列表--{:?}", req_data);
-    trace!("htx--查询合约订单列表--{}", req_data.data);
-}
-
-/*查询单个订单详情*/
-#[tokio::test]
-async fn rest_get_order_details_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-    let req_data = ret.get_order_details(json!({
-        "order_id":"123"
-    })).await;
-    trace!("htx--查询单个订单详情--{:?}", req_data);
-    trace!("htx--查询单个订单详情--{}", req_data.data);
-}
-/*合约交易下单*/
-#[tokio::test]
-async fn rest_swap_order_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-
-    let req_data = ret.swap_order(json!({
-        "pair":"SHIB-USDT",
-        "contract_type":"swap",
-        "order_price_type":"limit",
-        "offset":"open",
-        "direction":"buy",
-        "price":"0.000001359",
-        "volume":1,
-        "lever_rate":1,
-
-    })).await;
-    trace!("htx--合约交易下单--{:?}", req_data);
-    trace!("htx--合约交易下单--{}", req_data.data);
-}
-
-/*全部撤单*/
-#[tokio::test]
-async fn rest_cancel_price_order_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-
-    let req_data = ret.cancel_price_order(json!({  })).await;
-    trace!("htx--全部撤单--{:?}", req_data);
-    trace!("htx--全部撤单--{}", req_data.data);
-}
-
-/*撤单*/
-#[tokio::test]
-async fn rest_cancel_order_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-
-    let req_data = ret.cancel_order(json!({
-        "order_id":"123"
-    })).await;
-    trace!("htx--撤单--{:?}", req_data);
-    trace!("htx--撤单--{}", req_data.data);
-}
-
-
-/*设置持仓模式*/
-#[tokio::test]
-async fn rest_setting_dual_mode_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-
-    let req_data = ret.setting_dual_mode(json!({
-        "margin_account":"USDT",
-        "position_mode":"dual_side",
-    })).await;
-    trace!("htx--设置持仓模式--{:?}", req_data);
-    trace!("htx--设置持仓模式--{}", req_data.data);
-}
-
-
-/*设置杠杆*/
-#[tokio::test]
-async fn rest_setting_dual_leverage_test() {
-    global::log_utils::init_log_with_trace();
-    // proxy_handle();
-
-    let mut ret = get_rest();
-
-    let req_data = ret.setting_dual_leverage(json!({
-        "pair":"BTC-USDT",
-        "contract_type":"swap",
-        "lever_rate":1,
-    })).await;
-    trace!("htx--设置持仓模式--{:?}", req_data);
-    trace!("htx--设置持仓模式--{}", req_data.data);
-}
-
-
-fn get_rest() -> HtxSwapRest {
-    let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-    btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-    btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-
-    let htx_exc = HtxSwapRest::new(false, btree_map);
-    htx_exc
-}
-
-// 检测是否走代理
-pub fn proxy_handle() {
-    if proxy::ParsingDetail::http_enable_proxy() {
-        trace!("检测有代理配置,配置走代理");
-    }
-}

+ 0 - 264
exchanges/tests/kucoin_spot_test.rs

@@ -1,264 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-//
-// use futures_util::StreamExt;
-// use tokio::sync::Mutex;
-// use tracing::trace;
-//
-// use exchanges::kucoin_spot_rest::KucoinSpotRest;
-// use exchanges::kucoin_spot_ws::{KucoinSpotLogin, KucoinSpotSubscribeType, KucoinSpotWs, KucoinSpotWsType};
-//
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-// const PASS_KEY: &str = "";
-//
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_custom_subscribe_pu() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//
-//     let mut ws = get_ws(None, KucoinSpotWsType::Public).await;
-//     ws.set_symbols(vec!["BTC-USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50,
-//         KucoinSpotSubscribeType::PuMarketTicker,
-//         KucoinSpotSubscribeType::PuMarketMatch,
-//     ]);
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//     });
-//
-//     //写数据
-//     let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     let _write_tx_clone = Arc::clone(&write_tx_am);
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20*1000)).await;
-//     //         let close_frame = CloseFrame {
-//     //             code: CloseCode::Normal,
-//     //             reason: Cow::Borrowed("Bye bye"),
-//     //         };
-//     //         let close_message = Message::Close(Some(close_frame));
-//     //         // AbstractWsMode::send_subscribe(write_tx_clone.clone(), Message::Text("32313221".to_string()));
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), close_message);
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     // loop {
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     // }
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-// //ws-订阅私有频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-// async fn ws_custom_subscribe_pr() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//     let btree_map = KucoinSpotLogin {
-//         access_key: ACCESS_KEY.to_string(),
-//         secret_key: SECRET_KEY.to_string(),
-//         pass_key: PASS_KEY.to_string(),
-//     };
-//     let mut ws = get_ws(Option::from(btree_map), KucoinSpotWsType::Public).await;
-//     ws.set_symbols(vec!["BTC-USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         KucoinSpotSubscribeType::PrAccountBalance,
-//         KucoinSpotSubscribeType::PrSpotMarketTradeOrders,
-//     ]);
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//     });
-//
-//     //写数据
-//     let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     let _write_tx_clone = Arc::clone(&write_tx_am);
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20*1000)).await;
-//     //         let close_frame = CloseFrame {
-//     //             code: CloseCode::Normal,
-//     //             reason: Cow::Borrowed("Bye bye"),
-//     //         };
-//     //         let close_message = Message::Close(Some(close_frame));
-//     //         // AbstractWsMode::send_subscribe(write_tx_clone.clone(), Message::Text("32313221".to_string()));
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), close_message);
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     // loop {
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     // }
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-//
-// //rest-获取成交记录
-// #[tokio::test]
-// async fn rest_get_fills_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_fills("BTC-USDT".to_string(),
-//                                   "".to_string(),
-//                                   "".to_string(),
-//                                   -1,
-//                                   -1,
-//                                   500,
-//     ).await;
-//     trace!(?rep_data)
-// }
-//
-//
-// //rest-获取订单
-// #[tokio::test]
-// async fn rest_get_order_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_order().await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-獲取行情
-// #[tokio::test]
-// async fn rest_get_level1_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_level1("BTC-USDT".to_string()).await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-通過orderId获取訂單詳情
-// #[tokio::test]
-// async fn rest_get_order_by_order_id_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_order_by_order_id("3123123".to_string()).await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-通過clientOid獲取訂單詳情
-// #[tokio::test]
-// async fn rest_get_order_by_client_id_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_order_by_client_id("3123123".to_string()).await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-獲取賬戶列表 - 現貨/槓桿/現貨高頻
-// #[tokio::test]
-// async fn rest_get_accounts_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_accounts("USDT".to_string()).await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-獲取交易對列表
-// #[tokio::test]
-// async fn rest_get_symbols_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.get_symbols().await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-通過orderId撤單- 没权限需要查看
-// #[tokio::test]
-// async fn rest_cancel_order_by_order_id_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.cancel_order_by_order_id("dddd123131".to_string()).await;
-//     trace!(?rep_data)
-// }
-//
-// //rest-通過clientOid撤單- 没权限需要查看
-// #[tokio::test]
-// async fn rest_cancel_order_by_client_id_test() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut rest = get_rest();
-//     let rep_data = rest.cancel_order_by_client_id("dddd123131".to_string()).await;
-//     trace!(?rep_data)
-// }
-//
-//
-// async fn get_ws(btree_map: Option<KucoinSpotLogin>, type_v: KucoinSpotWsType) -> KucoinSpotWs {
-//     let ku_ws = KucoinSpotWs::new(false, btree_map,
-//                                   type_v).await;
-//     ku_ws
-// }
-//
-// fn get_rest() -> KucoinSpotRest {
-//     let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-//     // btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     // btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//     btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//     btree_map.insert("pass_key".to_string(), PASS_KEY.to_string());
-//
-//     let ku_exc = KucoinSpotRest::new(false, btree_map);
-//     ku_exc
-// }

+ 0 - 168
exchanges/tests/kucoin_swap_test.rs

@@ -1,168 +0,0 @@
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-//
-// use futures_util::StreamExt;
-// use tokio::sync::Mutex;
-// use tracing::trace;
-//
-// use exchanges::kucoin_swap_ws::{KucoinSwapLogin, KucoinSwapSubscribeType, KucoinSwapWs, KucoinSwapWsType};
-//
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-// const PASS_KEY: &str = "";
-//
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_custom_subscribe_pu() {
-//     global::log_utils::init_log_with_trace();
-//
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//
-//
-//     let mut ws = get_ws(None, KucoinSwapWsType::Public).await;
-//     ws.set_symbols(vec!["xbt_usdtM".to_string()]);
-//     ws.set_subscribe(vec![
-//         KucoinSwapSubscribeType::PuContractMarketLevel2Depth50,
-//         KucoinSwapSubscribeType::PuContractMarketExecution,
-//         KucoinSwapSubscribeType::PuContractMarkettickerV2,
-//     ]);
-//
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//     });
-//
-//     //写数据
-//     let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     let _write_tx_clone = Arc::clone(&write_tx_am);
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20*1000)).await;
-//     //         let close_frame = CloseFrame {
-//     //             code: CloseCode::Normal,
-//     //             reason: Cow::Borrowed("Bye bye"),
-//     //         };
-//     //         let close_message = Message::Close(Some(close_frame));
-//     //         // AbstractWsMode::send_subscribe(write_tx_clone.clone(), Message::Text("32313221".to_string()));
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), close_message);
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     // loop {
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     // }
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-// //ws-订阅私有频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_custom_subscribe_pr() {
-//     global::log_utils::init_log_with_trace();
-//
-//
-//     //对象
-//     let btree_map = KucoinSwapLogin {
-//         access_key: ACCESS_KEY.to_string(),
-//         secret_key: SECRET_KEY.to_string(),
-//         pass_key: PASS_KEY.to_string(),
-//     };
-//
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//     // let (write_tx, write_rx) = tokio::sync::broadcast::channel::<Message>(10);
-//     // let (read_tx, mut read_rx) = tokio::sync::broadcast::channel::<ResponseData>(10);
-//
-//
-//     let mut ws = get_ws(Option::from(btree_map), KucoinSwapWsType::Private).await;
-//     ws.set_symbols(vec!["xbt_usdtM".to_string()]);
-//     ws.set_subscribe(vec![
-//         // KucoinSwapSubscribeType::PuContractMarketLevel2Depth50,
-//         // KucoinSwapSubscribeType::PuContractMarketExecution,
-//         KucoinSwapSubscribeType::PuContractMarkettickerV2,
-//         KucoinSwapSubscribeType::PrContractAccountWallet,
-//         KucoinSwapSubscribeType::PrContractPosition,
-//         KucoinSwapSubscribeType::PrContractMarketTradeOrdersSys,
-//         KucoinSwapSubscribeType::PrContractMarketTradeOrders,
-//     ]);
-//
-//
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//     });
-//
-//     //写数据
-//     let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     let _write_tx_clone = Arc::clone(&write_tx_am);
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20*1000)).await;
-//     //         let close_frame = CloseFrame {
-//     //             code: CloseCode::Normal,
-//     //             reason: Cow::Borrowed("Bye bye"),
-//     //         };
-//     //         let close_message = Message::Close(Some(close_frame));
-//     //         // AbstractWsMode::send_subscribe(write_tx_clone.clone(), Message::Text("32313221".to_string()));
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), close_message);
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-//
-//     // loop {
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     // }
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-//
-//
-// async fn get_ws(btree_map: Option<KucoinSwapLogin>, type_v: KucoinSwapWsType) -> KucoinSwapWs {
-//     let ku_ws = KucoinSwapWs::new(false, btree_map,
-//                                   type_v).await;
-//     ku_ws
-// }

+ 0 - 411
exchanges/tests/okx_swap_test.rs

@@ -1,411 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// 
-// use futures_util::StreamExt;
-// use tokio::sync::Mutex;
-// use tracing::trace;
-// 
-// use exchanges::okx_swap_rest::OkxSwapRest;
-// use exchanges::okx_swap_ws::{OkxSwapLogin, OkxSwapSubscribeType, OkxSwapWs, OkxSwapWsType};
-// 
-// const ACCESS_KEY: &str = "";
-// const SECRET_KEY: &str = "";
-// const PASS_KEY: &str = "";
-// 
-// 
-// //ws-订阅公共频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_custom_subscribe_pu() {
-//     global::log_utils::init_log_with_trace();
-// 
-// 
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-// 
-// 
-//     let mut ws = get_ws(None, OkxSwapWsType::Public).await;
-//     ws.set_symbols(vec!["BTC_USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         // OkxSwapSubscribeType::PuBooks5,
-//         // OkxSwapSubscribeType::Putrades,
-//         OkxSwapSubscribeType::PuBooks50L2tbt,
-//         // OkxSwapSubscribeType::PuIndexTickers,
-//     ]);
-// 
-// 
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-// 
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-// 
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-// 
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-// 
-// //ws-订阅私有频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
-// async fn ws_custom_subscribe_bu() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-// 
-//     let mut ws = get_ws(None, OkxSwapWsType::Business).await;
-//     ws.set_symbols(vec!["BTC-USD".to_string()]);
-//     ws.set_subscribe(vec![
-//         OkxSwapSubscribeType::BuIndexCandle30m,
-//     ]);
-// 
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-// 
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-// 
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-// 
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-// }
-// 
-// //ws-订阅私有频道信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-// async fn ws_custom_subscribe_pr() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-// 
-//     let btree_map = OkxSwapLogin {
-//         api_key: ACCESS_KEY.to_string(),
-//         secret_key: SECRET_KEY.to_string(),
-//         passphrase: PASS_KEY.to_string(),
-//     };
-//     let mut ws = get_ws(Option::from(btree_map), OkxSwapWsType::Private).await;
-//     ws.set_symbols(vec!["BTC-USDT".to_string()]);
-//     ws.set_subscribe(vec![
-//         OkxSwapSubscribeType::PrAccount("USDT".to_string()),
-//         OkxSwapSubscribeType::PrOrders,
-//         OkxSwapSubscribeType::PrPositions,
-//         OkxSwapSubscribeType::PrBalanceAndPosition,
-//     ]);
-// 
-// 
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let is_shutdown_arc = Arc::new(AtomicBool::new(true));
-// 
-//     //读取
-//     let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
-//     let _tr = tokio::spawn(async move {
-//         trace!("线程-数据读取-开启");
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 trace!("读取数据data:{:?}",data)
-//             }
-//         }
-//         // trace!("线程-数据读取-结束");
-//     });
-// 
-//     //写数据
-//     // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
-//     // let write_tx_clone = Arc::clone(&write_tx_am);
-//     // let su = ws.get_subscription();
-//     // let tw = tokio::spawn(async move {
-//     //     trace!("线程-数据写入-开始");
-//     //     loop {
-//     //         tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
-//     //         // let close_frame = CloseFrame {
-//     //         //     code: CloseCode::Normal,
-//     //         //     reason: Cow::Borrowed("Bye bye"),
-//     //         // };
-//     //         // let message = Message::Close(Some(close_frame));
-//     //
-//     //
-//     //         let message = Message::Text(su.clone());
-//     //         AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
-//     //         trace!("发送指令成功");
-//     //     }
-//     //     trace!("线程-数据写入-结束");
-//     // });
-// 
-//     let t1 = tokio::spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         trace!("test 唯一线程结束--");
-//     });
-//     tokio::try_join!(t1).unwrap();
-//     trace!("当此结束");
-//     trace!("重启!");
-//     trace!("参考交易所关闭");
-//     return;
-//     //
-//     // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
-//     // let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-//     //
-//     // btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     // btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//     // btree_map.insert("pass_key".to_string(), PASS_KEY.to_string());
-//     //
-//     // let (tx, mut rx) = channel(1024);
-//     // let mut ws = get_ws(btree_map, OkxWsType::Private, tx).await;
-//     // ws.set_subscribe(vec![
-//     //     OkxSubscribeType::PrBalanceAndPosition,
-//     //     // OkxSubscribeType::PrAccount("USDT".to_string()),
-//     //     OkxSubscribeType::PrOrders,
-//     //     OkxSubscribeType::PrPositions,
-//     // ]);
-//     //
-//     // let t1 = tokio::spawn(async move {
-//     //     ws.custom_subscribe(is_shutdown_arc, vec!["BTC-USDT".to_string()]).await;
-//     // });
-//     //
-//     // let t2 = tokio::spawn(async move {
-//     //     loop {
-//     //         if let Ok(received) = rx.try_recv() {
-//     //             trace!( "age: {:?}", received);
-//     //         }
-//     //     }
-//     // });
-//     // try_join!(t1,t2).unwrap();
-// }
-// 
-// 
-// //rest-订单查询
-// #[tokio::test]
-// async fn rest_get_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_order("BTC-USDT".to_string(), "3333".to_string(), "".to_string()).await;
-//     println!("okx--订单查询--{:?}", req_data);
-// }
-// 
-// 
-// //rest-未完成的订单
-// #[tokio::test]
-// async fn rest_get_incomplete_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_incomplete_order("BTC-USDT".to_string()).await;
-//     println!("okx--未完成的订单--{:?}", req_data);
-// }
-// 
-// //rest-获取系统时间
-// #[tokio::test]
-// async fn rest_get_server_time_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_server_time().await;
-//     println!("okx--获取系统时间--{:?}", req_data);
-// }
-// 
-// //rest-查看持仓信息
-// #[tokio::test]
-// async fn rest_get_positions_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_positions("SWA1P".to_string()).await;
-//     println!("okx--查看持仓信息--{:?}", req_data);
-// }
-// 
-// //rest-获取单个产品行情信息
-// #[tokio::test]
-// async fn rest_get_ticker_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_ticker("BTC-USDT".to_string()).await;
-//     println!("okx--获取单个产品行情信息--{:?}", req_data);
-// }
-// 
-// //rest-查看账户余额
-// #[tokio::test]
-// async fn rest_get_balance_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_balance("BTC,ETH".to_string()).await;
-//     println!("okx--查看账户余额--{:?}", req_data);
-// }
-// 
-// //rest-获取交易产品基础信息
-// #[tokio::test]
-// async fn rest_get_instruments_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_instruments().await;
-//     println!("okx--获取交易产品基础信息--{:?}", req_data);
-// }
-// 
-// //rest-获取成交明细(近三天)
-// #[tokio::test]
-// async fn rest_get_trade_fills_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_trade_fills("".to_string()).await;
-//     println!("okx--获取成交明细(近三天)--{:?}", req_data);
-// }
-// 
-// //rest-撤单
-// #[tokio::test]
-// async fn rest_cancel_order_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.cancel_order("BTC-USD".to_string(), "1111".to_string(), "".to_string()).await;
-//     println!("okx--撤单--{:?}", req_data);
-// }
-// 
-// //rest-设置杠杆倍数
-// #[tokio::test]
-// async fn rest_set_leverage_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.set_leverage("BTC-USDT".to_string(), "5".to_string()).await;
-//     println!("okx--设置杠杆倍数--{:?}", req_data);
-// }
-// 
-// //rest-设置持仓模式
-// #[tokio::test]
-// async fn rest_set_position_mode_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.set_position_mode().await;
-//     println!("okx--设置持仓模式--{:?}", req_data);
-// }
-// 
-// //rest-获取历史订单记录(近七天)
-// #[tokio::test]
-// async fn rest_get_orders_history_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_orders_history("".to_string(),
-//                                           "".to_string(),
-//                                           "filled".to_string(),
-//                                           "".to_string(),
-//                                           "".to_string(),
-//                                           "".to_string(),
-//     ).await;
-//     println!("okx--获取历史订单记录--{:?}", req_data);
-// }
-// 
-// //rest-获取历史成交数据(近七天)
-// #[tokio::test]
-// async fn rest_get_trades_test() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut ret = get_rest();
-//     let req_data = ret.get_trades("".to_string(),
-//                                   "".to_string(),
-//                                   "".to_string(),
-//                                   "".to_string(),
-//                                   "".to_string(),
-//                                   "100".to_string(),
-//     ).await;
-//     println!("okx--获取历史成交数据--{:?}", req_data);
-// }
-// 
-// 
-// async fn get_ws(btree_map: Option<OkxSwapLogin>, type_v: OkxSwapWsType) -> OkxSwapWs {
-//     let ku_ws = OkxSwapWs::new(false, btree_map, type_v);
-//     ku_ws
-// }
-// 
-// fn get_rest() -> OkxSwapRest {
-//     let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-//     btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
-//     btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
-//     btree_map.insert("pass_key".to_string(), PASS_KEY.to_string());
-// 
-//     let okx_exc = OkxSwapRest::new(false, btree_map.clone());
-//     okx_exc
-// }

+ 0 - 67
exchanges/tests/socket_tool_test.rs

@@ -1,67 +0,0 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::Duration;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use futures_util::StreamExt;
-use tokio::sync::mpsc::{channel, Sender};
-use tokio::try_join;
-use tokio_tungstenite::client_async;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::trace;
-use exchanges::binance_swap_rest::BinanceSwapRest;
-use exchanges::binance_swap_ws::{BinanceSwapSubscribeType, BinanceSwapWs, BinanceSwapWsType};
-use exchanges::response_base::ResponseData;
-use exchanges::socket_tool::{client, ws_connect_async};
-
-//ws-订阅公共频道信息
-#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
-async fn ws_custom_subscribe() {
-    global::log_utils::init_log_with_trace();
-
-    // // 币安订阅
-    let base_url = "wss://fstream.binance.com/stream?streams=btcusdt@depth20@100ms".to_string();
-    // // okx 公共订阅
-    // let str = serde_json::json!({
-    //             "op": "subscribe",
-    //             "args": [
-    //                     {
-    //                     "channel":"books5",
-    //                     "instId":"BTC-USDT"
-    //                     }
-    //                 ]
-    //         });
-    //
-    // //创建通道,发送指令通道, 与读取推送数据通道
-    // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-    // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-    //
-    //
-    // //对象
-    // // let model = OkxSwapModel::new();
-    // let is_ok =  ws_connect_async(base_url).await;
-    // //写数据,订阅频道,有些是Url跟参数,有些是单独发送订阅字符串
-    // // write_tx.unbounded_send(Message::Text(str.to_string())).expect("发送失败");
-    // match is_ok {
-    //     Ok(_) => {
-    //         let t1 = tokio::spawn(async move {
-    //             loop {
-    //                 if let Some(message) = read_rx.next().await {
-    //
-    //                 }
-    //             }
-    //         });
-    //         try_join!(t1).unwrap();
-    //     }
-    //     _ => {}
-    // }
-    client(base_url).await;
-}
-
-//
-// fn get_ws(btree_map: BTreeMap<String, String>, tx: Sender<ResponseData>) -> BinanceSwapWs {
-//     let binance_ws = BinanceSwapWs::new(false,
-//                                         btree_map,
-//                                         BinanceSwapWsType::PublicAndPrivate);
-//     binance_ws
-// }

+ 0 - 9
src/core_libs.rs

@@ -36,21 +36,12 @@ pub async fn init(params: Params,
                                    error_sender.clone(),
                                    error_sender.clone(),
                                    running.clone(),
                                    running.clone(),
                                    cci_arc.clone()).await;
                                    cci_arc.clone()).await;
-    let ref_name = core_obj.ref_name[0].clone();
     let trade_name = core_obj.trade_name.clone();
     let trade_name = core_obj.trade_name.clone();
 
 
     info!("core初始化……");
     info!("core初始化……");
     core_obj.before_trade().await;
     core_obj.before_trade().await;
     let core_arc = Arc::new(Mutex::new(core_obj));
     let core_arc = Arc::new(Mutex::new(core_obj));
 
 
-    // 参考交易所
-    exchange_disguise::run_reference_exchange(ws_running.clone(),
-                                              params.ref_exchange.get(0).unwrap().clone(),
-                                              core_arc.clone(),
-                                              ref_name,
-                                              params.ref_pair.clone(),
-                                              params.colo != 0i8,
-                                              exchange_params.clone()).await;
     // 交易交易所
     // 交易交易所
     exchange_disguise::run_transactional_exchange(ws_running.clone(),
     exchange_disguise::run_transactional_exchange(ws_running.clone(),
                                                   params.exchange,
                                                   params.exchange,

+ 0 - 118
standard/src/binance_spot.rs

@@ -1,118 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::io::{Error, ErrorKind};
-// use std::result::Result;
-// use async_trait::async_trait;
-// use rust_decimal::Decimal;
-// use rust_decimal_macros::dec;
-// use tracing::{warn};
-// use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand};
-// use exchanges::binance_spot_rest::BinanceSpotRest;
-// use global::trace_stack::TraceStack;
-//
-// #[allow(dead_code)]
-// #[derive(Clone)]
-// pub struct BinanceSpot {
-//     exchange: ExchangeEnum,
-//     symbol: String,
-//     is_colo: bool,
-//     params: BTreeMap<String, String>,
-//     request: BinanceSpotRest,
-// }
-//
-// impl BinanceSpot {
-//     pub fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>) -> BinanceSpot {
-//         BinanceSpot {
-//             exchange: ExchangeEnum::BinanceSpot,
-//             symbol: symbol.to_uppercase(),
-//             is_colo,
-//             params: params.clone(),
-//             request: BinanceSpotRest::new(is_colo, params.clone()),
-//         }
-//     }
-// }
-//
-//
-// #[async_trait]
-// impl Platform for BinanceSpot {
-//     // 克隆方法
-//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-//     // 获取交易所模式
-//     fn get_self_exchange(&self) -> ExchangeEnum {
-//         ExchangeEnum::BinanceSpot
-//     }
-//     // 获取交易对
-//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
-//     // 获取是否使用高速通道
-//     fn get_self_is_colo(&self) -> bool {
-//         self.is_colo
-//     }
-//     // 获取登录params信息
-//     fn get_self_params(&self) -> BTreeMap<String, String> {
-//         self.params.clone()
-//     }
-//
-//     fn get_self_market(&self) -> Market {
-//         warn!("binance_spot:该交易所方法未实现");
-//         return Market::new();
-//     }
-//
-//     fn get_request_delays(&self) -> Vec<i64> {
-//         warn!("binance_spot:该交易所方法未实现");
-//         return vec![];
-//     }
-//
-//     fn get_request_avg_delay(&self) -> Decimal {
-//         warn!("binance_spot:该交易所方法未实现");
-//         return dec!(0);
-//     }
-//
-//     fn get_request_max_delay(&self) -> i64 {
-//         warn!("binance_spot:该交易所方法未实现");
-//         return 0;
-//     }
-//
-//     async fn get_server_time(&mut self) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     // 获取账号信息
-//     async fn get_account(&mut self) -> Result<Account, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     // 获取仓位信息
-//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     // 获取市场行情
-//     async fn get_ticker(&mut self) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_ticker_symbol(&mut self, _symbol: String) -> Result<Ticker, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_market(&mut self) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_market_symbol(&mut self, _symbol: String) -> Result<Market, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_order_detail(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn command_order(&mut self, _order_command: OrderCommand, _trace_stack: TraceStack) { warn!("binance_spot:该交易所方法未实现"); }
-// }

+ 0 - 51
standard/src/binance_spot_handle.rs

@@ -1,51 +0,0 @@
-// use std::str::FromStr;
-// use rust_decimal::Decimal;
-// use rust_decimal_macros::dec;
-// use exchanges::response_base::ResponseData;
-// use crate::{MarketOrder, SpecialDepth, SpecialTicker};
-// use crate::exchange::ExchangeEnum;
-// use crate::handle_info::HandleSwapInfo;
-//
-//
-// // 处理特殊Ticker信息
-// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-//     let res_data_str = res_data.data;
-//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-//     format_special_ticker(res_data_json, res_data.label)
-// }
-//
-// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-//     let bp = Decimal::from_str(data["b"].as_str().unwrap()).unwrap();
-//     let bq = Decimal::from_str(data["B"].as_str().unwrap()).unwrap();
-//     let ap = Decimal::from_str(data["a"].as_str().unwrap()).unwrap();
-//     let aq = Decimal::from_str(data["A"].as_str().unwrap()).unwrap();
-//     let mp = (bp + ap) * dec!(0.5);
-//     let t = Decimal::from_str(&data["u"].to_string()).unwrap();
-//
-//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at: Default::default() };
-//     let depth_info = vec![bp, bq, ap, aq];
-//     SpecialDepth {
-//         name: label,
-//         depth: depth_info,
-//         ticker: ticker_info,
-//         t,
-//         create_at: Default::default(),
-//     }
-// }
-//
-// // 处理特殊深度数据
-// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-//     HandleSwapInfo::handle_special_depth(ExchangeEnum::BinanceSpot, res_data)
-// }
-//
-// // 格式化深度信息
-// pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-//     let mut depth_items: Vec<MarketOrder> = vec![];
-//     for value in value.as_array().unwrap() {
-//         depth_items.push(MarketOrder {
-//             price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-//         })
-//     }
-//     return depth_items;
-// }

+ 0 - 397
standard/src/binance_swap.rs

@@ -1,397 +0,0 @@
-use std::collections::BTreeMap;
-use std::io::{Error, ErrorKind};
-use std::result::Result;
-use std::str::FromStr;
-use async_trait::async_trait;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use serde_json::Value;
-use tokio::sync::mpsc::Sender;
-use tokio::time::Instant;
-use tracing::{error, warn};
-use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand, utils, PositionModeEnum};
-use exchanges::binance_swap_rest::BinanceSwapRest;
-use global::trace_stack::TraceStack;
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct BinanceSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: BinanceSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl BinanceSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BinanceSwap {
-        let market = Market::new();
-        let mut binance_swap = BinanceSwap {
-            exchange: ExchangeEnum::BinanceSwap,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: BinanceSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        binance_swap.market = BinanceSwap::get_market(&mut binance_swap).await.unwrap_or(binance_swap.market);
-        return binance_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for BinanceSwap {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    // 获取交易所模式
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::BinanceSwap
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-    // 获取market信息
-    fn get_self_market(&self) -> Market { self.market.clone() }
-    // 获取请求时间
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-    // 获取请求平均时间
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-    // 获取请求最大时间
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-
-    // 获取服务器时间
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let result = res_data_json["serverTime"].to_string();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取账号信息
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let res_data = self.request.get_account().await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let balance_info = res_data_json.iter().find(|item| item["asset"].as_str().unwrap().to_string() == symbol_array[1].to_string());
-            match balance_info {
-                None => {
-                    error!("binance_swap:格式化账号信息错误!\nget_account: res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let balance = Decimal::from_str(value["balance"].as_str().unwrap()).unwrap();
-                    let available_balance = Decimal::from_str(value["availableBalance"].as_str().unwrap()).unwrap();
-                    let frozen_balance = balance - available_balance;
-                    let result = Account {
-                        coin: value["asset"].as_str().unwrap().to_string(),
-                        balance,
-                        available_balance,
-                        frozen_balance,
-                        stocks: Decimal::ZERO,
-                        available_stocks: Decimal::ZERO,
-                        frozen_stocks: Decimal::ZERO,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string()))
-    }
-
-    // 获取仓位信息
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_position_risk(symbol_format).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let res_data = self.request.get_position_risk("".to_string()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let result = res_data_json.iter().map(|item| { format_position_item(item, Decimal::ONE) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 获取市场行情
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let res_data = self.request.get_book_ticker(symbol_format).await;
-        if res_data.code == 200 {
-            let res_data_json: serde_json::Value = res_data.data;
-            let result = Ticker {
-                time: res_data_json["time"].as_i64().unwrap(),
-                high: Decimal::from_str(res_data_json["askPrice"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(res_data_json["bidPrice"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(res_data_json["askPrice"].as_str().unwrap()).unwrap(),
-                sell_volume: Default::default(),
-                buy: Decimal::from_str(res_data_json["bidPrice"].as_str().unwrap()).unwrap(),
-                buy_volume: Default::default(),
-                last: dec!(-1),
-                volume: dec!(-1),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let res_data = self.request.get_book_ticker(symbol_format).await;
-        if res_data.code == 200 {
-            let res_data_json: serde_json::Value = res_data.data;
-            let result = Ticker {
-                time: res_data_json["time"].as_i64().unwrap(),
-                high: Decimal::from_str(res_data_json["askPrice"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(res_data_json["bidPrice"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(res_data_json["askPrice"].as_str().unwrap()).unwrap(),
-                sell_volume: Default::default(),
-                buy: Decimal::from_str(res_data_json["bidPrice"].as_str().unwrap()).unwrap(),
-                buy_volume: Default::default(),
-                last: dec!(-1),
-                volume: dec!(-1),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let res_data = self.request.get_exchange_info().await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let symbols = res_data_json["symbols"].as_array().unwrap();
-            let market_info = symbols.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format);
-            match market_info {
-                None => {
-                    error!("binance_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_json);
-                    Err(Error::new(ErrorKind::Other, res_data_json.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseAsset"].as_str().unwrap_or("").to_string();
-                    let quote_asset = value["quoteAsset"].as_str().unwrap_or("").to_string();
-
-                    let filter_array = value["filters"].as_array().unwrap().clone();
-                    let price_filter = filter_array.iter().find(|&item| item["filterType"].as_str().unwrap() == "PRICE_FILTER").unwrap();
-                    let lot_size_filter = filter_array.iter().find(|&item| item["filterType"].as_str().unwrap() == "LOT_SIZE").unwrap();
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset, quote_asset),
-                        base_asset,
-                        quote_asset,
-                        tick_size: Decimal::from_str(&price_filter["tickSize"].as_str().unwrap()).unwrap(),
-                        amount_size: Decimal::from_str(lot_size_filter["stepSize"].as_str().unwrap()).unwrap(),
-                        price_precision: Decimal::from_f64(value["pricePrecision"].as_f64().unwrap()).unwrap(),
-                        amount_precision: Decimal::from_f64(value["quantityPrecision"].as_f64().unwrap()).unwrap(),
-                        min_qty: Decimal::from_str(lot_size_filter["minQty"].as_str().unwrap()).unwrap(),
-                        max_qty: Decimal::from_str(lot_size_filter["maxQty"].as_str().unwrap()).unwrap(),
-                        min_notional: Decimal::from_str(price_filter["minPrice"].as_str().unwrap()).unwrap(),
-                        max_notional: Decimal::from_str(price_filter["maxPrice"].as_str().unwrap()).unwrap(),
-                        ct_val: Decimal::ONE,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let res_data = self.request.get_exchange_info().await;
-        if res_data.code == 200 {
-            let res_data_json: serde_json::Value = res_data.data;
-            let symbols = res_data_json["symbols"].as_array().unwrap();
-            let market_info = symbols.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format);
-            match market_info {
-                None => {
-                    error!("binance_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_json);
-                    Err(Error::new(ErrorKind::Other, res_data_json.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseAsset"].as_str().unwrap_or("").to_string();
-                    let quote_asset = value["quoteAsset"].as_str().unwrap_or("").to_string();
-
-                    let filter_array = value["filters"].as_array().unwrap().clone();
-                    let price_filter = filter_array.iter().find(|&item| item["filterType"].as_str().unwrap() == "PRICE_FILTER").unwrap();
-                    let lot_size_filter = filter_array.iter().find(|&item| item["filterType"].as_str().unwrap() == "LOT_SIZE").unwrap();
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset, quote_asset),
-                        base_asset,
-                        quote_asset,
-                        tick_size: Decimal::from_str(&price_filter["tickSize"].as_str().unwrap()).unwrap(),
-                        amount_size: Decimal::from_str(lot_size_filter["stepSize"].as_str().unwrap()).unwrap(),
-                        price_precision: Decimal::from_f64(value["pricePrecision"].as_f64().unwrap()).unwrap(),
-                        amount_precision: Decimal::from_f64(value["quantityPrecision"].as_f64().unwrap()).unwrap(),
-                        min_qty: Decimal::from_str(lot_size_filter["minQty"].as_str().unwrap()).unwrap(),
-                        max_qty: Decimal::from_str(lot_size_filter["maxQty"].as_str().unwrap()).unwrap(),
-                        min_notional: Decimal::from_str(price_filter["minPrice"].as_str().unwrap()).unwrap(),
-                        max_notional: Decimal::from_str(price_filter["maxPrice"].as_str().unwrap()).unwrap(),
-                        ct_val: Decimal::ONE,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let res_data = self.request.get_order(symbol_format, order_id.parse().unwrap_or(-1), custom_id.to_string()).await;
-        if res_data.code == 200 {
-            let res_data_json: serde_json::Value = res_data.data;
-
-            let status = res_data_json["status"].as_str().unwrap();
-            let custom_status = if ["CANCELED", "EXPIRED", "FILLED"].contains(&status) { "REMOVE".to_string() } else if status == "NEW" { "NEW".to_string() } else {
-                error!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data_json);
-                panic!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data_json)
-            };
-            let result = Order {
-                id: res_data_json["orderId"].to_string(),
-                custom_id: res_data_json["clientOrderId"].as_str().unwrap().parse().unwrap(),
-                price: Decimal::from_str(res_data_json["price"].as_str().unwrap()).unwrap(),
-                amount: Decimal::from_str(res_data_json["origQty"].as_str().unwrap()).unwrap(),
-                deal_amount: Decimal::from_str(res_data_json["executedQty"].as_str().unwrap()).unwrap(),
-                avg_price: Decimal::from_str(res_data_json["avgPrice"].as_str().unwrap()).unwrap(),
-                status: custom_status,
-                order_type: res_data_json["type"].as_str().unwrap().parse().unwrap(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("301 binance_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let res_data = self.request.get_open_orders(symbol_format).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let order_info: Vec<_> = res_data_json.iter().filter(|item| item["contract"].as_str().unwrap_or("") == self.symbol).collect();
-            let result = order_info.iter().map(|&item| {
-                let status = item["status"].as_str().unwrap();
-                let custom_status = if ["CANCELED", "EXPIRED", "FILLED"].contains(&status) { "REMOVE".to_string() } else if status == "NEW" { "NEW".to_string() } else {
-                    error!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data);
-                    panic!("binance_swap:格式化订单状态错误!\nget_order_detail:res_data={:?}", res_data)
-                };
-                Order {
-                    id: item["orderId"].to_string(),
-                    custom_id: item["clientOrderId"].as_str().unwrap().parse().unwrap(),
-                    price: Decimal::from_str(item["price"].as_str().unwrap()).unwrap(),
-                    amount: Decimal::from_str(item["origQty"].as_str().unwrap()).unwrap(),
-                    deal_amount: Decimal::from_str(item["executedQty"].as_str().unwrap()).unwrap(),
-                    avg_price: Decimal::from_str(item["avgPrice"].as_str().unwrap()).unwrap(),
-                    status: custom_status,
-                    order_type: item["type"].as_str().unwrap().parse().unwrap(),
-                    trace_stack: TraceStack::new(0, Instant::now()).on_special("331 binance_swap".to_string()),
-                }
-            }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-
-    async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "binance_swap:该交易所方法未实现".to_string())) }
-
-    async fn command_order(&mut self, _order_command: &mut OrderCommand, _trace_stack: &TraceStack) { warn!("binance_swap:该交易所方法未实现"); }
-}
-
-pub fn format_position_item(position: &serde_json::Value, ct_val: Decimal) -> Position {
-    let mut position_mode = match position["positionSide"].as_str().unwrap_or("") {
-        "BOTH" => PositionModeEnum::Both,
-        "LONG" => PositionModeEnum::Long,
-        "SHORT" => PositionModeEnum::Short,
-        _ => {
-            error!("binance_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("binance_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
-        }
-    };
-    let size = Decimal::from_str(position["positionAmt"].as_str().unwrap()).unwrap();
-    let amount = size * ct_val;
-    match position_mode {
-        PositionModeEnum::Both => {
-            position_mode = match amount {
-                amount if amount > Decimal::ZERO => PositionModeEnum::Long,
-                amount if amount < Decimal::ZERO => PositionModeEnum::Short,
-                _ => { PositionModeEnum::Both }
-            };
-        }
-        _ => {}
-    }
-    Position {
-        symbol: position["symbol"].as_str().unwrap_or("").parse().unwrap(),
-        margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(position["entryPrice"].as_str().unwrap()).unwrap(),
-        profit: Decimal::from_str(position["unRealizedProfit"].as_str().unwrap()).unwrap(),
-        position_mode,
-        margin: Decimal::from_str(position["isolatedMargin"].as_str().unwrap()).unwrap(),
-    }
-}

+ 0 - 40
standard/src/binance_swap_handle.rs

@@ -1,40 +0,0 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
-use serde_json::Value;
-use exchanges::response_base::ResponseData;
-use crate::{MarketOrder, SpecialDepth, SpecialTicker};
-
-
-// 处理特殊Ticker信息
-pub fn handle_book_ticker(res_data: &ResponseData) -> SpecialDepth {
-    let bp = Decimal::from_str((*res_data).data["b"].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_str((*res_data).data["B"].as_str().unwrap()).unwrap();
-    let ap = Decimal::from_str((*res_data).data["a"].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_str((*res_data).data["A"].as_str().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_str(&(*res_data).data["u"].to_string()).unwrap();
-    let create_at = (*res_data).data["E"].as_i64().unwrap() * 1000;
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: (*res_data).label.clone(),
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
-
-// 格式化深度信息
-pub fn format_depth_items(value: Value) -> Vec<MarketOrder> {
-    let mut depth_items: Vec<MarketOrder> = vec![];
-    for value in value.as_array().unwrap() {
-        depth_items.push(MarketOrder {
-            price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}

+ 0 - 625
standard/src/bitget_spot.rs

@@ -1,625 +0,0 @@
-// use std::collections::{BTreeMap, HashMap};
-// use std::io::{Error, ErrorKind};
-// use std::str::FromStr;
-// use tokio::sync::mpsc::Sender;
-// use async_trait::async_trait;
-// use futures::stream::FuturesUnordered;
-// use futures::TryStreamExt;
-// use rust_decimal::Decimal;
-// use rust_decimal::prelude::ToPrimitive;
-// use rust_decimal_macros::dec;
-// use serde_json::json;
-// use tokio::time::Instant;
-// use tracing::{error};
-// use exchanges::bitget_spot_rest::BitgetSpotRest;
-// use global::trace_stack::TraceStack;
-// use crate::exchange::ExchangeEnum;
-// use crate::{Account, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
-//
-// #[allow(dead_code)]
-// #[derive(Clone)]
-// pub struct BitgetSpot {
-//     exchange: ExchangeEnum,
-//     symbol: String,
-//     is_colo: bool,
-//     params: BTreeMap<String, String>,
-//     request: BitgetSpotRest,
-//     market: Market,
-//     order_sender: Sender<Order>,
-//     error_sender: Sender<Error>,
-// }
-//
-// impl BitgetSpot {
-//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BitgetSpot {
-//         let market = Market::new();
-//         let mut bitget_spot = BitgetSpot {
-//             exchange: ExchangeEnum::BitgetSpot,
-//             symbol: symbol.to_uppercase(),
-//             is_colo,
-//             params: params.clone(),
-//             request: BitgetSpotRest::new(is_colo, params.clone()),
-//             market,
-//             order_sender,
-//             error_sender,
-//         };
-//         bitget_spot.market = BitgetSpot::get_market(&mut bitget_spot).await.unwrap_or(bitget_spot.market);
-//         return bitget_spot;
-//     }
-// }
-//
-// #[async_trait]
-// impl Platform for BitgetSpot {
-//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-//
-//     fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::BitgetSpot }
-//
-//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
-//
-//     fn get_self_is_colo(&self) -> bool { self.is_colo }
-//
-//     fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
-//
-//     fn get_self_market(&self) -> Market { self.market.clone() }
-//
-//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-//
-//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-//
-//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-//
-//     async fn get_server_time(&mut self) -> Result<String, Error> {
-//         let res_data = self.request.get_server_time().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let result = res_data_json["serverTime"].as_str().unwrap().to_string();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_account(&mut self) -> Result<Account, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-//         let res_data = self.request.get_account_assets().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
-//             let result = res_data_json.iter().map(|item| format_account_info(item.clone())).collect();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string())) }
-//
-//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-//         let res_data = self.request.get_tickers(symbol_format).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let ticker_info = res_data_json[0].clone();
-//             let time = (Decimal::from_str(&*ticker_info["ts"].as_str().unwrap()).unwrap() / dec!(1000)).floor().to_i64().unwrap();
-//             let result = Ticker {
-//                 time,
-//                 high: Decimal::from_str(ticker_info["high24h"].as_str().unwrap()).unwrap(),
-//                 low: Decimal::from_str(ticker_info["low24h"].as_str().unwrap()).unwrap(),
-//                 sell: Decimal::from_str(ticker_info["askPr"].as_str().unwrap()).unwrap(),
-//                 buy: Decimal::from_str(ticker_info["bidPr"].as_str().unwrap()).unwrap(),
-//                 last: Decimal::from_str(ticker_info["lastPr"].as_str().unwrap()).unwrap(),
-//                 volume: Decimal::from_str(ticker_info["quoteVolume"].as_str().unwrap()).unwrap(),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-//         let symbol_format = utils::format_symbol(symbol.clone(), "");
-//         let res_data = self.request.get_tickers(symbol_format).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let ticker_info = res_data_json[0].clone();
-//             let time = (Decimal::from_str(&*ticker_info["ts"].as_str().unwrap()).unwrap() / dec!(1000)).floor().to_i64().unwrap();
-//             let result = Ticker {
-//                 time,
-//                 high: Decimal::from_str(ticker_info["high24h"].as_str().unwrap()).unwrap(),
-//                 low: Decimal::from_str(ticker_info["low24h"].as_str().unwrap()).unwrap(),
-//                 sell: Decimal::from_str(ticker_info["askPr"].as_str().unwrap()).unwrap(),
-//                 buy: Decimal::from_str(ticker_info["bidPr"].as_str().unwrap()).unwrap(),
-//                 last: Decimal::from_str(ticker_info["lastPr"].as_str().unwrap()).unwrap(),
-//                 volume: Decimal::from_str(ticker_info["quoteVolume"].as_str().unwrap()).unwrap(),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_market(&mut self) -> Result<Market, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-//         let res_data = self.request.get_symbols(symbol_format.clone()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
-//             let market_info = res_data_json.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format.clone());
-//             match market_info {
-//                 None => {
-//                     error!("bitget_spot:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//                 }
-//                 Some(value) => {
-//                     let base_asset = value["baseCoin"].as_str().unwrap().to_string();
-//                     let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
-//                     let price_precision = Decimal::from_str(value["pricePrecision"].as_str().unwrap()).unwrap();
-//                     let amount_precision = Decimal::from_str(value["quantityPrecision"].as_str().unwrap()).unwrap();
-//                     let min_qty = Decimal::from_str(&value["minTradeAmount"].as_str().unwrap()).unwrap();
-//                     let max_qty = Decimal::from_str(&value["maxTradeAmount"].as_str().unwrap()).unwrap();
-//
-//                     let tick_size = if price_precision > dec!(0) {
-//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(price_precision - dec!(1)).unwrap()))).unwrap()
-//                     } else {
-//                         Decimal::ONE
-//                     };
-//                     let amount_size = if amount_precision > dec!(0) {
-//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(amount_precision - dec!(1)).unwrap()))).unwrap()
-//                     } else {
-//                         Decimal::ONE
-//                     };
-//
-//                     let result = Market {
-//                         symbol: format!("{}_{}", base_asset, quote_asset),
-//                         base_asset,
-//                         quote_asset,
-//                         tick_size,
-//                         amount_size,
-//                         price_precision,
-//                         amount_precision,
-//                         min_qty,
-//                         max_qty,
-//                         min_notional: min_qty,
-//                         max_notional: max_qty,
-//                         ct_val: Decimal::ONE,
-//                     };
-//                     Ok(result)
-//                 }
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-//         let symbol_format = utils::format_symbol(symbol.clone(), "");
-//         let res_data = self.request.get_symbols(symbol_format.clone()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
-//             let market_info = res_data_json.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol_format.clone());
-//             match market_info {
-//                 None => {
-//                     error!("bitget_spot:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-//                     Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//                 }
-//                 Some(value) => {
-//                     let base_asset = value["baseCoin"].as_str().unwrap().to_string();
-//                     let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
-//                     let price_precision = Decimal::from_str(value["pricePrecision"].as_str().unwrap()).unwrap();
-//                     let amount_precision = Decimal::from_str(value["quantityPrecision"].as_str().unwrap()).unwrap();
-//                     let min_qty = Decimal::from_str(&value["minTradeAmount"].as_str().unwrap()).unwrap();
-//                     let max_qty = Decimal::from_str(&value["maxTradeAmount"].as_str().unwrap()).unwrap();
-//
-//                     let tick_size = if price_precision > dec!(0) {
-//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(price_precision - dec!(1)).unwrap()))).unwrap()
-//                     } else {
-//                         Decimal::ONE
-//                     };
-//                     let amount_size = if amount_precision > dec!(0) {
-//                         Decimal::from_str(&format!("0.{}1", "0".repeat(usize::try_from(amount_precision - dec!(1)).unwrap()))).unwrap()
-//                     } else {
-//                         Decimal::ONE
-//                     };
-//
-//                     let result = Market {
-//                         symbol: format!("{}_{}", base_asset, quote_asset),
-//                         base_asset,
-//                         quote_asset,
-//                         tick_size,
-//                         amount_size,
-//                         price_precision,
-//                         amount_precision,
-//                         min_qty,
-//                         max_qty,
-//                         min_notional: min_qty,
-//                         max_notional: max_qty,
-//                         ct_val: Decimal::ONE,
-//                     };
-//                     Ok(result)
-//                 }
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-//         let ct_val = self.market.ct_val;
-//         let res_data = self.request.get_order(order_id.to_string(), custom_id.to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
-//             if res_data_json.len() == 0 {
-//                 Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//             } else {
-//                 let order_info = res_data_json[0].clone();
-//                 let result = format_order_item(order_info, ct_val);
-//                 Ok(result)
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-//         let ct_val = self.market.ct_val;
-//         let res_data = self.request.get_unfilled_orders(symbol_format.to_string(), "".to_string(), "".to_string(), "".to_string(), "100".to_string(), "".to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = 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)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-//         let mut params = json!({
-//             "symbol": symbol_format.to_string(),
-//             "clientOid": custom_id,
-//             "price": price.to_string(),
-//         });
-//         if price.eq(&Decimal::ZERO) {
-//             params["orderType"] = json!("market");
-//             params["force"] = json!("post_only");
-//         } else {
-//             params["orderType"] = json!("limit");
-//             params["force"] = json!("gtc");
-//         };
-//         params["size"] = json!(amount);
-//         match origin_side {
-//             "kd" => {
-//                 params["side"] = json!("buy");
-//             }
-//             "pd" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "kk" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "pk" => {
-//                 params["side"] = json!("buy");
-//             }
-//             _ => { error!("下单参数错误"); }
-//         };
-//         let res_data = self.request.spot_order(params).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let result = Order {
-//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
-//                 custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "NEW".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("328 bitget_spot".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-//         let symbol_format = utils::format_symbol(symbol.clone(), "");
-//         let mut params = json!({
-//             "symbol": symbol_format.to_string(),
-//             "clientOid": custom_id,
-//             "price": price.to_string(),
-//         });
-//         if price.eq(&Decimal::ZERO) {
-//             params["orderType"] = json!("market");
-//             params["force"] = json!("post_only");
-//         } else {
-//             params["orderType"] = json!("limit");
-//             params["force"] = json!("gtc");
-//         };
-//         let size = (amount / ct_val).floor();
-//         params["size"] = json!(size);
-//         match origin_side {
-//             "kd" => {
-//                 params["side"] = json!("buy");
-//             }
-//             "pd" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "kk" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "pk" => {
-//                 params["side"] = json!("buy");
-//             }
-//             _ => { error!("下单参数错误"); }
-//         };
-//         let res_data = self.request.spot_order(params).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let result = Order {
-//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
-//                 custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "NEW".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("380 bitget_spot".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-//         let res_data = self.request.spot_cancel_order(symbol_format.clone(), order_id.to_string(), custom_id.to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let result = Order {
-//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
-//                 custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "REMOVE".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("403 bitget_spot".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-//         let orders_res_data = self.request.get_unfilled_orders(symbol_format.to_string(), "".to_string(), "".to_string(), "".to_string(), "100".to_string(), "".to_string()).await;
-//         if orders_res_data.code == "200" {
-//             let mut result = vec![];
-//             let orders_res_data_str = &orders_res_data.data;
-//             let orders_res_data_json: Vec<serde_json::Value> = serde_json::from_str(orders_res_data_str).unwrap();
-//             for order in orders_res_data_json {
-//                 let order_id = order["orderId"].as_str().unwrap().to_string();
-//                 let cancel_res_data = self.request.spot_cancel_order(symbol_format.clone(), order_id, "".to_string()).await;
-//                 if cancel_res_data.code == "200" {
-//                     let cancel_res_data_str = &cancel_res_data.data;
-//                     let cancel_res_data_json: serde_json::Value = serde_json::from_str(cancel_res_data_str).unwrap();
-//                     result.push(Order {
-//                         id: cancel_res_data_json["orderId"].as_str().unwrap().to_string(),
-//                         custom_id: cancel_res_data_json["clientOid"].as_str().unwrap().to_string(),
-//                         price: Decimal::ZERO,
-//                         amount: Decimal::ZERO,
-//                         deal_amount: Decimal::ZERO,
-//                         avg_price: Decimal::ZERO,
-//                         status: "REMOVE".to_string(),
-//                         order_type: "".to_string(),
-//                         trace_stack: TraceStack::new(0, Instant::now()).on_special("434 bitget_spot".to_string()),
-//                     });
-//                 } else {
-//                     return Err(Error::new(ErrorKind::Other, cancel_res_data.to_string()));
-//                 }
-//             }
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, orders_res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "bitget_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn wallet_transfers(&mut self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error> {
-//         let coin_format = coin.to_string().to_uppercase();
-//         let res_data = self.request.wallet_transfer(from.to_string(), to.to_string(), amount.to_string(), coin_format.clone(), "".to_string(), "".to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let result = res_data_str.clone();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-//         let mut handles = vec![];
-//         // 撤销订单
-//         let cancel = order_command.cancel;
-//         for item in cancel.keys() {
-//             let mut self_clone = self.clone();
-//             let cancel_clone = cancel.clone();
-//             let item_clone = item.clone();
-//             let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let handle = tokio::spawn(async move {
-//                 let result = self_clone.cancel_order(&order_id, &custom_id).await;
-//                 match result {
-//                     Ok(_) => {
-//                         // result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         // 取消失败去查订单。
-//                         let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-//                         match query_rst {
-//                             Ok(order) => {
-//                                 result_sd.send(order).await.unwrap();
-//                             }
-//                             Err(_query_err) => {
-//                                 // error!(?_query_err);
-//                                 // error!("撤单失败,而且查单也失败了,bitget_spot,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-//                             }
-//                         }
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//         // 下单指令
-//         let mut limits = HashMap::new();
-//         limits.extend(order_command.limits_open);
-//         limits.extend(order_command.limits_close);
-//         for item in limits.keys() {
-//             let mut self_clone = self.clone();
-//             let limits_clone = limits.clone();
-//             let item_clone = item.clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let ts = trace_stack.clone();
-//
-//             let handle = tokio::spawn(async move {
-//                 let value = limits_clone[&item_clone].clone();
-//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-//                 let side = value.get(1).unwrap();
-//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-//                 let cid = value.get(3).unwrap();
-//
-//                 //  order_name: [数量,方向,价格,c_id]
-//                 let result = self_clone.take_order(cid, side, price, amount).await;
-//                 match result {
-//                     Ok(mut result) => {
-//                         // 记录此订单完成时间
-//                         // ts.on_after_send();
-//                         result.trace_stack = ts;
-//
-//                         result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         let mut err_order = Order::new();
-//                         err_order.custom_id = cid.clone();
-//                         err_order.status = "REMOVE".to_string();
-//
-//                         result_sd.send(err_order).await.unwrap();
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//         // 检查订单指令
-//         let check = order_command.check;
-//         for item in check.keys() {
-//             let mut self_clone = self.clone();
-//             let check_clone = check.clone();
-//             let item_clone = item.clone();
-//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let handle = tokio::spawn(async move {
-//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-//                 match result {
-//                     Ok(result) => {
-//                         result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//
-//         let futures = FuturesUnordered::from_iter(handles);
-//         let _: Result<Vec<_>, _> = futures.try_collect().await;
-//     }
-// }
-//
-// pub fn format_account_info(balance_data: serde_json::Value) -> Account {
-//     let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
-//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-//     let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
-//     let balance = available_balance + frozen_balance;
-//
-//     Account {
-//         coin: balance_coin,
-//         balance,
-//         available_balance,
-//         frozen_balance,
-//         stocks: Decimal::ZERO,
-//         available_stocks: Decimal::ZERO,
-//         frozen_stocks: Decimal::ZERO,
-//     }
-// }
-//
-// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-//     let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
-//     let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
-//     let status = order["status"].as_str().unwrap_or("");
-//     let base_volume = Decimal::from_str(order["baseVolume"].as_str().unwrap()).unwrap();
-//
-//     let avg_price = Decimal::from_str(order["priceAvg"].as_str().unwrap()).unwrap();
-//
-//     let amount = size * ct_val;
-//     let deal_amount = base_volume * ct_val;
-//     let custom_status = if ["filled", "cancelled"].contains(&status) {
-//         "REMOVE".to_string()
-//     } else if ["init", "live", "new", "partially_filled"].contains(&status) {
-//         "NEW".to_string()
-//     } else {
-//         "NULL".to_string()
-//     };
-//     Order {
-//         id: order["orderId"].as_str().unwrap().to_string(),
-//         custom_id: order["clientOid"].as_str().unwrap().to_string(),
-//         price,
-//         amount,
-//         deal_amount,
-//         avg_price,
-//         status: custom_status,
-//         order_type: order["orderType"].as_str().unwrap().to_string(),
-//         trace_stack: TraceStack::new(0, Instant::now()).on_special("622 bitget_spot".to_string()),
-//     }
-// }

+ 0 - 136
standard/src/bitget_spot_handle.rs

@@ -1,136 +0,0 @@
-// use std::str::FromStr;
-// use rust_decimal::Decimal;
-// use rust_decimal_macros::dec;
-// use serde_json::json;
-// use tokio::time::Instant;
-// use tracing::trace;
-// use exchanges::response_base::ResponseData;
-// use global::trace_stack::TraceStack;
-// use crate::{Account, MarketOrder, Order, SpecialDepth, SpecialOrder, SpecialTicker};
-// use crate::exchange::ExchangeEnum;
-// use crate::handle_info::HandleSwapInfo;
-//
-// // 处理账号信息
-// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-//     let symbol_upper = symbol.to_uppercase();
-//     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-//     let res_data_str = res_data.data;
-//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
-//     let balance_info_default = json!({"available":"0","coin": symbol_array[1],"frozen":"0","limitAvailable":"0","locked":"0","uTime":"0"});
-//     let balance_info = res_data_json.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[1]).unwrap_or(&balance_info_default);
-//     let stocks_info_default = json!({"available":"0","coin": symbol_array[0],"frozen":"0","limitAvailable":"0","locked":"0","uTime":"0"});
-//     let stocks_info = res_data_json.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[0]).unwrap_or(&stocks_info_default);
-//     format_account_info(balance_info.clone(), stocks_info.clone())
-// }
-//
-// pub fn format_account_info(balance_data: serde_json::Value, stocks_data: serde_json::Value) -> Account {
-//     let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
-//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-//     let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
-//     let balance = available_balance + frozen_balance;
-//
-//     let stocks_coin = stocks_data["coin"].as_str().unwrap().to_string().to_uppercase();
-//     let available_stocks = Decimal::from_str(stocks_data["available"].as_str().unwrap()).unwrap();
-//     let frozen_stocks = Decimal::from_str(stocks_data["frozen"].as_str().unwrap()).unwrap();
-//     let stocks = available_stocks + frozen_stocks;
-//
-//     Account {
-//         coin: format!("{}_{}", stocks_coin, balance_coin),
-//         balance,
-//         available_balance,
-//         frozen_balance,
-//         stocks,
-//         available_stocks,
-//         frozen_stocks,
-//     }
-// }
-//
-// // 处理order信息
-// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-//     let res_data_str = res_data.data;
-//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-//     let mut order_info = Vec::new();
-//     for item in res_data_json.iter() {
-//         order_info.push(format_order_item(item.clone(), ct_val));
-//     }
-//     trace!(?order_info);
-//     SpecialOrder {
-//         name: res_data.label,
-//         order: order_info,
-//     }
-// }
-//
-// // 处理订单信息
-// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-//     let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
-//     let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
-//     let status = order["status"].as_str().unwrap_or("");
-//     let acc_base_volume = Decimal::from_str(order["accBaseVolume"].as_str().unwrap()).unwrap();
-//
-//     let avg_price = Decimal::from_str(order["priceAvg"].as_str().unwrap()).unwrap();
-//
-//     let amount = size * ct_val;
-//     let deal_amount = acc_base_volume * ct_val;
-//     let custom_status = if ["filled", "cancelled"].contains(&status) {
-//         "REMOVE".to_string()
-//     } else if ["init", "live", "new", "partially_filled"].contains(&status) {
-//         "NEW".to_string()
-//     } else {
-//         "NULL".to_string()
-//     };
-//     Order {
-//         id: order["orderId"].as_str().unwrap().to_string(),
-//         custom_id: order["clientOid"].as_str().unwrap().to_string(),
-//         price,
-//         amount,
-//         deal_amount,
-//         avg_price,
-//         status: custom_status,
-//         order_type: order["orderType"].as_str().unwrap().to_string(),
-//         trace_stack: TraceStack::new(0, Instant::now()).on_special("89 bitget_spot_handle".to_string()),
-//     }
-// }
-//
-// // 处理特殊深度数据
-// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-//     HandleSwapInfo::handle_special_depth(ExchangeEnum::BitgetSpot, res_data)
-// }
-//
-// // 格式化深度信息
-// pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-//     let mut depth_items: Vec<MarketOrder> = vec![];
-//     for value in value.as_array().unwrap() {
-//         depth_items.push(MarketOrder {
-//             price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-//         })
-//     }
-//     return depth_items;
-// }
-//
-// // 处理特殊Ticker信息
-// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-//     let res_data_str = res_data.data;
-//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-//     format_special_ticker(res_data_json[0].clone(), res_data.label)
-// }
-//
-// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-//     let bp = Decimal::from_str(data["bidPr"].as_str().unwrap()).unwrap();
-//     let bq = Decimal::from_str(data["bidSz"].as_str().unwrap()).unwrap();
-//     let ap = Decimal::from_str(data["askPr"].as_str().unwrap()).unwrap();
-//     let aq = Decimal::from_str(data["askSz"].as_str().unwrap()).unwrap();
-//     let mp = (bp + ap) * dec!(0.5);
-//     let t = Decimal::from_str(data["ts"].as_str().unwrap()).unwrap();
-//     let create_at = data["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-//
-//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-//     let depth_info = vec![bp, bq, ap, aq];
-//     SpecialDepth {
-//         name: label,
-//         depth: depth_info,
-//         ticker: ticker_info,
-//         t,
-//         create_at,
-//     }
-// }

+ 0 - 672
standard/src/bitget_swap.rs

@@ -1,672 +0,0 @@
-use std::collections::{BTreeMap};
-use exchanges::bitget_swap_rest::BitgetSwapRest;
-use std::io::{Error, ErrorKind};
-use tokio::sync::mpsc::Sender;
-use std::str::FromStr;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::{Decimal, MathematicalOps};
-use rust_decimal::prelude::ToPrimitive;
-use rust_decimal_macros::dec;
-use serde_json::{json, Value};
-use tokio::spawn;
-use tokio::time::Instant;
-use tracing::{error, info};
-use global::trace_stack::TraceStack;
-use crate::exchange::ExchangeEnum;
-use crate::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, Ticker, utils};
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct BitgetSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: BitgetSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl BitgetSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BitgetSwap {
-        let market = Market::new();
-        let mut bitget_swap = BitgetSwap {
-            exchange: ExchangeEnum::BitgetSwap,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: BitgetSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        bitget_swap.market = BitgetSwap::get_market(&mut bitget_swap).await.unwrap();
-        // 修改持仓模式
-        let mode_result = bitget_swap.set_dual_mode("", true).await;
-        match mode_result {
-            Ok(ok) => {
-                info!("BitgetSwap:设置持仓模式成功!{:?}", ok);
-            }
-            Err(error) => {
-                error!("BitgetSwap:设置持仓模式失败!{:?}", error)
-            }
-        }
-        // 设置持仓杠杆
-        // let lever_rate_result = bitget_swap.set_dual_leverage("10").await;
-        // match lever_rate_result {
-        //     Ok(ok) => {
-        //         info!("BitgetSwap:设置持仓杠杆成功!{:?}", ok);
-        //     }
-        //     Err(error) => {
-        //         error!("BitgetSwap:设置持仓杠杆失败!{:?}", error)
-        //     }
-        // }
-
-        return bitget_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for BitgetSwap {
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-
-    fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::BitgetSwap }
-
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-
-    fn get_self_is_colo(&self) -> bool { self.is_colo }
-
-    fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
-
-    fn get_self_market(&self) -> Market { self.market.clone() }
-
-    fn get_request_delays(&self) -> Vec<i64> {
-        // self.request.get_delays()
-        vec![]
-    }
-
-    fn get_request_avg_delay(&self) -> Decimal {
-        // self.request.get_avg_delay()
-        Decimal::ZERO
-    }
-
-    fn get_request_max_delay(&self) -> i64 { 0 }
-
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let result = res_data_json["serverTime"].as_str().unwrap().to_string();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let response = self.request.get_account_info().await;
-
-        if response.code == 200 {
-            for data in response.data.as_array().unwrap() {
-                if data["marginCoin"].as_str().unwrap() != "USDT" {
-                    continue
-                }
-
-                // 格式化account信息
-                let mut account = Account {
-                    coin: data["marginCoin"].to_string(),
-                    balance: Decimal::from_str(data["accountEquity"].as_str().unwrap()).unwrap(),
-                    available_balance: Decimal::from_str(data["available"].as_str().unwrap()).unwrap(),
-                    frozen_balance: Default::default(),
-                    stocks: Default::default(),
-                    available_stocks: Default::default(),
-                    frozen_stocks: Default::default(),
-                };
-                account.frozen_balance = account.balance - account.available_balance;
-
-                return Ok(account)
-            }
-
-            Err(Error::new(ErrorKind::NotFound, format!("bitget_usdt_swap 未能找到USDT账户:{}。", response.to_string())))
-        } else {
-            Err(Error::new(ErrorKind::Other, response.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_swap get_spot_account:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> { Err(Error::new(ErrorKind::NotFound, "bitget_swap get_position:该交易所方法未实现".to_string())) }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let params = json!({
-            "productType": "USDT-FUTURES",
-            "marginCoin": "USDT"
-        });
-        let response = self.request.get_all_position(params).await;
-        info!(?response);
-
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("bitget_swap 获取仓位异常{:?}", response).to_string()))
-        }
-
-        // 正常处理持仓信息
-        let mut positions: Vec<Position> = vec![];
-        if response.data.is_null() {
-            return Ok(positions)
-        }
-
-        let positions_json = response.data.as_array().unwrap();
-        for position_json in positions_json {
-            let symbol = position_json["symbol"].as_str().unwrap().to_string();
-            let margin_level = Decimal::from_str(position_json["leverage"].as_str().unwrap()).unwrap();
-            let amount = Decimal::from_str(position_json["total"].as_str().unwrap()).unwrap();
-            let frozen_amount = Decimal::from_str(position_json["locked"].as_str().unwrap()).unwrap();
-            let price = Decimal::from_str(position_json["openPriceAvg"].as_str().unwrap()).unwrap();
-            let profit = Decimal::from_str(position_json["unrealizedPL"].as_str().unwrap()).unwrap();
-            let position_mode = match position_json["posMode"].as_str().unwrap() {
-                "hedge_mode" => {
-                    match position_json["holdSide"].as_str().unwrap() {
-                        "short" => {
-                            PositionModeEnum::Short
-                        }
-                        "long" => {
-                            PositionModeEnum::Long
-                        },
-                        _ => {
-                            panic!("bitget_usdt_swap: 未知的持仓模式与持仓方向: {}, {}",
-                                   position_json["posMode"].as_str().unwrap(), position_json["holdSide"].as_str().unwrap())
-                        }
-                    }
-                },
-                "one_way_mode" => {
-                    PositionModeEnum::Both
-                },
-                _ => {
-                    panic!("bitget_usdt_swap: 未知的持仓模式: {}", position_json["posMode"].as_str().unwrap())
-                }
-            };
-            let margin = Decimal::from_str(position_json["marginSize"].as_str().unwrap()).unwrap();
-
-            positions.push(Position {
-                symbol,
-                margin_level,
-                amount,
-                frozen_amount,
-                price,
-                profit,
-                position_mode,
-                margin,
-            });
-        }
-
-        Ok(positions)
-    }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        return self.get_ticker_symbol(self.symbol.clone()).await
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let res_data = self.request.get_tickers(symbol_format).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let ticker_info = res_data_json[0].clone();
-            let time = (Decimal::from_str(&*ticker_info["ts"].as_str().unwrap()).unwrap() / dec!(1000)).floor().to_i64().unwrap();
-            let result = Ticker {
-                time,
-                high: Decimal::from_str(ticker_info["high24h"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(ticker_info["low24h"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(ticker_info["askPr"].as_str().unwrap()).unwrap(),
-                sell_volume: Default::default(),
-                buy: Decimal::from_str(ticker_info["bidPr"].as_str().unwrap()).unwrap(),
-                buy_volume: Default::default(),
-                last: Decimal::from_str(ticker_info["lastPr"].as_str().unwrap()).unwrap(),
-                volume: Decimal::from_str(ticker_info["quoteVolume"].as_str().unwrap()).unwrap(),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        self.get_market_symbol(self.symbol.clone()).await
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let response = self.request.get_contracts(symbol_format.clone()).await;
-
-        if response.code == 200 {
-            let res_data_json = response.data.as_array().unwrap();
-            let market_info = res_data_json[0].clone();
-
-            info!(?market_info);
-            if !market_info["symbol"].as_str().unwrap().to_string().eq(&symbol_format) {
-                return Err(Error::new(ErrorKind::NotFound, format!("符号未找到:symbol={}, response={:?}", symbol_format, response))).unwrap();
-            }
-
-            let base_asset = market_info["baseCoin"].as_str().unwrap().to_string();
-            let quote_asset = market_info["quoteCoin"].as_str().unwrap().to_string();
-            let price_precision = Decimal::from_str(market_info["pricePlace"].as_str().unwrap()).unwrap();
-            let tick_size = Decimal::TEN.powd(Decimal::NEGATIVE_ONE * price_precision);
-            let amount_precision = Decimal::from_str(market_info["volumePlace"].as_str().unwrap()).unwrap();
-            let amount_size = Decimal::TEN.powd(Decimal::NEGATIVE_ONE * amount_precision);
-            let min_qty = Decimal::NEGATIVE_ONE;
-            let max_qty = Decimal::NEGATIVE_ONE;
-            // let ct_val = Decimal::from_str(&market_info["sizeMultiplier"].as_str().unwrap()).unwrap();
-            let ct_val = Decimal::ONE;
-
-            let result = Market {
-                symbol: format!("{}_{}", base_asset, quote_asset),
-                base_asset,
-                quote_asset,
-                tick_size,
-                amount_size,
-                price_precision,
-                amount_precision,
-                min_qty,
-                max_qty,
-                min_notional: min_qty,
-                max_notional: max_qty,
-                ct_val,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, response.to_string()))
-        }
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let params = json!({
-            "symbol": symbol_format,
-            "productType": "USDT-FUTURES",
-            "clientOid": custom_id,
-            "orderId": order_id
-        });
-
-        let ct_val = self.market.ct_val;
-        let response = self.request.get_order(params).await;
-        if response.code == 200 {
-            let res_data_json = response.data;
-            let result = format_order_item(res_data_json, ct_val);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, response.to_string()))
-        }
-    }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_swap get_orders_list:该交易所方法未实现".to_string()))
-        // let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        // let ct_val = self.market.ct_val;
-        // let res_data = self.request.get_unfilled_orders(symbol_format.to_string(), "".to_string(), "".to_string(), "".to_string(), "100".to_string(), "".to_string()).await;
-        // if res_data.code == 200 {
-        //     let res_data_str = &res_data.data;
-        //     let res_data_json: Vec<serde_json::Value> = 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)
-        // } else {
-        //     Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        // }
-    }
-
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let ct_val = self.market.ct_val;
-
-        return self.take_order_symbol(self.symbol.clone(), ct_val, custom_id, origin_side, price, amount).await;
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(symbol, "");
-        let final_size = amount / ct_val;
-        let mut params = json!({
-            "symbol": symbol_format,
-            "clientOid": custom_id,
-            "productType": "USDT-FUTURES",
-            "marginMode": "crossed",
-            "marginCoin": "USDT",
-            "size": final_size.to_string()
-        });
-        if price.eq(&Decimal::ZERO) {
-            params["orderType"] = json!("market");
-            params["force"] = json!("gtc");
-        } else {
-            params["price"] = json!(price.to_string());
-            params["orderType"] = json!("limit");
-            params["force"] = json!("gtc");
-        };
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-                params["tradeSide"] = json!("open");
-            }
-            "pd" => {
-                params["side"] = json!("buy");
-                params["tradeSide"] = json!("close");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-                params["tradeSide"] = json!("open");
-            }
-            "pk" => {
-                params["side"] = json!("sell");
-                params["tradeSide"] = json!("close");
-            }
-            _ => { panic!("bitget_usdt_swap 下单参数错误"); }
-        };
-        let res_data = self.request.swap_order(params).await;
-        if res_data.code != 200 {
-            return Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-
-        let res_data_json = res_data.data;
-        let result = Order {
-            id: res_data_json["orderId"].as_str().unwrap().to_string(),
-            custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-            price: Decimal::ZERO,
-            amount: Decimal::ZERO,
-            deal_amount: Decimal::ZERO,
-            avg_price: Decimal::ZERO,
-            status: "NEW".to_string(),
-            order_type: "".to_string(),
-            trace_stack: TraceStack::new(0, Instant::now()).on_special("328 bitget_swap".to_string()),
-        };
-        return Ok(result)
-    }
-
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "");
-        let params = json!({
-            "symbol": symbol_format,
-            "productType": "USDT-FUTURES",
-            "clientOid": custom_id,
-            "orderId": order_id
-        });
-        let response = self.request.cancel_order(params).await;
-
-        // 取消失败,进行报错
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, response.to_string()));
-        }
-
-        let res_data_json = response.data;
-        let result = Order {
-            id: res_data_json["orderId"].as_str().unwrap().to_string(),
-            custom_id: res_data_json["clientOid"].as_str().unwrap().to_string(),
-            price: Decimal::ZERO,
-            amount: Decimal::ZERO,
-            deal_amount: Decimal::ZERO,
-            avg_price: Decimal::ZERO,
-            status: "REMOVE".to_string(),
-            order_type: "".to_string(),
-            trace_stack: TraceStack::new(0, Instant::now()).on_special("443 bitget_swap".to_string()),
-        };
-        Ok(result)
-    }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_swap cancel_orders:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let response = self.request.get_pending_orders().await;
-        if response.code == 200 {
-            info!("{}", response.data.to_string());
-            let mut result = vec![];
-
-            if !response.data["entrustedList"].is_null() {
-                let orders_res_data_json = response.data["entrustedList"].as_array().unwrap();
-                for order in orders_res_data_json {
-                    let symbol = order["symbol"].as_str().unwrap().to_string();
-                    let order_id = order["orderId"].as_str().unwrap().to_string();
-                    let params = json!({
-                        "symbol": symbol,
-                        "productType": "USDT-FUTURES",
-                        "orderId": order_id,
-                    });
-                    let cancel_res_data = self.request.cancel_order(params).await;
-                    if cancel_res_data.code == 200 {
-                        let cancel_res_data_json = cancel_res_data.data;
-                        result.push(Order {
-                            id: cancel_res_data_json["orderId"].as_str().unwrap().to_string(),
-                            custom_id: cancel_res_data_json["clientOid"].as_str().unwrap().to_string(),
-                            price: Decimal::ZERO,
-                            amount: Decimal::ZERO,
-                            deal_amount: Decimal::ZERO,
-                            avg_price: Decimal::ZERO,
-                            status: "REMOVE".to_string(),
-                            order_type: "".to_string(),
-                            trace_stack: TraceStack::new(0, Instant::now()).on_special("457 bitget_swap".to_string()),
-                        });
-                    } else {
-                        return Err(Error::new(ErrorKind::Other, cancel_res_data.to_string()));
-                    }
-                }
-            }
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, response.to_string()))
-        }
-    }
-
-    async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_swap take_stop_loss_order:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_swap cancel_stop_loss_order:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, is_dual_mode: bool) -> Result<String, Error> {
-        let pos_mode = if is_dual_mode {
-            "hedge_mode"
-        } else {
-            "one_way_mode"
-        };
-        let params = json!({
-            "productType": "USDT-FUTURES",
-            "posMode": pos_mode,
-        });
-        let response = self.request.set_position_mode(params).await;
-
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::Other, format!("设置持仓模式失败:{:?}", response).to_string()))
-        }
-
-        return Ok(response.data.to_string());
-    }
-
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-        let params = json!({
-            "symbol": "ETHUSDT",
-            "productType": "USDT-FUTURES",
-            "marginCoin": "USDT",
-            "leverage": leverage
-        });
-        let response = self.request.set_leverage(params).await;
-
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::Other, format!("设置杠杆失败:{:?}", response).to_string()))
-        }
-
-        return Ok(response.data.to_string());
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_swap set_auto_deposit_status:该交易所方法未实现".to_string()))
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bitget_swap wallet_transfers:该交易所方法未实现".to_string()))
-        // let coin_format = coin.to_string().to_uppercase();
-        // let res_data = self.request.wallet_transfer(from.to_string(), to.to_string(), amount.to_string(), coin_format.clone(), "".to_string(), "".to_string()).await;
-        // if res_data.code == 200 {
-        //     let res_data_str = &res_data.data;
-        //     let result = res_data_str.clone();
-        //     Ok(result)
-        // } else {
-        //     Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        // }
-    }
-
-    async fn command_order(&mut self, order_command: &mut OrderCommand, trace_stack: &TraceStack) {
-        let mut handles = vec![];
-
-        // 下单指令
-        for item in order_command.limits_open.keys() {
-            let mut ts = trace_stack.clone();
-
-            let amount = Decimal::from_str(&*order_command.limits_open[item].get(0).unwrap().clone()).unwrap();
-            let side = order_command.limits_open[item].get(1).unwrap().clone();
-            let price = Decimal::from_str(&*order_command.limits_open[item].get(2).unwrap().clone()).unwrap();
-            let cid = order_command.limits_open[item].get(3).unwrap().clone();
-
-            //  order_name: [数量,方向,价格,c_id]
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                // TraceStack::show_delay(&ts.ins);
-                ts.on_before_send();
-                let result = self_clone.take_order(cid.as_str(), side.as_str(), price, amount).await;
-                ts.on_after_send();
-
-                match result {
-                    Ok(mut result) => {
-                        result.trace_stack = ts;
-
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        info!(?error);
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        self_clone.order_sender.send(err_order).await.unwrap();
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(handles);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 撤销订单
-        let mut cancel_handlers = vec![];
-        for item in order_command.cancel.keys() {
-            let order_id = order_command.cancel[item].get(1).unwrap().clone();
-            let custom_id = order_command.cancel[item].get(0).unwrap().clone();
-
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                match result {
-                    Ok(_) => {
-                        // result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        // 取消失败去查订单。
-                        let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                        match query_rst {
-                            Ok(order) => {
-                                self_clone.order_sender.send(order).await.unwrap();
-                            }
-                            Err(err) => {
-                                error!("撤单失败,而且查单也失败了,bitget_swap,oid={}, cid={}, err={:?}。", order_id.clone(), custom_id.clone(), err);
-                            }
-                        }
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            cancel_handlers.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(cancel_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 检查订单指令
-        let mut check_handlers = vec![];
-        for item in order_command.check.keys() {
-            let order_id = order_command.check[item].get(1).unwrap().clone();
-            let custom_id = order_command.check[item].get(0).unwrap().clone();
-
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                let result = self_clone.get_order_detail(order_id.as_str(), custom_id.as_str()).await;
-                match result {
-                    Ok(result) => {
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            check_handlers.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(check_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-// pub fn format_account_info(balance_data: Value) -> Account {
-//     let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
-//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-//     let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
-//     let balance = available_balance + frozen_balance;
-//
-//     Account {
-//         coin: balance_coin,
-//         balance,
-//         available_balance,
-//         frozen_balance,
-//         stocks: Decimal::ZERO,
-//         available_stocks: Decimal::ZERO,
-//         frozen_stocks: Decimal::ZERO,
-//     }
-// }
-
-pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["price"].as_str().unwrap_or(order["priceAvg"].as_str().unwrap())).unwrap();
-    let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
-    let status = order["state"].as_str().unwrap();
-    let base_volume = Decimal::from_str(order["quoteVolume"].as_str().unwrap()).unwrap();
-    let avg_price = if order["priceAvg"].is_null() || order["priceAvg"].as_str().unwrap().is_empty() {
-        Decimal::ZERO
-    } else {
-        Decimal::from_str(order["priceAvg"].as_str().unwrap().to_string().as_str()).unwrap()
-    };
-
-    let amount = size * ct_val;
-    let deal_amount = base_volume * ct_val;
-    let custom_status = if ["filled", "cancelled"].contains(&status) {
-        "REMOVE".to_string()
-    } else if ["init", "live", "new", "partially_filled"].contains(&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id: order["orderId"].as_str().unwrap().to_string(),
-        custom_id: order["clientOid"].as_str().unwrap().to_string(),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["orderType"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("700 bitget_swap".to_string()),
-    }
-}

+ 0 - 181
standard/src/bitget_swap_handle.rs

@@ -1,181 +0,0 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use serde_json::Value;
-use tokio::time::Instant;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialOrder};
-
-// 处理账号信息
-pub fn handle_account_info(response: &ResponseData, _symbol: &String) -> Account {
-    let mut rst = Account::new();
-
-    for data in response.data.as_array().unwrap() {
-        if data["marginCoin"].as_str().unwrap() != "USDT" {
-            continue
-        }
-
-        // 格式化account信息
-        let mut account = Account {
-            coin: data["marginCoin"].to_string(),
-            balance: Decimal::from_str(data["usdtEquity"].as_str().unwrap()).unwrap(),
-            available_balance: Decimal::from_str(data["available"].as_str().unwrap()).unwrap(),
-            frozen_balance: Decimal::from_str(data["frozen"].as_str().unwrap()).unwrap(),
-            stocks: Default::default(),
-            available_stocks: Default::default(),
-            frozen_stocks: Default::default(),
-        };
-        account.frozen_balance = account.balance - account.available_balance;
-
-        rst = account
-    }
-
-    return rst;
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_json = res_data.data.as_array().unwrap();
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    }
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-// 处理订单信息
-pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["price"].as_str().unwrap().to_string().as_str()).unwrap();
-    let size = Decimal::from_str(order["size"].as_str().unwrap().to_string().as_str()).unwrap();
-    let binding = order["status"].clone().as_str().unwrap().to_string();
-    let status = binding.as_str();
-    let acc_base_volume = Decimal::from_str(order["accBaseVolume"].as_str().unwrap().to_string().as_str()).unwrap();
-    let avg_price = if order["priceAvg"].is_null() || order["priceAvg"].as_str().unwrap().is_empty() {
-        Decimal::ZERO
-    } else {
-        Decimal::from_str(order["priceAvg"].as_str().unwrap().to_string().as_str()).unwrap()
-    };
-    let c_id = if order["clientOid"].is_null() {
-        ""
-    } else {
-        order["clientOid"].as_str().unwrap()
-    };
-
-    let amount = size * ct_val;
-    let deal_amount = acc_base_volume * ct_val;
-    let custom_status = if ["filled", "canceled"].contains(&status) {
-        "REMOVE".to_string()
-    } else if ["init", "live", "new", "partially_filled"].contains(&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id: order["orderId"].as_str().unwrap().to_string(),
-        custom_id: c_id.to_string(),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["orderType"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("86 bitget_swap_handle".to_string()),
-    }
-}
-
-// 格式化深度信息
-pub fn format_depth_items(value: Value) -> Vec<MarketOrder> {
-    let mut depth_items: Vec<MarketOrder> = vec![];
-    for value in value.as_array().unwrap() {
-        depth_items.push(MarketOrder {
-            price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
-
-// 处理position信息
-pub fn handle_position(res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
-    let res_data_json = res_data.data.as_array().unwrap();
-    res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect()
-}
-
-pub fn format_position_item(position_json: &Value, ct_val: &Decimal) -> Position {
-    let symbol = position_json["instId"].as_str().unwrap().to_string();
-    let margin_level = Decimal::from_i64(position_json["leverage"].as_i64().unwrap()).unwrap();
-    let amount = Decimal::from_str(position_json["total"].as_str().unwrap()).unwrap() * ct_val;
-    let frozen_amount = Decimal::from_str(position_json["frozen"].as_str().unwrap()).unwrap() * ct_val;
-    let price = Decimal::from_str(position_json["openPriceAvg"].as_str().unwrap()).unwrap();
-    let profit = Decimal::from_str(position_json["unrealizedPL"].as_str().unwrap()).unwrap();
-    let position_mode = match position_json["posMode"].as_str().unwrap() {
-        "hedge_mode" => {
-            match position_json["holdSide"].as_str().unwrap() {
-                "short" => {
-                    PositionModeEnum::Short
-                }
-                "long" => {
-                    PositionModeEnum::Long
-                },
-                _ => {
-                    panic!("bitget_usdt_swap: 未知的持仓模式与持仓方向: {}, {}",
-                           position_json["posMode"].as_str().unwrap(), position_json["holdSide"].as_str().unwrap())
-                }
-            }
-        },
-        "one_way_mode" => {
-            PositionModeEnum::Both
-        },
-        _ => {
-            panic!("bitget_usdt_swap: 未知的持仓模式: {}", position_json["posMode"].as_str().unwrap())
-        }
-    };
-    let margin = Decimal::from_str(position_json["marginSize"].as_str().unwrap()).unwrap();
-
-    Position {
-        symbol,
-        margin_level,
-        amount,
-        frozen_amount,
-        price,
-        profit,
-        position_mode,
-        margin,
-    }
-}
-
-// 处理特殊深度数据
-// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-//     HandleSwapInfo::handle_special_depth(ExchangeEnum::BitgetSwap, res_data)
-// }
-
-// // 处理特殊Ticker信息
-// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-//     let res_data_str = res_data.data;
-//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-//     format_special_ticker(res_data_json[0].clone(), res_data.label)
-// }
-//
-// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-//     let bp = Decimal::from_str(data["bidPr"].as_str().unwrap()).unwrap();
-//     let bq = Decimal::from_str(data["bidSz"].as_str().unwrap()).unwrap();
-//     let ap = Decimal::from_str(data["askPr"].as_str().unwrap()).unwrap();
-//     let aq = Decimal::from_str(data["askSz"].as_str().unwrap()).unwrap();
-//     let mp = (bp + ap) * dec!(0.5);
-//     let t = Decimal::from_str(data["ts"].as_str().unwrap()).unwrap();
-//     let create_at = data["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-//
-//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-//     let depth_info = vec![bp, bq, ap, aq];
-//     SpecialDepth {
-//         name: label,
-//         depth: depth_info,
-//         ticker: ticker_info,
-//         t,
-//         create_at,
-//     }
-// }

+ 0 - 752
standard/src/bybit_swap.rs

@@ -1,752 +0,0 @@
-use std::collections::{BTreeMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use serde_json::{from_value, json, Value};
-use rust_decimal::prelude::FromPrimitive;
-use serde::{Deserialize, Serialize};
-use tokio::time::Instant;
-use tracing::{error, info, trace};
-use exchanges::bybit_swap_rest::BybitSwapRest;
-use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand, PositionModeEnum};
-use global::trace_stack::TraceStack;
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-struct SwapTicker {
-    symbol: String,
-    high_price24h: Decimal,
-    low_price24h: Decimal,
-    bid1_price: Decimal,
-    ask1_price: Decimal,
-    last_price: Decimal,
-    volume24h: Decimal
-}
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct BybitSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    symbol_uppercase: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: BybitSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl BybitSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> BybitSwap {
-        let market = Market::new();
-        let mut bybit_swap = BybitSwap {
-            exchange: ExchangeEnum::BybitSwap,
-            symbol: symbol.to_uppercase(),
-            symbol_uppercase: symbol.replace("_", "").to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: BybitSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-
-        // 修改持仓模式
-        let symbol_array: Vec<&str> = symbol.split("_").collect();
-        let mode_result = bybit_swap.set_dual_mode(symbol_array[1], true).await;
-        match mode_result {
-            Ok(_) => {
-                trace!("Bybit:设置持仓模式成功!")
-            }
-            Err(error) => {
-                error!("Bybit:设置持仓模式失败!mode_result={}", error)
-            }
-        }
-        // 获取市场信息
-        bybit_swap.market = BybitSwap::get_market(&mut bybit_swap).await.unwrap_or(bybit_swap.market);
-        return bybit_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for BybitSwap {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    // 获取交易所模式
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::GateSwap
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-    // 获取market信息
-    fn get_self_market(&self) -> Market { self.market.clone() }
-    // 获取请求时间
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-    // 获取请求平均时间
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-    // 获取请求最大时间
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-
-    // 获取服务器时间
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        if res_data.code == 200 {
-            let result = res_data.data["server_time"].to_string();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取账号信息
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let res_data = self.request.get_account_balance(symbol_array[1].parse().unwrap()).await;
-        if res_data.code == 200 {
-            let arr_infos: Vec<Value> = from_value(res_data.data["list"].clone()).unwrap();
-            if arr_infos.len() < 1usize{
-                return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
-            }
-            let coin_infos: Vec<Value> = from_value(arr_infos[0]["coin"].clone()).unwrap();
-            if coin_infos.len() < 1usize{
-               return Err(Error::new(ErrorKind::NotFound, format!("{} 无账户信息", symbol_array[1])));
-            }
-            let balance = Decimal::from_str(coin_infos[0]["equity"].as_str().unwrap()).unwrap();
-            let available_balance = Decimal::from_str(coin_infos[0]["walletBalance"].as_str().unwrap()).unwrap();
-            let frozen_balance = balance - available_balance;
-            let result = Account {
-                coin: symbol_array[1].to_string(),
-                balance,
-                available_balance,
-                frozen_balance,
-                stocks: Decimal::ZERO,
-                available_stocks: Decimal::ZERO,
-                frozen_stocks: Decimal::ZERO,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bybit_swap:该交易所方法未实现".to_string()))
-    }
-
-    // 获取持仓信息
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_positions(symbol, "".to_string()).await;
-        if res_data.code == 200 {
-            let result = res_data.data["list"].as_array().unwrap().iter().map(|item| { format_position_item(item, ct_val) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取所有持仓
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_positions("".to_string(), symbol_array[1].to_string().to_uppercase()).await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let result = res_data.data["list"].as_array().unwrap().iter().map(|item| { format_position_item(item, ct_val) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取市场行情
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.get_tickers(symbol).await;
-        if res_data.code == 200 {
-            let list :Vec<SwapTicker> = from_value(res_data.data["list"].clone()).unwrap_or(Vec::new());
-
-            if list.len() < 1usize {
-                error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
-                return Err(Error::new(ErrorKind::Other, res_data.to_string()));
-            }
-            let value = list[0].clone();
-            Ok(Ticker{
-                time: chrono::Utc::now().timestamp_millis(),
-                high: value.high_price24h,
-                low: value.low_price24h,
-                sell: value.ask1_price,
-                sell_volume: Default::default(),
-                buy: value.bid1_price,
-                buy_volume: Default::default(),
-                last: value.last_price,
-                volume: value.volume24h
-            })
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_upper = symbol.replace("_", "").to_uppercase();
-        let res_data = self.request.get_tickers(symbol_upper.clone()).await;
-        if res_data.code == 200 {
-            let list: Vec<SwapTicker> = from_value(res_data.data["list"].clone()).unwrap();
-            let ticker_info = list.iter().find(|&item| item.symbol == symbol_upper);
-
-            match ticker_info {
-                None => {
-                    error!("bybit_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let result = Ticker {
-                        time: chrono::Utc::now().timestamp_millis(),
-                        high: value.high_price24h,
-                        low: value.low_price24h,
-                        sell: value.ask1_price,
-                        sell_volume: Default::default(),
-                        buy: value.bid1_price,
-                        buy_volume: Default::default(),
-                        last: value.last_price,
-                        volume: value.volume24h
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.get_instruments_info(symbol.clone()).await;
-        if res_data.code == 200 {
-            let arr_data: Vec<Value> = from_value(res_data.data["list"].clone()).unwrap();
-            let market_info = arr_data.iter().find(|&item| item["symbol"].as_str().unwrap() == symbol);
-            match market_info {
-                None => {
-                    error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_coin = value["baseCoin"].as_str().unwrap();
-                    let quote_coin = value["quoteCoin"].as_str().unwrap();
-                    let name = format!("{}_{}",base_coin, quote_coin);
-                    let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
-                    let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let ct_val = Decimal::ONE;
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-                    let max_notional = max_qty * ct_val;
-
-                    let result = Market {
-                        symbol: name,
-                        base_asset: base_coin.to_string(),
-                        quote_asset: quote_coin.to_string(),
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional,
-                        max_notional,
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol = symbol.replace("_", "").to_uppercase();
-        let res_data = self.request.get_instruments_info(symbol.clone()).await;
-        if res_data.code == 200 {
-            let arr_data: Vec<Value> = from_value(res_data.data["list"].clone()).unwrap();
-            let market_info = arr_data.iter().find(|item| item["symbol"].as_str().unwrap() == symbol);
-            match market_info {
-                None => {
-                    error!("bybit_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_coin = value["baseCoin"].as_str().unwrap();
-                    let quote_coin = value["quoteCoin"].as_str().unwrap();
-                    let name = format!("{}_{}",base_coin, quote_coin);
-                    let tick_size = Decimal::from_str(value["priceFilter"]["minPrice"].as_str().unwrap().trim()).unwrap();
-                    let min_qty = Decimal::from_str(value["lotSizeFilter"]["minOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let max_qty = Decimal::from_str(value["lotSizeFilter"]["maxOrderQty"].as_str().unwrap().trim()).unwrap();
-                    let ct_val = Decimal::ONE;
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-                    let max_notional = max_qty * ct_val;
-
-                    let result = Market {
-                        symbol: name,
-                        base_asset: base_coin.to_string(),
-                        quote_asset: quote_coin.to_string(),
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional,
-                        max_notional,
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 获取订单详情
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let ct_val = self.market.ct_val;
-        let id = if !custom_id.trim().eq("") { format!("t-{}", custom_id) } else { String::new() };
-        let res_data = self.request.get_order(symbol, order_id.parse().unwrap(), id).await;
-        if res_data.code == 200 {
-            let res_data_json: Value = res_data.data["list"].clone();
-            if res_data_json.is_array() && res_data_json.as_array().unwrap().len() == 0 {
-                return Err(Error::new(ErrorKind::Other, "没有该订单!"));
-            }
-            let result = format_order_item(res_data_json.as_array().unwrap()[0].clone(), ct_val);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取订单列表
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-       Err(Error::new(ErrorKind::Other, "bybit获取订单列表暂未实现".to_string()))
-    }
-    // 下单接口
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let ct_val = self.market.ct_val;
-        let size = amount / ct_val;
-        let mut params = json!({
-            "orderLinkId": format!("t-{}", custom_id),
-            "symbol": symbol.to_string(),
-            "price": price.to_string(),
-            "category": "linear",
-            "orderType":"Limit",
-            "qty": json!(size),
-            // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
-            "positionIdx": json!(1),
-            "reduceOnly": json!(false)
-        });
-
-        if price.eq(&Decimal::ZERO) {
-            params["timeInForce"] = json!("IOC".to_string());
-        }
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("Buy");
-            }
-            "pd" => {
-                params["side"] = json!("Sell");
-                // 减仓
-                params["reduceOnly"] = json!(true);
-            }
-            "kk" => {
-                params["side"] = json!("Sell");
-                params["positionIdx"] = json!(2);
-            }
-            "pk" => {
-                params["side"] = json!("Buy");
-                // 减仓
-                params["reduceOnly"] = json!(true);
-                params["positionIdx"] = json!(2);
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.swap_order(params).await;
-        if res_data.code == 200 {
-            let result = format_new_order_item(res_data.data, price, size);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_upper = symbol.replace("_", "").trim().to_uppercase();
-        let size = (amount / ct_val).floor();
-        let order_type = if price == Decimal::ZERO {
-            "Market"
-        } else {
-            "Limit"
-        };
-        let mut params = json!({
-            "orderLinkId": format!("t-{}", custom_id),
-            "symbol": symbol_upper,
-            "price": price.to_string(),
-            "category": "linear",
-            "orderType": order_type,
-            "qty": json!(size),
-            // 0.單向持倉 1.買側雙向持倉 2.賣側雙向持倉
-            "positionIdx": json!(1),
-            "reduceOnly": json!(false)
-        });
-
-        if price.eq(&Decimal::ZERO) {
-            params["timeInForce"] = json!("IOC".to_string());
-        }
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("Buy");
-            }
-            "pd" => {
-                params["side"] = json!("Sell");
-                params["positionIdx"] = json!(1);
-                // 减仓
-                params["reduceOnly"] = json!(true);
-            }
-            "kk" => {
-                params["side"] = json!("Sell");
-                params["positionIdx"] = json!(2);
-            }
-            "pk" => {
-                params["side"] = json!("Buy");
-                params["positionIdx"] = json!(2);
-                // 减仓
-                params["reduceOnly"] = json!(true);
-            }
-            _ => { error!("下单参数错误"); }
-        };
-        let res_data = self.request.swap_order(params.clone()).await;
-        if res_data.code == 200 {
-            let result = format_new_order_item(res_data.data, price, size);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 撤销订单
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let id = format!("t-{}", custom_id);
-        let res_data = self.request.cancel_order(symbol, String::from(order_id), id.clone()).await;
-        if res_data.code == 200 {
-            let result = format_cancel_order_item(res_data.data);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 批量撤销订单
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.cancel_orders(symbol).await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let res_arr: Vec<Value> = from_value(res_data.data).unwrap();
-            let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.cancel_orders(symbol).await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let res_arr: Vec<Value> = from_value(res_data.data["list"].clone()).unwrap();
-            let result = res_arr.iter().map(|item| format_cancel_order_item(item.clone())).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bybit_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "bybit_swap:该交易所方法未实现".to_string()))
-    }
-
-    // 设置持仓模式
-    async fn set_dual_mode(&mut self, _coin: &str, is_dual_mode: bool) -> Result<String, Error> {
-        let coin_format = self.symbol_uppercase.clone();
-        let mut mod_num = 0;
-        if is_dual_mode {
-            mod_num = 3;
-        }
-        let res_data = self.request.set_position_mode(coin_format, mod_num).await;
-        if res_data.code == 200 {
-            Ok(res_data.data.to_string())
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 更新双持仓模式下杠杆
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-        let symbol = self.symbol_uppercase.clone();
-        let res_data = self.request.set_leverage(symbol, leverage.to_string()).await;
-        if res_data.code == 200 {
-            Ok(res_data.data.to_string())
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "gate:该交易所方法未实现".to_string())) }
-
-    // 交易账户互转
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        // let coin_format = coin.to_string().to_lowercase();
-        // let res_data = self.request.wallet_transfers(coin_format.clone(), from.to_string(), to.to_string(), amount.to_string(), coin_format.clone()).await;
-        // if res_data.code == 200 {
-        //     let res_data_str = &res_data.data;
-        //     let result = res_data_str.clone();
-        //     Ok(result)
-        // } else {
-        //     Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        // }
-        Err(Error::new(ErrorKind::Other, "暂未实现!"))
-    }
-
-    // 指令下单
-    async fn command_order(&mut self, order_command: &mut OrderCommand, trace_stack: &TraceStack) {
-        // 下单指令
-        let mut handles = vec![];
-        for item in order_command.limits_open.keys() {
-            let mut self_clone = self.clone();
-
-            let amount = Decimal::from_str(order_command.limits_open[item].get(0).unwrap_or(&"0".to_string())).unwrap();
-            let side = order_command.limits_open[item].get(1).unwrap().clone();
-            let price = Decimal::from_str(order_command.limits_open[item].get(2).unwrap_or(&"0".to_string())).unwrap();
-            let cid = order_command.limits_open[item].get(3).unwrap().clone();
-
-            let mut ts = trace_stack.clone();
-
-            let handle = tokio::spawn(async move {
-                ts.on_before_send();
-                // TraceStack::show_delay(&ts.ins);
-                let result = self_clone.take_order(cid.as_str(), side.as_str(), price, amount).await;
-                ts.on_after_send();
-                match result {
-                    Ok(mut result) => {
-                        // 记录此订单完成时间
-                        result.trace_stack = ts;
-
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        error!("bybit:下单失败:{:?}", error);
-
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        self_clone.order_sender.send(err_order).await.unwrap();
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 撤销订单
-        let mut cancel_handles = vec![];
-        for item in order_command.cancel.keys() {
-            let mut self_clone = self.clone();
-
-            let order_id = order_command.cancel[item].get(1).unwrap().clone();
-            let custom_id = order_command.cancel[item].get(0).unwrap().clone();
-
-            let handle = tokio::spawn(async move {
-                let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                match result {
-                    Ok(_) => {
-                        // result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        // 取消失败去查订单。
-                        let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                        match query_rst {
-                            Ok(order) => {
-                                self_clone.order_sender.send(order).await.unwrap();
-                            }
-                            Err(_err) => {
-                                error!("bybit:撤单失败,而且查单也失败了,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                            }
-                        }
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            cancel_handles.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(cancel_handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 检查订单指令
-        let mut check_handles = vec![];
-        for item in order_command.check.keys() {
-            let mut self_clone = self.clone();
-
-            let order_id = order_command.check[item].get(1).unwrap().clone();
-            let custom_id = order_command.check[item].get(0).unwrap().clone();
-
-            let handle = tokio::spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            check_handles.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(check_handles);
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
-    let position_idx = position["positionIdx"].to_string();
-    let mut position_mode = match position_idx.as_str() {
-        "0" => PositionModeEnum::Both,
-        "1" => PositionModeEnum::Long,
-        "2" => PositionModeEnum::Short,
-        _ => {
-            error!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
-        }
-    };
-    let size_str: String = from_value(position["size"].clone()).unwrap();
-    let size = Decimal::from_str(size_str.as_str()).unwrap();
-    let amount = size * ct_val;
-    let mut profit = Decimal::ZERO;
-    let profit_str = position["unrealisedPnl"].as_str().unwrap_or("0");
-    if profit_str != "" {
-        profit = Decimal::from_str(profit_str).unwrap();
-    }
-
-    match position_mode {
-        PositionModeEnum::Both => {
-            position_mode = match amount {
-                amount if amount > Decimal::ZERO => PositionModeEnum::Long,
-                amount if amount < Decimal::ZERO => PositionModeEnum::Short,
-                _ => { PositionModeEnum::Both }
-            }
-        }
-        _ => {}
-    }
-    Position {
-        symbol: position["symbol"].as_str().unwrap_or("").parse().unwrap(),
-        margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(position["avgPrice"].as_str().unwrap()).unwrap(),
-        profit,
-        position_mode,
-        margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
-    }
-}
-
-fn format_cancel_order_item(order: Value) -> Order {
-     Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
-        price: Decimal::ZERO,
-        amount: Decimal::ZERO,
-        deal_amount: Decimal::ZERO,
-        avg_price: Decimal::ZERO,
-        status: "REMOVE".to_string(),
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string())
-    }
-}
-
-fn format_new_order_item(order: Value, price: Decimal, amount: Decimal) -> Order {
-    Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: order["orderLinkId"].as_str().unwrap().replace("t-my-custom-id_", "").replace("t-", ""),
-        price,
-        amount,
-        deal_amount: Decimal::ZERO,
-        avg_price: price,
-        status: "NEW".to_string(),
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string())
-    }
-}
-
-pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
-    let status = order["orderStatus"].as_str().unwrap_or("");
-    let text = order["orderLinkId"].as_str().unwrap_or("");
-    let mut size = Decimal::ZERO;
-    let mut deal_amount = Decimal::ZERO;
-    let mut avg_price = Decimal::ZERO;
-
-    let right_str = order["cumExecQty"].to_string();
-    let size_str = order["qty"].to_string();
-
-    if !order.get("qty").is_some() {
-        size = Decimal::from_str(size_str.as_str()).unwrap();
-        let right_val = Decimal::from_str(order["cumExecValue"].as_str().unwrap()).unwrap();
-        let right = Decimal::from_str(right_str.as_str()).unwrap();
-        if right != Decimal::ZERO {
-            avg_price = right_val / right;
-        }
-        deal_amount = right * ct_val;
-    }
-
-    let amount = size * ct_val;
-    let custom_status = if status == "Filled" || status == "Cancelled" { "REMOVE".to_string() } else if status == "New" { "NEW".to_string() } else {
-        "NULL".to_string()
-    };
-    let rst_order = Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
-        price: Decimal::from_str(order["price"].as_str().unwrap()).unwrap(),
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("688 trace_stack".to_string()),
-    };
-    return rst_order;
-}

+ 0 - 209
standard/src/bybit_swap_handle.rs

@@ -1,209 +0,0 @@
-use std::str::FromStr;
-use std::sync::Arc;
-use lazy_static::lazy_static;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
-use rust_decimal_macros::dec;
-use serde_json::{from_value, Value};
-use tokio::sync::Mutex;
-use tokio::time::Instant;
-use tracing::{error};
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
-
-// 处理账号信息
-pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account {
-    format_account_info(res_data.data.as_array().unwrap().clone(), symbol)
-}
-
-pub fn format_account_info(data: Vec<Value>, symbol: &String) -> Account {
-    let account = data.iter().find(|&item| item["accountType"] == "UNIFIED");
-    match account {
-        None => {
-            error!("Bybit:格式化统一账户信息错误!\nformat_account_info: data={:?}", data);
-            panic!("Bybit:格式化统一账户信息错误!\nformat_account_info: data={:?}", data)
-        }
-        Some(val) => {
-            let arr: Vec<Value> = from_value(val["coin"].clone()).unwrap();
-            let upper_str = symbol.to_uppercase();
-            let symbol_array: Vec<&str> = upper_str.split("_").collect();
-            let balance_info = arr.iter().find(|&item| item["coin"].as_str().unwrap() == symbol_array[1]);
-            match balance_info {
-                None => {
-                    error!("Bybit:格式化usdt余额信息错误!\nformat_account_info: data={:?}", balance_info);
-                    panic!("Bybit:格式化usdt余额信息错误!\nformat_account_info: data={:?}", balance_info)
-                }
-                Some(value) => {
-                    let balance = Decimal::from_str(&value["walletBalance"].as_str().unwrap().to_string()).unwrap();
-                    Account {
-                        coin: symbol_array[1].to_string(),
-                        balance,
-                        available_balance: Decimal::ZERO,
-                        frozen_balance: Decimal::ZERO,
-                        stocks: Decimal::ZERO,
-                        available_stocks: Decimal::ZERO,
-                        frozen_stocks: Decimal::ZERO,
-                    }
-                }
-            }
-        }
-    }
-}
-
-// 处理position信息
-pub fn handle_position(res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
-    res_data.data.as_array().unwrap().iter().map(|item| { format_position_item(item, ct_val) }).collect()
-}
-
-pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
-    let position_idx: String = position["positionIdx"].to_string();
-    let mut position_mode = match position_idx.as_str() {
-        "0" => PositionModeEnum::Both,
-        "1" => PositionModeEnum::Long,
-        "2" => PositionModeEnum::Short,
-        _ => {
-            error!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("bybit_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
-        }
-    };
-    let symbol_mapper = position["symbol"].as_str().unwrap().to_string();
-    let currency = "USDT";
-    let coin = &symbol_mapper[..symbol_mapper.find(currency).unwrap_or(0)];
-    let size_str: String = from_value(position["size"].clone()).unwrap();
-    let size = Decimal::from_str(size_str.as_str()).unwrap();
-    let amount = size * ct_val;
-    match position_mode {
-        PositionModeEnum::Both => {
-            position_mode = match amount {
-                amount if amount > Decimal::ZERO => PositionModeEnum::Long,
-                amount if amount < Decimal::ZERO => PositionModeEnum::Short,
-                _ => { PositionModeEnum::Both }
-            }
-        }
-        _ => {}
-    }
-    Position {
-        symbol: format! {"{}_{}", coin, currency},
-        margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(position["entryPrice"].as_str().unwrap()).unwrap(),
-        profit: Decimal::from_str(position["unrealisedPnl"].as_str().unwrap()).unwrap(),
-        position_mode,
-        margin: Decimal::from_str(position["positionBalance"].as_str().unwrap()).unwrap(),
-    }
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_json: Vec<Value> = res_data.data.as_array().unwrap().clone();
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item.clone(), ct_val));
-    };
-
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
-    let status = order["orderStatus"].as_str().unwrap_or("");
-    let text = order["orderLinkId"].as_str().unwrap_or("");
-    let size = Decimal::from_str(order["qty"].as_str().unwrap()).unwrap();
-    let right = Decimal::from_str(order["cumExecQty"].as_str().unwrap()).unwrap();
-    let right_val = Decimal::from_str(order["cumExecValue"].as_str().unwrap()).unwrap();
-    let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
-    let amount = size * ct_val;
-    let mut avg_price = Decimal::ZERO;
-    if right != Decimal::ZERO {
-        avg_price = right_val / right;
-    }
-    let deal_amount = right * ct_val;
-    let custom_status = if status == "Filled" || status == "Cancelled" { "REMOVE".to_string() } else if status == "New" { "NEW".to_string() } else {
-        "NULL".to_string()
-    };
-    let rst_order = Order {
-        id: format!("{}", order["orderId"].as_str().unwrap()),
-        custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("120 bybit_handle".to_string()),
-    };
-
-    return rst_order;
-}
-
-
-lazy_static! {
-    static ref DEPTH: Arc<Mutex<Vec<Decimal>>> = Arc::new(Mutex::new(vec![dec!(0),dec!(0),dec!(0),dec!(0)]));
-    static ref TICKER: Arc<Mutex<SpecialTicker>> = Arc::new(Mutex::new(SpecialTicker::new()));
-}
-
-// 处理特殊Ticket信息
-pub async fn handle_ticker(res_data: &ResponseData) -> SpecialDepth {
-    let mut depth = DEPTH.lock().await;
-    let mut ticker = TICKER.lock().await;
-
-    let t = Decimal::from_i64(res_data.data["ts"].as_i64().unwrap()).unwrap();
-    let create_at = t.to_i64().unwrap();
-
-    match res_data.data["ask1Price"].as_str() {
-        Some(str) => {
-            let ap = Decimal::from_str(str).unwrap();
-            ticker.sell = ap;
-            depth[2] = ap;
-        }
-        _ => {}
-    }
-    match res_data.data["bid1Price"].as_str() {
-        Some(str) => {
-            let bp = Decimal::from_str(str).unwrap();
-            ticker.buy = bp;
-            depth[0] = bp;
-        }
-        _ => {}
-    }
-    match res_data.data["ask1Size"].as_str() {
-        Some(str) => {
-            depth[3] = Decimal::from_str(str).unwrap();
-        }
-        _ => {}
-    }
-    match res_data.data["bid1Size"].as_str() {
-        Some(str) => {
-            depth[1] = Decimal::from_str(str).unwrap();
-        }
-        _ => {}
-    }
-
-    ticker.mid_price = (ticker.buy + ticker.sell) * dec!(0.5);
-    ticker.t = t;
-    ticker.create_at = 0;
-
-    SpecialDepth {
-        name: res_data.label.clone(),
-        depth: depth.clone(),
-        ticker: ticker.clone(),
-        t,
-        create_at,
-    }
-}
-
-pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-    let mut depth_items: Vec<MarketOrder> = vec![];
-    for val in value.as_array().unwrap() {
-        let arr = val.as_array().unwrap();
-        depth_items.push(MarketOrder {
-            price: Decimal::from_str(arr[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(arr[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}

+ 0 - 775
standard/src/coinex_swap.rs

@@ -1,775 +0,0 @@
-use std::collections::{BTreeMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
-use serde_json::{Value};
-use tokio::spawn;
-use tokio::time::Instant;
-use tracing::{error, info, trace};
-use exchanges::coinex_swap_rest::CoinexSwapRest;
-use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, OrderCommand, PositionModeEnum, utils};
-use global::trace_stack::TraceStack;
-use crate::utils::get_tick_size;
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct CoinexSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: CoinexSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl CoinexSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> CoinexSwap {
-        let market = Market::new();
-        let mut coinex_swap = CoinexSwap {
-            exchange: ExchangeEnum::CoinexSwap,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: CoinexSwapRest::new(params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-
-        // 修改持仓模式
-        let symbol_array: Vec<&str> = symbol.split("_").collect();
-        let mode_result = coinex_swap.set_dual_mode(symbol_array[1], true).await;
-        match mode_result {
-            Ok(_) => {
-                trace!("Coinex:设置持仓模式成功!")
-            }
-            Err(error) => {
-                error!("Coinex:设置持仓模式失败!mode_result={}", error)
-            }
-        }
-        // 获取市场信息
-        coinex_swap.market = CoinexSwap::get_market(&mut coinex_swap).await.unwrap_or(coinex_swap.market);
-        // 设置持仓杠杆
-        let lever_rate_result = coinex_swap.set_dual_leverage("10").await;
-        match lever_rate_result {
-            Ok(ok) => {
-                info!("Coinex:设置持仓杠杆成功!{:?}", ok);
-            }
-            Err(error) => {
-                error!("Coinex:设置持仓杠杆失败!{:?}", error)
-            }
-        }
-        return coinex_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for CoinexSwap {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    // 获取交易所模式
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::CoinexSwap
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-    // 获取market信息
-    fn get_self_market(&self) -> Market { self.market.clone() }
-    // 获取请求时间
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-    // 获取请求平均时间
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-    // 获取请求最大时间
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-
-    // 获取服务器时间
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        if res_data.code == 200 {
-            let res_data_json: Value = res_data.data;
-            let result = res_data_json["timestamp"].to_string();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取账号信息
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let coin = symbol_array[1].to_string().to_uppercase();
-        let res_data = self.request.get_account().await;
-        if res_data.code == 200 {
-            if res_data.data.is_array() {
-                let res_data_array = res_data.data.as_array().unwrap();
-                for res_data_json in res_data_array.iter() {
-                    if res_data_json["ccy"].as_str().unwrap() == coin {
-                        let frozen_balance= Decimal::from_str(res_data_json["frozen"].as_str().unwrap()).unwrap();
-                        let available_balance = Decimal::from_str(res_data_json["available"].as_str().unwrap()).unwrap();
-                        let balance = frozen_balance + available_balance;
-                        let result = Account {
-                            coin: symbol_array[1].to_string(),
-                            balance,
-                            available_balance,
-                            frozen_balance,
-                            stocks: Decimal::ZERO,
-                            available_stocks: Decimal::ZERO,
-                            frozen_stocks: Decimal::ZERO,
-                        };
-                        return Ok(result);
-                    }
-                }
-            }
-        }
-        Err(Error::new(ErrorKind::Other, res_data.to_string()))
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "coinex_swap:该方法暂未实现".to_string()))
-    }
-
-    // 获取持仓信息
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol: String = self.symbol.replace("_", "").to_uppercase();
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_position(symbol).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let result = res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 获取所有持仓
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let res_data = self.request.get_user_position().await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let res_data_json = res_data.data.as_array().unwrap();
-            let result = res_data_json.iter().map(|item| { format_position_item(item, Decimal::ONE) }).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取市场行情
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol: String = self.symbol.replace("_", "");
-        let res_data = self.request.get_ticker(symbol.clone()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let ticker_info = res_data_json.iter().find(|item| item["market"].as_str().unwrap() == symbol);
-            match ticker_info {
-                None => {
-                    error!("coinex_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let result = Ticker {
-                        time: chrono::Utc::now().timestamp_millis(),
-                        high: Decimal::from_str(value["high"].as_str().unwrap()).unwrap(),
-                        low: Decimal::from_str(value["low"].as_str().unwrap()).unwrap(),
-                        sell: Decimal::from_str(value["last"].as_str().unwrap()).unwrap(),
-                        sell_volume: Default::default(),
-                        buy: Decimal::from_str(value["last"].as_str().unwrap()).unwrap(),
-                        buy_volume: Default::default(),
-                        last: Decimal::from_str(value["last"].as_str().unwrap()).unwrap(),
-                        volume: Decimal::from_str(value["volume"].as_str().unwrap()).unwrap(),
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol_param: String) -> Result<Ticker, Error> {
-        let symbol: String = symbol_param.replace("_", "").to_uppercase();
-        let res_data = self.request.get_ticker(symbol.clone()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let ticker_info = res_data_json.iter().find(|item| item["contract"].as_str().unwrap() == symbol);
-            match ticker_info {
-                None => {
-                    error!("coinex_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let result = Ticker {
-                        time: chrono::Utc::now().timestamp_millis(),
-                        high: Decimal::from_str(value["high"].as_str().unwrap()).unwrap(),
-                        low: Decimal::from_str(value["low"].as_str().unwrap()).unwrap(),
-                        sell: Decimal::from_str(value["last"].as_str().unwrap()).unwrap(),
-                        sell_volume: Default::default(),
-                        buy: Decimal::from_str(value["last"].as_str().unwrap()).unwrap(),
-                        buy_volume: Default::default(),
-                        last: Decimal::from_str(value["last"].as_str().unwrap()).unwrap(),
-                        volume: Decimal::from_str(value["volume"].as_str().unwrap()).unwrap(),
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-        let symbol = format!("{}{}", symbol_array[0], symbol_array[1]);
-        let res_data = self.request.get_market_details(symbol.clone()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let market_info = res_data_json.iter().find(|item| item["market"].as_str().unwrap() == symbol);
-            match market_info {
-                None => {
-                    error!("coinex_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    // 报价精度字符串
-                    let price_precision_i64 = value["quote_ccy_precision"].as_i64().unwrap();
-                    // 价格最小变动数值
-                    let tick_size = get_tick_size(price_precision_i64.to_u32().unwrap());
-                    // 报价精度
-                    let price_precision = Decimal::from_i64(price_precision_i64).unwrap();
-                    // 最小数量
-                    let min_qty = Decimal::from_str(value["min_amount"].as_str().unwrap()).unwrap();
-                    // 数量没有最大值
-                    let max_qty = Decimal::MAX;
-                    // 没有张数
-                    let ct_val = Decimal::ONE;
-
-                    let amount_size = min_qty * ct_val;
-                    let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-                    let max_notional = max_qty * ct_val;
-
-                    let result = Market {
-                        symbol: self.symbol.clone(),
-                        base_asset: symbol_array[0].to_string(),
-                        quote_asset: symbol_array[1].to_string(),
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional,
-                        max_notional,
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_upper = symbol.to_uppercase();
-        let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-        let symbol = format!("{}{}", symbol_array[0], symbol_array[1]);
-        let res_data = self.request.get_market_details(symbol.clone()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let market_info = res_data_json.iter().find(|item| item["name"].as_str().unwrap() == symbol.clone());
-            match market_info {
-                None => {
-                    error!("coinex_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let tick_size = Decimal::from_str(value["quote_ccy_precision"].as_str().unwrap()).unwrap();
-                    let min_qty = Decimal::from_str(&value["min_amount"].to_string()).unwrap();
-                    // 数量没有最大值
-                    let max_qty = Decimal::MAX;
-                    // 没有张数
-                    let ct_val = Decimal::ONE;
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-                    let max_notional = max_qty * ct_val;
-
-                    let result = Market {
-                        symbol: self.symbol.clone(),
-                        base_asset: symbol_array[0].to_string(),
-                        quote_asset: symbol_array[1].to_string(),
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty,
-                        min_notional,
-                        max_notional,
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 获取订单详情
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol = self.symbol.replace("_", "").to_uppercase();
-        let ct_val = self.market.ct_val;
-        let res_data;
-        let status ;
-        if order_id != "" {
-            status = "";
-            res_data = self.request.get_order_details(order_id.to_string(), symbol).await;
-        } else if custom_id != "" {
-            // 通过客户端id查询  只有未完成的订单才能查询出来
-            res_data = self.request.get_pending_order(custom_id.to_string()).await;
-            status = "open";
-        } else {
-            return Err(Error::new(ErrorKind::Other, format!("订单id和客户端id都为空,查询失败!order_id :{}, custom_id: {}", order_id, custom_id)));
-        }
-
-        if res_data.code == 200 {
-            // info!("order_detail {}", res_data.data);
-            if res_data.data.is_array() {
-                let res_data_json = res_data.data.as_array().unwrap();
-                if res_data_json.len() == 0 { // 已取消或已成交
-                    return Ok(Order{
-                        id: order_id.to_string(),
-                        custom_id: custom_id.to_string(),
-                        price: Default::default(),
-                        amount: Default::default(),
-                        deal_amount: Default::default(),
-                        avg_price: Default::default(),
-                        status: "NULL".to_string(),
-                        order_type: "".to_string(),
-                        trace_stack: TraceStack::new(0, Instant::now()).on_special("358 coinex_swap".to_string()),
-                    })
-                } else { // 待成交
-                    let mut result = format_order_item(res_data_json[0].clone(), ct_val, status);
-                    result.custom_id = custom_id.to_string();
-                    result.id = order_id.to_string();
-                    Ok(result)
-                }
-            } else {
-                let mut result = format_order_item(res_data.data, ct_val, status);
-                result.custom_id = custom_id.to_string();
-                result.id = order_id.to_string();
-                Ok(result)
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 获取未完成订单列表
-    async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error> {
-        let symbol = self.symbol.replace("_", "").to_uppercase();
-        let ct_val = self.market.ct_val;
-        let status_order;
-        let res_data;
-        if status == "pending" {
-            res_data = self.request.get_pending_orders().await;
-            status_order = "open";
-        } else if status == "finish" {
-            res_data = self.request.get_finished_orders().await;
-            status_order = "filled";
-        }else{
-            return Err(Error::new(ErrorKind::Other, status));
-        }
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            if res_data_json.len() ==0 {
-               return Ok(vec![])
-            }
-            let order_info: Vec<_> = res_data_json.iter().filter(|item| item["market"].as_str().unwrap_or("") == symbol).collect();
-            let result = order_info.iter().map(|&item| format_order_item(item.clone(), ct_val, status_order)).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 下单接口
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol = self.symbol.replace("_", "").to_uppercase();
-        let ct_val = self.market.ct_val;
-        let order_side;
-        let position_side;
-        let size = utils::truncate_decimal(amount, self.market.amount_precision.to_u32().unwrap());
-        if size <= Decimal::ZERO {
-            error!("下单数量异常 amount {} amount_precision {} size {}", amount, self.market.amount_precision.to_u32().unwrap(), size);
-            return Err(Error::new(ErrorKind::Other, format!("下单数量错误 amount:{}", amount)));
-        }
-        match origin_side {
-            "kd" => {
-                position_side = "long";
-                order_side = "buy";
-            }
-            "pd" => {
-                position_side = "long";
-                order_side = "sell";
-            }
-            "kk" => {
-                position_side = "short";
-                order_side = "sell";
-            }
-            "pk" => {
-                position_side = "short";
-                order_side = "buy";
-            }
-            _ => {
-                error!("下单参数错误");
-                position_side = "error";
-                order_side = "error";
-            }
-        };
-        let res_data = self.request.order(symbol, position_side.to_string(), order_side.to_string(), size, price, custom_id.to_string()).await;
-        if res_data.code == 200 {
-            let res_data_json: Value = res_data.data;
-            // info!("take_order {}", res_data_json);
-            let result = format_order_item(res_data_json, ct_val, "open");
-            Ok(result)
-        } else {
-            // error!("take_order error {}", res_data.data);
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol_y: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol = symbol_y.replace("_", "").to_uppercase();
-        let order_side;
-        let position_side;
-        let size = (amount / ct_val).floor();
-        match origin_side {
-            "kd" => {
-                position_side = "long";
-                order_side = "buy";
-            }
-            "pd" => {
-                position_side = "long";
-                order_side = "sell";
-            }
-            "kk" => {
-                position_side = "short";
-                order_side = "sell";
-            }
-            "pk" => {
-                position_side = "short";
-                order_side = "buy";
-            }
-            _ => {
-                error!("下单参数错误");
-                position_side = "error";
-                order_side = "error";
-            }
-        };
-        let res_data = self.request.order(symbol, position_side.to_string(), order_side.to_string(), size, price, custom_id.to_string()).await;
-        if res_data.code == 200 {
-            let res_data_json: Value = res_data.data;
-            let result = format_order_item(res_data_json, ct_val, "open");
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    // 撤销订单
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol = self.symbol.replace("_", "").to_uppercase();
-
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.cancel_order(symbol, order_id, custom_id).await;
-        if res_data.code == 200 {
-            let res_data_json: Value = res_data.data;
-            let mut result;
-            if res_data_json.is_null(){
-                result = Order{
-                    id: custom_id.to_string(),
-                    custom_id: order_id.to_string(),
-                    price: Default::default(),
-                    amount: Default::default(),
-                    deal_amount: Default::default(),
-                    avg_price: Default::default(),
-                    status: "NULL".to_string(),
-                    order_type: "".to_string(),
-                    trace_stack:  TraceStack::new(0, Instant::now()).on_special("513 coinex_swap".to_string())
-                };
-            } else {
-                result = format_order_item(res_data_json, ct_val, "canceled");
-                result.custom_id = custom_id.to_string();
-                result.id = order_id.to_string();
-            }
-            Ok(result)
-        } else {
-            let message = format!("撤单HTTP请求失败  order_id: {}, custom_id: {}, res_data: {:?}", order_id, custom_id, res_data);
-            Err(Error::new(ErrorKind::Other, message))
-        }
-    }
-    // 批量撤销订单
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol = self.symbol.replace("_", "").to_uppercase();
-        let res_data = self.request.cancel_order_all(symbol).await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let result = vec![];
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let orders_res_data = self.request.get_pending_orders().await;
-        if orders_res_data.code == 200 {
-            let result = vec![];
-            let orders_res_data_json = orders_res_data.data.as_array().unwrap();
-            for order in orders_res_data_json {
-                let cancel_res_data = self.request.cancel_order_all( order["market"].as_str().unwrap().to_string()).await;
-                if cancel_res_data.code != 200 {
-                    return Err(Error::new(ErrorKind::Other, cancel_res_data.to_string()));
-                }
-            }
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, orders_res_data.to_string()))
-        }
-    }
-
-    async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "coin_ex:该交易所暂未实现自动订单下单".to_string()))
-    }
-
-    async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "coin_ex:该交易所暂未实现取消自动订单".to_string()))
-    }
-
-    // 设置持仓模式
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "coin_ex:该交易所只允许单向持仓,无法设置持仓模式".to_string()))
-    }
-
-    // 更新杠杆
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-        let leverage_int = leverage.parse::<i32>().unwrap();
-        let symbol = self.symbol.replace("_", "").to_uppercase();
-        let res_data = self.request.setting_dual_leverage(symbol, leverage_int).await;
-        if res_data.code == 200 {
-            let res_data_str = &res_data.data;
-            let result = res_data_str.clone();
-            Ok(result.to_string())
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "Coinex:该交易所方法未实现".to_string())) }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "Coinex wallet_transfers:该交易所方法未实现".to_string()))
-    }
-
-    // 指令下单
-    async fn command_order(&mut self, order_command: &mut OrderCommand, trace_stack: &TraceStack) {
-        let mut handles = vec![];
-
-        // 下单指令
-        for item in order_command.limits_open.keys() {
-            let mut ts = trace_stack.clone();
-
-            let amount = Decimal::from_str(&*order_command.limits_open[item].get(0).unwrap().clone()).unwrap();
-            let side = order_command.limits_open[item].get(1).unwrap().clone();
-            let price = Decimal::from_str(&*order_command.limits_open[item].get(2).unwrap().clone()).unwrap();
-            let cid = order_command.limits_open[item].get(3).unwrap().clone();
-
-            //  order_name: [数量,方向,价格,c_id]
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                // info!("数量 {},方向 {},价格 {},c_id {}", amount, side, price, cid);
-                ts.on_before_send();
-                let result = self_clone.take_order(&cid, &side, price, amount).await;
-                ts.on_after_send();
-
-                match result {
-                    Ok(mut result) => {
-                        result.trace_stack = ts;
-                        // info!("数量 {},方向 {},价格 {},c_id {}", amount, side, price, cid);
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-                        // info!("coinex下单error 数量: {},方向: {},价格: {},c_id: {}, err: {}", amount, side, price, cid, error);
-                        self_clone.order_sender.send(err_order).await.unwrap();
-                        self_clone.error_sender.send(error).await.unwrap();
-                        // 触发限频
-                        // if error_info.to_string().contains("213:Please don't try too frequently") {
-                        //     Err(Error::new(ErrorKind::Other, "触发限频, 请调整下单频率"))
-                        // }
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(handles);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 撤销订单
-        let mut cancel_handlers = vec![];
-        for item in order_command.cancel.keys() {
-            let order_id = order_command.cancel[item].get(1).unwrap().clone();
-            let custom_id = order_command.cancel[item].get(0).unwrap().clone();
-
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                match result {
-                    Ok(order) => {
-                        if order.status == "REMOVE" {
-                            // 由于有时撤单成功ws不推送,所以加入rest
-                            self_clone.order_sender.send(order).await.unwrap();
-                        }
-                    }
-                    Err(error) => {
-                        // info!("撤单失败:{:?}", error.to_string());
-                        // 取消失败去查订单。
-                        let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                        match query_rst {
-                            Ok(order) => {
-                                // info!("查单 订单详情:{:?}", order);
-                                self_clone.order_sender.send(order).await.unwrap();
-                            }
-                            Err(_err) => {
-                                // warn!("撤单失败,而且查单也失败了,Coinex_io_swap,oid={}, cid={} err={:?}", order_id.clone(), custom_id.clone(), err);
-                                // panic!("撤单失败,而且查单也失败了,Coinex_io_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                            }
-                        }
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            cancel_handlers.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(cancel_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 检查订单指令
-        let mut check_handlers = vec![];
-        for item in order_command.check.keys() {
-            let order_id = order_command.check[item].get(1).unwrap().clone();
-            let custom_id = order_command.check[item].get(0).unwrap().clone();
-
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            check_handlers.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(check_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_position_item(position: &Value, ct_val: Decimal) -> Position {
-    let position_mode = match position["side"].as_str().unwrap_or("") {
-        "long" => PositionModeEnum::Long,
-        "short" => PositionModeEnum::Short,
-        _ => {
-            error!("coinex_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("coinex_swap:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
-        }
-    };
-    let size = Decimal::from_str(&position["open_interest"].as_str().unwrap()).unwrap();
-    let amount = size * ct_val;
-    Position {
-        symbol: position["market"].as_str().unwrap_or("").parse().unwrap(),
-        margin_level: Decimal::from_str(position["leverage"].as_str().unwrap()).unwrap(),
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(position["avg_entry_price"].as_str().unwrap()).unwrap(),
-        profit: Decimal::from_str(position["unrealized_pnl"].as_str().unwrap()).unwrap(),
-        position_mode,
-        margin: Decimal::from_str(position["ath_margin_size"].as_str().unwrap()).unwrap(),
-    }
-}
-
-pub fn format_order_item(order: Value, ct_val: Decimal, status: &str) -> Order {
-    // info!("order_format {}", order);
-    let size;
-    match order["amount"].as_str() {
-        Some(val) => {
-            size = Decimal::from_str(val).unwrap()
-        },
-        None => {
-            error!("coinex_swap:格式化订单大小错误!\nformat_order_item:order={:?} status={}", order, status);
-            panic!("coinex_swap:格式化订单大小失败,退出程序!");
-        }
-    }
-    // info!("order {}", order);
-    // 通过客户端id查询订单 只能查出未完成订单(没有状态字段)
-    let status = order["status"].as_str().unwrap_or(status);
-    let text = order["client_id"].as_str().unwrap_or("");
-
-    let deal_amount = Decimal::from_str(&order["filled_amount"].as_str().unwrap()).unwrap();
-    let filled_value = Decimal::from_str(&order["filled_value"].as_str().unwrap()).unwrap();
-
-    let amount = size * ct_val;
-    let mut avg_price = Decimal::ZERO;
-    if deal_amount != Decimal::ZERO{
-        avg_price = filled_value/deal_amount;
-    }
-    let custom_status = if status == "filled" || status == "canceled" {
-        "REMOVE".to_string()
-    } else if status == "open" || status == "part_filled" || status == "part_canceled" {
-        "NEW".to_string()
-    } else {
-        error!("coinex_swap:格式化订单状态错误!\nformat_order_item:order={:?}", order);
-        "NULL".to_string()
-    };
-    let rst_order = Order {
-        id: order["order_id"].to_string(),
-        custom_id: text.to_string(),
-        price: Decimal::from_str(order["price"].as_str().unwrap()).unwrap(),
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("765 trace_stack".to_string()),
-    };
-    return rst_order;
-}

+ 0 - 158
standard/src/coinex_swap_handle.rs

@@ -1,158 +0,0 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use serde_json::Value;
-use tokio::time::Instant;
-use tracing::{error};
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
-
-// 处理账号信息
-pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account {
-    let res_data_json = res_data.data["balance_list"].as_array().unwrap();
-    format_account_info(res_data_json, symbol)
-}
-
-pub fn format_account_info(data: &Vec<Value>, symbol: &String) -> Account {
-    let symbol_upper = symbol.to_uppercase();
-    let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-    let balance_info = data.iter().find(|&item| item["ccy"].as_str().unwrap().contains(symbol_array[1]));
-
-    match balance_info {
-        None => {
-            error!("Coinex:格式化账号信息错误!\nformat_account_info: data={:?}", data);
-            panic!("Coinex:格式化账号信息错误!\nformat_account_info: data={:?}", data)
-        }
-        Some(value) => {
-            let frozen_balance= Decimal::from_str(&value["frozen"].as_str().unwrap()).unwrap();
-            let available_balance = Decimal::from_str(&value["available"].as_str().unwrap()).unwrap();
-            let margin = Decimal::from_str(&value["margin"].as_str().unwrap()).unwrap();
-            // let profit_unreal = Decimal::from_str(&value["unrealized_pnl"].as_str().unwrap()).unwrap();
-            let balance = frozen_balance + available_balance + margin;
-            Account {
-                coin: symbol_array[1].to_string(),
-                balance,
-                available_balance: Decimal::ZERO,
-                frozen_balance: Decimal::ZERO,
-                stocks: Decimal::ZERO,
-                available_stocks: Decimal::ZERO,
-                frozen_stocks: Decimal::ZERO,
-            }
-        }
-    }
-}
-
-// 处理position信息
-pub fn handle_position(res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
-    let res_data_json = &res_data.data["position"];
-    let position =  format_position_item(res_data_json, ct_val);
-    vec![position]
-}
-
-pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
-    let position_mode = match position["side"].as_str().unwrap_or("") {
-        "long" => PositionModeEnum::Long,
-        "short" => PositionModeEnum::Short,
-        _ => {
-            error!("Coinex:格式化持仓模式错误!\nformat_position_item:position={:?}", position);
-            panic!("Coinex:格式化持仓模式错误!\nformat_position_item:position={:?}", position)
-        }
-    };
-    let size = Decimal::from_str(&position["open_interest"].as_str().unwrap()).unwrap();
-    let amount = size * ct_val;
-    Position {
-        symbol: position["market"].as_str().unwrap().to_string(),
-        margin_level: Decimal::from_str(&position["leverage"].as_str().unwrap()).unwrap(),
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: Decimal::from_str(&position["avg_entry_price"].as_str().unwrap()).unwrap(),
-        profit: Decimal::from_str(&position["unrealized_pnl"].as_str().unwrap()).unwrap(),
-        position_mode,
-        margin: Decimal::from_str(&position["ath_margin_size"].as_str().unwrap()).unwrap(),
-    }
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let status = res_data.data["event"].as_str().unwrap();
-    let res_data_json = &res_data.data["order"];
-    let order_info = format_order_item(res_data_json, ct_val, status);
-
-    SpecialOrder {
-        name: res_data.label,
-        order: vec![order_info],
-    }
-}
-
-pub fn format_order_item(order: &Value, ct_val: Decimal, status: &str) -> Order {
-    let text = order["client_id"].as_str().unwrap_or("");
-    let size = Decimal::from_str(order["amount"].as_str().unwrap()).unwrap();
-    let left = Decimal::from_str(order["unfilled_amount"].as_str().unwrap()).unwrap();
-    // 已成交量
-    let filled_amount = size - left;
-    // 成交额
-    let filled_value = Decimal::from_str(order["filled_value"].as_str().unwrap()).unwrap();
-    // 成交均价
-    let mut avg_price = Decimal::ZERO;
-    if filled_amount > Decimal::ZERO{
-        avg_price = filled_value/filled_amount;
-    }
-    let amount = size * ct_val;
-    let deal_amount = filled_amount * ct_val;
-    let custom_status = if status == "finish" { "REMOVE".to_string() } else if status == "put" || status == "update" { "NEW".to_string() } else {
-        "NULL".to_string()
-    };
-    let rst_order = Order {
-        id: order["order_id"].to_string(),
-        custom_id: text.replace("t-my-custom-id_", "").replace("t-", ""),
-        price: Decimal::from_str(order["price"].as_str().unwrap()).unwrap(),
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: "limit".to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("120 Coinex_handle".to_string()),
-    };
-    return rst_order;
-}
-
-// 处理特殊Ticket信息
-pub fn handle_ticker(res_data: &ResponseData) -> SpecialDepth {
-    let depth = &res_data.data["depth"];
-
-    let bp = Decimal::from_str(depth["bids"][0][0].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_str(depth["bids"][0][1].as_str().unwrap()).unwrap();
-    let ap = Decimal::from_str(depth["asks"][0][0].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_str(depth["asks"][0][1].as_str().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_i64(depth.get("checksum").unwrap().as_i64().unwrap_or(0i64)).unwrap();
-    let create_at = depth.get("updated_at").unwrap().as_i64().unwrap() * 1000;
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-
-    SpecialDepth {
-        name: (*res_data).label.clone(),
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
-
-pub fn format_depth_items(value: &Value) -> Vec<MarketOrder> {
-    if value.is_null() {
-        return vec![];
-    }
-    let mut depth_items: Vec<MarketOrder> = vec![];
-    for value in value.as_array().unwrap() {
-        let values = value.as_array().unwrap();
-        depth_items.push(MarketOrder {
-            price: Decimal::from_str(values[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_str(values[1].as_str().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}

+ 1 - 53
standard/src/exchange.rs

@@ -2,18 +2,7 @@ use std::collections::{BTreeMap};
 use std::io::Error;
 use std::io::Error;
 use tokio::sync::mpsc::Sender;
 use tokio::sync::mpsc::Sender;
 use crate::{Order, Platform};
 use crate::{Order, Platform};
-use crate::binance_swap::BinanceSwap;
-// use crate::binance_spot::BinanceSpot;
-// use crate::gate_spot::GateSpot;
 use crate::gate_swap::GateSwap;
 use crate::gate_swap::GateSwap;
-use crate::kucoin_swap::KucoinSwap;
-// use crate::bitget_spot::BitgetSpot;
-use crate::bybit_swap::BybitSwap;
-use crate::bitget_swap::BitgetSwap;
-use crate::coinex_swap::CoinexSwap;
-// use crate::kucoin_spot::KucoinSpot;
-// use crate::okx_swap::OkxSwap;
-use crate::htx_swap::HtxSwap;
 
 
 /// 交易所交易模式枚举
 /// 交易所交易模式枚举
 /// - `BinanceSwap`: Binance交易所期货;
 /// - `BinanceSwap`: Binance交易所期货;
@@ -23,18 +12,7 @@ use crate::htx_swap::HtxSwap;
 /// - `KucoinSwap`: kucoin交易所期货;
 /// - `KucoinSwap`: kucoin交易所期货;
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ExchangeEnum {
 pub enum ExchangeEnum {
-    BinanceSwap,
-    // BinanceSpot,
-    GateSwap,
-    // GateSpot,
-    KucoinSwap,
-    // KucoinSpot,
-    // OkxSwap,
-    // BitgetSpot,
-    CoinexSwap,
-    BitgetSwap,
-    BybitSwap,
-    HtxSwap
+    GateSwap
 }
 }
 
 
 /// Exchange结构体
 /// Exchange结构体
@@ -79,39 +57,9 @@ pub struct Exchange;
 impl Exchange {
 impl Exchange {
     pub async fn new(exchange: ExchangeEnum, symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> Box<dyn Platform + Send + Sync> {
     pub async fn new(exchange: ExchangeEnum, symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> Box<dyn Platform + Send + Sync> {
         match exchange {
         match exchange {
-            ExchangeEnum::BinanceSwap => {
-                Box::new(BinanceSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
             ExchangeEnum::GateSwap => {
             ExchangeEnum::GateSwap => {
                 Box::new(GateSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
                 Box::new(GateSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
             }
             }
-            // ExchangeEnum::GateSpot => {
-            //     Box::new(GateSpot::new(symbol, is_colo, params))
-            // }
-            ExchangeEnum::KucoinSwap => {
-                Box::new(KucoinSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            // ExchangeEnum::KucoinSpot =>{
-            //     Box::new(KucoinSpot::new(symbol, is_colo, params, order_sender, error_sender).await)
-            // }
-            // ExchangeEnum::OkxSwap => {
-            //     Box::new(OkxSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            // }
-            // ExchangeEnum::BitgetSpot => {
-            //     Box::new(BitgetSpot::new(symbol, is_colo, params, order_sender, error_sender).await)
-            // }
-            ExchangeEnum::BitgetSwap => {
-                Box::new(BitgetSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            ExchangeEnum::BybitSwap => {
-                Box::new(BybitSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            ExchangeEnum::CoinexSwap => {
-                Box::new(CoinexSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
-            ExchangeEnum::HtxSwap => {
-                Box::new(HtxSwap::new(symbol, is_colo, params, order_sender, error_sender).await)
-            }
         }
         }
     }
     }
 }
 }

+ 0 - 9
standard/src/gate_swap.rs

@@ -481,33 +481,25 @@ impl Platform for GateSwap {
         let mut params = json!({});
         let mut params = json!({});
         let mut initial = json!({
         let mut initial = json!({
             "contract": "XRP_USDT",
             "contract": "XRP_USDT",
-
             "price": price.to_string(),
             "price": price.to_string(),
-
             "tif": "ioc",
             "tif": "ioc",
-
             // 是否只减仓
             // 是否只减仓
             "reduce_only": true,
             "reduce_only": true,
-
             // [平多:close_long, 平空:close_short]
             // [平多:close_long, 平空:close_short]
             // "auto_size": "close_long"
             // "auto_size": "close_long"
         });
         });
         let mut trigger = json!({
         let mut trigger = json!({
             // [平多:close-long-position, 平空:close-short-position]
             // [平多:close-long-position, 平空:close-short-position]
             // "order_type": "close-long-position",
             // "order_type": "close-long-position",
-
             // 一般都默认用0
             // 一般都默认用0
             "strategy_type": 0,
             "strategy_type": 0,
-
             // [0 - 最新成交价,1 - 标记价格,2 - 指数价格]
             // [0 - 最新成交价,1 - 标记价格,2 - 指数价格]
             "price_type": 0,
             "price_type": 0,
-
             // [1: 引用价格大于等于我们传的价格,2:引用价格小于等于我们传的价格]
             // [1: 引用价格大于等于我们传的价格,2:引用价格小于等于我们传的价格]
             // 在止损的情况下:
             // 在止损的情况下:
             //     1 可以理解为向上突破触发价(一般是给空单用)
             //     1 可以理解为向上突破触发价(一般是给空单用)
             //     2 可以理解为向下突破触发价(一般是给多单用)
             //     2 可以理解为向下突破触发价(一般是给多单用)
             // "rule": 2,
             // "rule": 2,
-
             // 订单触发价格
             // 订单触发价格
             "price": stop_price.to_string(),
             "price": stop_price.to_string(),
         });
         });
@@ -527,7 +519,6 @@ impl Platform for GateSwap {
                 error!("gate swap 止损单side错误: {}", side);
                 error!("gate swap 止损单side错误: {}", side);
             }
             }
         }
         }
-
         params["initial"] = initial;
         params["initial"] = initial;
         params["trigger"] = trigger;
         params["trigger"] = trigger;
 
 

+ 1 - 192
standard/src/handle_info.rs

@@ -3,11 +3,10 @@ use std::str::FromStr;
 use rust_decimal::{Decimal};
 use rust_decimal::{Decimal};
 use rust_decimal::prelude::FromPrimitive;
 use rust_decimal::prelude::FromPrimitive;
 use rust_decimal_macros::dec;
 use rust_decimal_macros::dec;
-use tracing::{error, info};
 use exchanges::response_base::ResponseData;
 use exchanges::response_base::ResponseData;
 use global::public_params;
 use global::public_params;
 use crate::exchange::ExchangeEnum;
 use crate::exchange::ExchangeEnum;
-use crate::{binance_swap_handle, gate_swap_handle, bybit_swap_handle, bitget_swap_handle, kucoin_handle, coinex_swap_handle, htx_swap_handle};
+use crate::gate_swap_handle;
 use crate::{Account, MarketOrder, Position, SpecialDepth, SpecialOrder, SpecialTicker};
 use crate::{Account, MarketOrder, Position, SpecialDepth, SpecialOrder, SpecialTicker};
 
 
 #[allow(dead_code)]
 #[allow(dead_code)]
@@ -26,159 +25,33 @@ impl HandleSwapInfo {
     // 处理账号信息
     // 处理账号信息
     pub fn handle_account_info(exchange: ExchangeEnum, res_data: &ResponseData, symbol: &String) -> Account {
     pub fn handle_account_info(exchange: ExchangeEnum, res_data: &ResponseData, symbol: &String) -> Account {
         match exchange {
         match exchange {
-            // ExchangeEnum::BinanceSwap => {
-            //     error!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
-            //     panic!("暂未提供此交易所方法!handle_account_info:{:?}", exchange);
-            // }
             ExchangeEnum::GateSwap => {
             ExchangeEnum::GateSwap => {
                 gate_swap_handle::handle_account_info(res_data, symbol)
                 gate_swap_handle::handle_account_info(res_data, symbol)
             }
             }
-            // ExchangeEnum::KucoinSwap => {
-            //     kucoin_handle::handle_account_info(res_data, symbol)
-            // }
-            // ExchangeEnum::KucoinSpot => {
-            //     kucoin_spot_handle::handle_account_info(res_data, symbol)
-            // }
-            // ExchangeEnum::OkxSwap => {
-            //     okx_handle::handle_account_info(res_data, symbol)
-            // }
-            // ExchangeEnum::BitgetSpot => {
-            //     bitget_spot_handle::handle_account_info(res_data, symbol)
-            // },
-            ExchangeEnum::BitgetSwap => {
-                bitget_swap_handle::handle_account_info(res_data, symbol)
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_account_info(res_data, symbol)
-            }
-            ExchangeEnum::CoinexSwap => {
-                coinex_swap_handle::handle_account_info(res_data, symbol)
-            }
-            ExchangeEnum::HtxSwap => {
-                htx_swap_handle::handle_account_info(res_data, symbol)
-            }
-            _ => {
-                error!("未找到该交易所!handle_account_info: {:?}",exchange);
-                panic!("未找到该交易所!handle_account_info: {:?}", exchange);
-            }
         }
         }
     }
     }
     // 处理特殊Ticket信息
     // 处理特殊Ticket信息
     pub async fn handle_book_ticker(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
     pub async fn handle_book_ticker(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
         match exchange {
         match exchange {
-            // ExchangeEnum::BinanceSpot => {
-            //     binance_spot_handle::handle_special_ticker(res_data)
-            // }
-            ExchangeEnum::BinanceSwap => {
-                binance_swap_handle::handle_book_ticker(res_data)
-            }
             ExchangeEnum::GateSwap => {
             ExchangeEnum::GateSwap => {
                 gate_swap_handle::handle_book_ticker(res_data)
                 gate_swap_handle::handle_book_ticker(res_data)
             }
             }
-            ExchangeEnum::KucoinSwap => {
-                kucoin_handle::handle_book_ticker(res_data)
-            }
-            // ExchangeEnum::KucoinSpot => {
-            //     kucoin_spot_handle::handle_special_ticker(res_data)
-            // }
-            // ExchangeEnum::KucoinSpot => {
-            //     kucoin_spot_handle::handle_special_ticker(res_data)
-            // }
-            // ExchangeEnum::OkxSwap => {
-            //     okx_handle::handle_special_ticker(res_data)
-            // }
-            // ExchangeEnum::BitgetSpot => {
-            //     bitget_spot_handle::handle_special_ticker(res_data)
-            // },
-            ExchangeEnum::BitgetSwap => {
-                info!(?res_data);
-                panic!("BitgetSwap 85 未实现格式化");
-                // bitget_swap_handle::handle_special_ticker(res_data)
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_ticker(res_data).await
-            }
-            ExchangeEnum::CoinexSwap => {
-                coinex_swap_handle::handle_ticker(res_data)
-            }
-            ExchangeEnum::HtxSwap => {
-                SpecialDepth::new()
-                // htx_swap_handle::handle_ticker(res_data)
-            }
         }
         }
     }
     }
     // 处理position信息
     // 处理position信息
     pub fn handle_position(exchange: ExchangeEnum, res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
     pub fn handle_position(exchange: ExchangeEnum, res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
         match exchange {
         match exchange {
-            ExchangeEnum::BinanceSwap => {
-                error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-                panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-            }
             ExchangeEnum::GateSwap => {
             ExchangeEnum::GateSwap => {
                 gate_swap_handle::handle_position(res_data, ct_val)
                 gate_swap_handle::handle_position(res_data, ct_val)
             }
             }
-            ExchangeEnum::KucoinSwap => {
-                kucoin_handle::handle_position(res_data, ct_val)
-            }
-            // ExchangeEnum::KucoinSpot => {
-            //     error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-            //     panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-            // }
-            // ExchangeEnum::OkxSwap => {
-            //     okx_handle::handle_position(res_data, ct_val)
-            // }
-            // ExchangeEnum::BitgetSpot => {
-            //     error!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-            //     panic!("暂未提供此交易所方法!handle_position:{:?}", exchange);
-            // },
-            ExchangeEnum::BitgetSwap => {
-                bitget_swap_handle::handle_position(res_data, ct_val)
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_position(res_data, ct_val)
-            }
-            ExchangeEnum::CoinexSwap => {
-                coinex_swap_handle::handle_position(res_data, ct_val)
-            }
-            ExchangeEnum::HtxSwap => {
-                htx_swap_handle::handle_position(res_data, ct_val)
-            }
         }
         }
     }
     }
     // 处理订单信息
     // 处理订单信息
     pub fn handle_order(exchange: ExchangeEnum, res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
     pub fn handle_order(exchange: ExchangeEnum, res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
         match exchange {
         match exchange {
-            ExchangeEnum::BinanceSwap => {
-                error!("暂未提供此交易所方法!handle_order:{:?}", exchange);
-                panic!("暂未提供此交易所方法!handle_order:{:?}", exchange);
-            }
             ExchangeEnum::GateSwap => {
             ExchangeEnum::GateSwap => {
                 gate_swap_handle::handle_order(res_data, ct_val)
                 gate_swap_handle::handle_order(res_data, ct_val)
             }
             }
-            ExchangeEnum::KucoinSwap => {
-                kucoin_handle::handle_order(res_data, ct_val)
-            }
-            // ExchangeEnum::KucoinSpot => {
-            //     kucoin_spot_handle::handle_order(res_data, ct_val)
-            // }
-            // ExchangeEnum::OkxSwap => {
-            //     okx_handle::handle_order(res_data, ct_val)
-            // }
-            // ExchangeEnum::BitgetSpot => {
-            //     bitget_spot_handle::handle_order(res_data, ct_val)
-            // },
-            ExchangeEnum::BitgetSwap => {
-                bitget_swap_handle::handle_order(res_data, ct_val)
-            },
-            ExchangeEnum::BybitSwap => {
-                bybit_swap_handle::handle_order(res_data, ct_val)
-            }
-            ExchangeEnum::CoinexSwap => {
-                coinex_swap_handle::handle_order(res_data, ct_val)
-            }
-            ExchangeEnum::HtxSwap => {
-                htx_swap_handle::handle_order(res_data, ct_val)
-            }
         }
         }
     }
     }
 
 
@@ -264,18 +137,6 @@ pub fn format_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> DepthPar
     let t: Decimal;
     let t: Decimal;
     let create_at: i64;
     let create_at: i64;
     match exchange {
     match exchange {
-        // ExchangeEnum::BinanceSpot => {
-        //     depth_asks = binance_swap_handle::format_depth_items(res_data_json["asks"].clone());
-        //     depth_bids = binance_swap_handle::format_depth_items(res_data_json["bids"].clone());
-        //     t = Decimal::from_str(&res_data_json["lastUpdateId"].to_string()).unwrap();
-        //     create_at = 0;
-        // }
-        ExchangeEnum::BinanceSwap => {
-            depth_asks = binance_swap_handle::format_depth_items(res_data.data["a"].clone());
-            depth_bids = binance_swap_handle::format_depth_items(res_data.data["b"].clone());
-            t = Decimal::from_str(&res_data.data["u"].to_string()).unwrap();
-            create_at = res_data.data["E"].as_i64().unwrap() * 1000;
-        }
         ExchangeEnum::GateSwap => {
         ExchangeEnum::GateSwap => {
             depth_asks = gate_swap_handle::format_depth_items(&res_data.data["asks"]);
             depth_asks = gate_swap_handle::format_depth_items(&res_data.data["asks"]);
             depth_bids = gate_swap_handle::format_depth_items(&res_data.data["bids"]);
             depth_bids = gate_swap_handle::format_depth_items(&res_data.data["bids"]);
@@ -283,58 +144,6 @@ pub fn format_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> DepthPar
             t = Decimal::from_str(&res_data.data["t"].to_string()).unwrap();
             t = Decimal::from_str(&res_data.data["t"].to_string()).unwrap();
             create_at = res_data.data["t"].as_i64().unwrap() * 1000;
             create_at = res_data.data["t"].as_i64().unwrap() * 1000;
         }
         }
-        ExchangeEnum::KucoinSwap => {
-            depth_asks = kucoin_handle::format_depth_items(res_data.data["asks"].clone());
-            depth_bids = kucoin_handle::format_depth_items(res_data.data["bids"].clone());
-            t = Decimal::from_str(&res_data.data["sequence"].to_string()).unwrap();
-            create_at = res_data.data["ts"].as_i64().unwrap() * 1000;
-        }
-        // ExchangeEnum::KucoinSpot => {
-        //     depth_asks = kucoin_spot_handle::format_depth_items(res_data_json["asks"].clone());
-        //     depth_bids = kucoin_spot_handle::format_depth_items(res_data_json["bids"].clone());
-        //     t = Decimal::from_str(&res_data_json["timestamp"].to_string()).unwrap();
-        //     create_at = res_data_json["timestamp"].as_i64().unwrap() * 1000;
-        // }
-        // ExchangeEnum::OkxSwap => {
-        //     depth_asks = okx_handle::format_depth_items(res_data_json[0]["asks"].clone());
-        //     depth_bids = okx_handle::format_depth_items(res_data_json[0]["bids"].clone());
-        //     t = Decimal::from_str(&res_data_json[0]["seqId"].to_string()).unwrap();
-        //     create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-        // }
-        // ExchangeEnum::BitgetSpot => {
-        //     depth_asks = bitget_spot_handle::format_depth_items(res_data_json[0]["asks"].clone());
-        //     depth_bids = bitget_spot_handle::format_depth_items(res_data_json[0]["bids"].clone());
-        //     t = Decimal::from_str(res_data_json[0]["ts"].as_str().unwrap()).unwrap();
-        //     create_at = res_data_json[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-        // }
-        ExchangeEnum::BitgetSwap => {
-            depth_asks = bitget_swap_handle::format_depth_items(res_data.data[0]["asks"].clone());
-            depth_bids = bitget_swap_handle::format_depth_items(res_data.data[0]["bids"].clone());
-            t = Decimal::from_str(res_data.data[0]["ts"].as_str().unwrap()).unwrap();
-            create_at = res_data.data[0]["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-        }
-        ExchangeEnum::BybitSwap => {
-            depth_asks = bybit_swap_handle::format_depth_items(res_data.data["a"].clone());
-            depth_bids = bybit_swap_handle::format_depth_items(res_data.data["b"].clone());
-            t = Decimal::from_i64(res_data.reach_time).unwrap();
-            create_at = res_data.reach_time * 1000;
-        },
-        ExchangeEnum::CoinexSwap => {
-            let depth = &res_data.data["depth"];
-            depth_asks = coinex_swap_handle::format_depth_items(&depth["asks"].clone());
-            depth_bids = coinex_swap_handle::format_depth_items(&depth["bids"].clone());
-            let time = depth.get("updated_at").unwrap().as_i64().unwrap_or(0i64);
-            t = Decimal::from_i64(time).unwrap();
-            create_at = time * 1000;
-        }
-        ExchangeEnum::HtxSwap => {
-            let depth = &res_data.data;
-            depth_asks = htx_swap_handle::format_depth_items(depth["asks"].clone());
-            depth_bids = htx_swap_handle::format_depth_items(depth["bids"].clone());
-            let time = depth["ts"].to_string().parse::<i64>().unwrap();
-            t = Decimal::from_i64(time).unwrap();
-            create_at = time * 1000;
-        }
     }
     }
 
 
     DepthParam {
     DepthParam {

+ 0 - 643
standard/src/htx_swap.rs

@@ -1,643 +0,0 @@
-use std::collections::{BTreeMap};
-use exchanges::htx_swap_rest::HtxSwapRest;
-use std::io::{Error, ErrorKind};
-use tokio::sync::mpsc::Sender;
-use std::str::FromStr;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::{FromPrimitive};
-use serde_json::json;
-use serde_json::Value::Null;
-use tokio::spawn;
-use tokio::time::Instant;
-use tracing::{error, info};
-use global::trace_stack::TraceStack;
-use crate::exchange::ExchangeEnum;
-use crate::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, Ticker, utils};
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct HtxSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: HtxSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl HtxSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> HtxSwap {
-        let market = Market::new();
-        let mut htx_swap = HtxSwap {
-            exchange: ExchangeEnum::HtxSwap,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: HtxSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        htx_swap.market = HtxSwap::get_market(&mut htx_swap).await.unwrap();
-        // 修改持仓模式
-        let mode_result = htx_swap.set_dual_mode("", true).await;
-        match mode_result {
-            Ok(ok) => {
-                info!("HtxSwap:设置持仓模式成功!{:?}", ok);
-            }
-            Err(error) => {
-                error!("HtxSwap:设置持仓模式失败!{:?}", error)
-            }
-        }
-        // 设置持仓杠杆
-        let lever_rate_result = htx_swap.set_dual_leverage("10").await;
-        match lever_rate_result {
-            Ok(ok) => {
-                info!("HtxSwap:设置持仓杠杆成功!{:?}", ok);
-            }
-            Err(error) => {
-                error!("HtxSwap:设置持仓杠杆失败!{:?}", error)
-            }
-        }
-
-        return htx_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for HtxSwap {
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-
-    fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::HtxSwap }
-
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-
-    fn get_self_is_colo(&self) -> bool { self.is_colo }
-
-    fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
-
-    fn get_self_market(&self) -> Market { self.market.clone() }
-
-    fn get_request_delays(&self) -> Vec<i64> {
-        // self.request.get_delays()
-        vec![]
-    }
-
-    fn get_request_avg_delay(&self) -> Decimal {
-        // self.request.get_avg_delay()
-        Decimal::ZERO
-    }
-
-    fn get_request_max_delay(&self) -> i64 { 0 }
-
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let response = self.request.get_server_time().await;
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取服务器时间异常{:?}", response).to_string()));
-        }
-
-        let res_data_json = response.data;
-        let result = res_data_json["ts"].to_string();
-        Ok(result)
-    }
-
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let params = json!({
-            "margin_account": "USDT"
-        });
-        let response = self.request.get_account(params).await;
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取账户信息异常{:?}", response).to_string()));
-        }
-
-        let res_data_json = response.data;
-        let mut account = Account::new();
-        for data in res_data_json.as_array().unwrap() {
-            let margin_position = Decimal::from_f64(data["margin_position"].as_f64().unwrap()).unwrap();
-
-            let balance = Decimal::from_f64(data["margin_static"].as_f64().unwrap()).unwrap();
-            let frozen_balance = Decimal::from_f64(data["margin_frozen"].as_f64().unwrap()).unwrap();
-            let available_balance = balance - margin_position - frozen_balance;
-            // 格式化account信息
-            account = Account {
-                coin: data["margin_asset"].as_str().unwrap().to_string(),
-                balance,
-                available_balance,
-                frozen_balance,
-                stocks: Default::default(),
-                available_stocks: Default::default(),
-                frozen_stocks: Default::default(),
-            };
-        }
-        return Ok(account);
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "htx_swap get_spot_account:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let ct_val = self.market.ct_val;
-        let params = json!({
-            "contract_type": "swap",
-            "contract_code": symbol_format
-        });
-        let response = self.request.get_user_position(params).await;
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取仓位异常{:?}", response).to_string()));
-        }
-
-        let res_data_json = response.data;
-        let positions_info = res_data_json.as_array().unwrap();
-        let result = positions_info.iter().map(|item| { format_position_item(item, &ct_val) }).collect();
-        Ok(result)
-    }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let params = json!({
-            "contract_type": "swap"
-        });
-        let response = self.request.get_user_position(params).await;
-
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取仓位异常{:?}", response).to_string()));
-        }
-
-        let res_data_json = response.data;
-        let positions_info = res_data_json.as_array().unwrap();
-        let result = positions_info.iter().map(|item| { format_position_item(item, &Decimal::ONE) }).collect();
-        Ok(result)
-    }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        return self.get_ticker_symbol(self.symbol.clone()).await;
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "-");
-        let params = json!({
-            "contract_code": symbol_format,
-        });
-        let response = self.request.get_ticker(params).await;
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取行情信息异常{:?}", response).to_string()));
-        }
-
-        let res_data_json = response.data;
-        let ticker_info = res_data_json["tick"].clone();
-        let time = ticker_info["ts"].as_i64().unwrap();
-        let result = Ticker {
-            time,
-            high: Decimal::from_str(ticker_info["high"].as_str().unwrap()).unwrap(),
-            low: Decimal::from_str(ticker_info["low"].as_str().unwrap()).unwrap(),
-            sell: Decimal::from_f64(ticker_info["bid"][0].as_f64().unwrap()).unwrap(),
-            sell_volume: Default::default(),
-            buy: Decimal::from_f64(ticker_info["ask"][0].as_f64().unwrap()).unwrap(),
-            buy_volume: Default::default(),
-            last: Decimal::from_str(ticker_info["close"].as_str().unwrap()).unwrap(),
-            volume: Decimal::from_str(ticker_info["amount"].as_str().unwrap()).unwrap(),
-        };
-        Ok(result)
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        self.get_market_symbol(self.symbol.clone()).await
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        let symbol_format = utils::format_symbol(symbol.clone(), "-");
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-
-        let params = json!({
-            "pair": symbol_format,
-            "contract_type":"swap"
-        });
-        let response = self.request.get_market(params).await;
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取市场信息异常{:?}", response).to_string()));
-        }
-        let res_data_json = response.data.as_array().unwrap();
-        let market_info = res_data_json[0].clone();
-
-        if !market_info["pair"].as_str().unwrap().to_string().eq(&symbol_format) {
-            return Err(Error::new(ErrorKind::NotFound, format!("符号未找到:symbol={}, response={:?}", symbol_format, response))).unwrap();
-        }
-
-        let base_asset = market_info["symbol"].as_str().unwrap().to_string();
-        let quote_asset = symbol_array[1].to_string();
-
-        let tick_size = Decimal::from_f64(market_info["price_tick"].as_f64().unwrap()).unwrap();
-        let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-        let amount_size = Decimal::from_f64(market_info["contract_size"].as_f64().unwrap()).unwrap();
-        let amount_precision = Decimal::ZERO;
-        let min_qty = Decimal::NEGATIVE_ONE;
-        let max_qty = Decimal::NEGATIVE_ONE;
-        let ct_val = Decimal::from_f64(market_info["contract_size"].as_f64().unwrap()).unwrap();
-
-        let result = Market {
-            symbol: format!("{}_{}", base_asset, quote_asset),
-            base_asset,
-            quote_asset,
-            tick_size,
-            amount_size,
-            price_precision,
-            amount_precision,
-            min_qty,
-            max_qty,
-            min_notional: min_qty,
-            max_notional: max_qty,
-            ct_val,
-        };
-        Ok(result)
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let ct_val = self.market.ct_val;
-
-        let mut params = json!({
-            "pair": symbol_format
-        });
-        if order_id.eq("") { params["client_order_id"] = json!(custom_id) } else { params["order_id"] = json!(order_id) };
-        let response = self.request.get_order_details(params).await;
-        if response.code != 200 || response.data == Null {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 获取订单详情异常{:?}", response).to_string()));
-        }
-
-        let res_data_json = response.data;
-        let orders = res_data_json.as_array().unwrap();
-        let result = format_order_item(orders[0].clone(), ct_val);
-        Ok(result)
-    }
-
-    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "htx_swap get_orders_list:该交易所方法未实现".to_string()))
-    }
-
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let ct_val = self.market.ct_val;
-
-        return self.take_order_symbol(self.symbol.clone(), ct_val, custom_id, origin_side, price, amount).await;
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(symbol, "-");
-        let final_size = (amount / ct_val).floor();
-        let mut params = json!({
-            "pair": symbol_format,
-            "client_order_id": custom_id,
-            "contract_type": "swap",
-            "volume": final_size.to_string(),
-            "lever_rate": 10
-        });
-        if price.eq(&Decimal::ZERO) {
-            params["order_price_type"] = json!("market");
-        } else {
-            params["price"] = json!(price.to_string());
-            params["order_price_type"] = json!("limit");
-        };
-        match origin_side {
-            "kd" => {
-                params["direction"] = json!("buy");
-                params["offset"] = json!("open");
-            }
-            "pd" => {
-                params["direction"] = json!("sell");
-                params["offset"] = json!("close");
-            }
-            "kk" => {
-                params["direction"] = json!("sell");
-                params["offset"] = json!("open");
-            }
-            "pk" => {
-                params["direction"] = json!("buy");
-                params["offset"] = json!("close");
-            }
-            _ => { panic!("htx_usdt_swap 下单参数错误"); }
-        };
-        let response = self.request.swap_order(params).await;
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 下单异常{:?}", response).to_string()));
-        }
-
-        let res_data_json = response.data;
-        let result = Order {
-            id: res_data_json["order_id"].to_string(),
-            custom_id: res_data_json["client_order_id"].to_string(),
-            price: Decimal::ZERO,
-            amount: Decimal::ZERO,
-            deal_amount: Decimal::ZERO,
-            avg_price: Decimal::ZERO,
-            status: "NEW".to_string(),
-            order_type: "".to_string(),
-            trace_stack: TraceStack::new(0, Instant::now()).on_special("339 htx_swap".to_string()),
-        };
-        return Ok(result);
-    }
-
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let mut params = json!({
-            "pair": symbol_format,
-            "contract_type": "swap"
-        });
-        if order_id.eq("") { params["client_order_id"] = json!(custom_id) } else { params["order_id"] = json!(order_id) };
-        let response = self.request.cancel_order(params).await;
-
-        // 取消失败,进行报错
-        if response.code != 200 || response.data["errors"].as_array().unwrap_or(&vec![]).len() > 0 {
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 取消订单异常{:?}", response).to_string()));
-        }
-        let res_data_json = response.data;
-        let mut id = order_id.to_string();
-        let mut custom_id = custom_id.to_string();
-        if order_id.eq("") {
-            custom_id = res_data_json["successes"].as_str().unwrap().to_string()
-        } else {
-            id = res_data_json["successes"].as_str().unwrap().to_string()
-        };
-        let result = Order {
-            id,
-            custom_id,
-            price: Decimal::ZERO,
-            amount: Decimal::ZERO,
-            deal_amount: Decimal::ZERO,
-            avg_price: Decimal::ZERO,
-            status: "REMOVE".to_string(),
-            order_type: "".to_string(),
-            trace_stack: TraceStack::new(0, Instant::now()).on_special("374 htx_swap".to_string()),
-        };
-        Ok(result)
-    }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "htx_swap cancel_orders:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let params = json!({
-            "pair": symbol_format,
-            "contract_type": "swap"
-        });
-        let response = self.request.cancel_price_order(params).await;
-        if response.code != 200 {
-            if response.data.to_string().contains("No cancellable orders") { return Ok(vec![]); }
-            return Err(Error::new(ErrorKind::NotFound, format!("htx_swap 撤销所有订单异常{:?}", response).to_string()));
-        }
-
-        Ok(vec![])
-    }
-
-    async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<serde_json::Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "htx_swap take_stop_loss_order:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<serde_json::Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "htx_swap cancel_stop_loss_order:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, is_dual_mode: bool) -> Result<String, Error> {
-        let pos_mode = if is_dual_mode { "dual_side" } else { "single_side" };
-        let params = json!({
-            "margin_account": "USDT",
-            "position_mode": pos_mode,
-        });
-        let response = self.request.setting_dual_mode(params).await;
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::Other, format!("设置持仓模式失败:{:?}", response).to_string()));
-        }
-
-        return Ok(response.data.to_string());
-    }
-
-    async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-        let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-        let params = json!({
-            "pair": symbol_format,
-            "contract_type": "swap",
-            "lever_rate": leverage
-        });
-        let response = self.request.setting_dual_leverage(params).await;
-
-        if response.code != 200 {
-            return Err(Error::new(ErrorKind::Other, format!("设置杠杆失败:{:?}", response).to_string()));
-        }
-
-        return Ok(response.data.to_string());
-    }
-
-    async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "htx_swap set_auto_deposit_status:该交易所方法未实现".to_string()))
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "htx_swap wallet_transfers:该交易所方法未实现".to_string()))
-    }
-
-    async fn command_order(&mut self, order_command: &mut OrderCommand, trace_stack: &TraceStack) {
-        let mut handles = vec![];
-
-        // 下单指令
-        for item in order_command.limits_open.keys() {
-            let mut ts = trace_stack.clone();
-
-            let amount = Decimal::from_str(&*order_command.limits_open[item].get(0).unwrap().clone()).unwrap();
-            let side = order_command.limits_open[item].get(1).unwrap().clone();
-            let price = Decimal::from_str(&*order_command.limits_open[item].get(2).unwrap().clone()).unwrap();
-            let cid = order_command.limits_open[item].get(3).unwrap().clone();
-
-            //  order_name: [数量,方向,价格,c_id]
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                // TraceStack::show_delay(&ts.ins);
-                ts.on_before_send();
-                let result = self_clone.take_order(cid.as_str(), side.as_str(), price, amount).await;
-                ts.on_after_send();
-                // info!("下单 custom_id {}", cid);
-                match result {
-                    Ok(mut result) => {
-                        result.trace_stack = ts;
-                        // info!("下单完成 order_id {}", result.id);
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        info!(?error);
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-                        ts.source = "htx_swap 474".to_string();
-                        err_order.trace_stack = ts;
-
-                        self_clone.order_sender.send(err_order).await.unwrap();
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(handles);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 撤销订单
-        let mut cancel_handlers = vec![];
-        for item in order_command.cancel.keys() {
-            let order_id = order_command.cancel[item].get(1).unwrap().clone();
-            let custom_id = order_command.cancel[item].get(0).unwrap().clone();
-            // info!("取消订单 order_id {}, custom_id {}", order_id, custom_id);
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                match result {
-                    Ok(_) => {
-                        // result_sd.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        // 已经取消的订单不去撤单了
-                        if !error.to_string().contains("Your order has been canceled") {
-                            // 取消失败去查订单。
-                            let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                            match query_rst {
-                                Ok(order) => {
-                                    self_clone.order_sender.send(order).await.unwrap();
-                                }
-                                Err(err) => {
-                                    error!("撤单失败,而且查单也失败了,htx_swap,oid={}, cid={}, err={:?}。", order_id.clone(), custom_id.clone(), err);
-                                }
-                            }
-                            error!("撤单失败,异常:{}", error);
-                            self_clone.error_sender.send(error).await.unwrap();
-                        }
-                    }
-                }
-            });
-            cancel_handlers.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(cancel_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 检查订单指令
-        let mut check_handlers = vec![];
-        for item in order_command.check.keys() {
-            let order_id = order_command.check[item].get(1).unwrap().clone();
-            let custom_id = order_command.check[item].get(0).unwrap().clone();
-
-            let mut self_clone = self.clone();
-            let handle = spawn(async move {
-                let result = self_clone.get_order_detail(order_id.as_str(), custom_id.as_str()).await;
-                match result {
-                    Ok(result) => {
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            check_handlers.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(check_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-// pub fn format_account_info(balance_data: Value) -> Account {
-//     let balance_coin = balance_data["coin"].as_str().unwrap().to_string().to_uppercase();
-//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-//     let frozen_balance = Decimal::from_str(balance_data["frozen"].as_str().unwrap()).unwrap();
-//     let balance = available_balance + frozen_balance;
-//
-//     Account {
-//         coin: balance_coin,
-//         balance,
-//         available_balance,
-//         frozen_balance,
-//         stocks: Decimal::ZERO,
-//         available_stocks: Decimal::ZERO,
-//         frozen_stocks: Decimal::ZERO,
-//     }
-// }
-
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    let id = order["order_id"].to_string();
-    let custom_id = order["client_order_id"].to_string();
-    let price = Decimal::from_f64(order["price"].as_f64().unwrap()).unwrap();
-    let amount = Decimal::from_f64(order["volume"].as_f64().unwrap()).unwrap() * ct_val;
-    let deal_amount = Decimal::from_f64(order["trade_volume"].as_f64().unwrap()).unwrap() * ct_val;
-    let avg_price = Decimal::from_f64(order["trade_avg_price"].as_f64().unwrap_or(0.0)).unwrap();
-
-    let status = order["status"].to_string();
-
-    let custom_status = if ["5", "6", "7"].contains(&&**&status) {
-        "REMOVE".to_string()
-    } else if ["1", "2", "3", "4"].contains(&&**&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id,
-        custom_id,
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["order_price_type"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("630 htx_swap".to_string()),
-    }
-}
-
-pub fn format_position_item(position: &serde_json::Value, ct_val: &Decimal) -> Position {
-    let symbol = position["pair"].as_str().unwrap().to_string();
-    let margin_level = Decimal::from_str(&position["lever_rate"].to_string()).unwrap();
-    let amount = Decimal::from_f64(position["volume"].as_f64().unwrap()).unwrap() * ct_val;
-
-    let frozen_amount = Decimal::from_f64(position["frozen"].as_f64().unwrap()).unwrap();
-    let price = Decimal::from_f64(position["cost_hold"].as_f64().unwrap()).unwrap();
-    let profit = Decimal::from_f64(position["profit_unreal"].as_f64().unwrap()).unwrap();
-    let position_mode = match position["position_mode"].as_str().unwrap() {
-        "dual_side" => {
-            match position["direction"].as_str().unwrap() {
-                "sell" => {
-                    PositionModeEnum::Short
-                }
-                "buy" => {
-                    PositionModeEnum::Long
-                }
-                _ => {
-                    panic!("htx_usdt_swap: 未知的持仓模式与持仓方向: {}, {}",
-                           position["direction"].as_str().unwrap(), position["direction"].as_str().unwrap())
-                }
-            }
-        }
-        "single_side" => {
-            PositionModeEnum::Both
-        }
-        _ => {
-            panic!("htx_usdt_swap: 未知的持仓模式: {}", position["position_mode"].as_str().unwrap())
-        }
-    };
-    let margin = Decimal::from_f64(position["position_margin"].as_f64().unwrap()).unwrap();
-
-    Position {
-        symbol,
-        margin_level,
-        amount,
-        frozen_amount,
-        price,
-        profit,
-        position_mode,
-        margin,
-    }
-}

+ 0 - 135
standard/src/htx_swap_handle.rs

@@ -1,135 +0,0 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use tokio::time::Instant;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialOrder};
-
-// 处理账号信息
-pub fn handle_account_info(response: &ResponseData, _symbol: &String) -> Account {
-    let mut result = Account::new();
-    let account_infos = response.data.as_array().unwrap();
-    for data in account_infos {
-        if data["margin_asset"].as_str().unwrap() != "USDT" { continue; }
-        let margin_position = Decimal::from_f64(data["margin_position"].as_f64().unwrap()).unwrap();
-        let balance = Decimal::from_f64(data["margin_static"].as_f64().unwrap()).unwrap();
-        let frozen_balance = Decimal::from_f64(data["margin_frozen"].as_f64().unwrap()).unwrap();
-        let available_balance = balance - margin_position - frozen_balance;
-        // 格式化account信息
-        let account = Account {
-            coin: data["margin_asset"].as_str().unwrap().to_string(),
-            balance,
-            available_balance,
-            frozen_balance,
-            stocks: Default::default(),
-            available_stocks: Default::default(),
-            frozen_stocks: Default::default(),
-        };
-        result = account
-    }
-    return result;
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_json = res_data.data;
-    let order_info = vec![format_order_item(res_data_json.clone(), ct_val)];
-    SpecialOrder {
-        name: res_data.label,
-        order: order_info,
-    }
-}
-
-// 处理订单信息
-pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-    let id = order["order_id"].to_string();
-    let custom_id = order["client_order_id"].to_string();
-    let price = Decimal::from_f64(order["price"].as_f64().unwrap()).unwrap();
-    let amount = Decimal::from_f64(order["volume"].as_f64().unwrap()).unwrap() * ct_val;
-    let deal_amount = Decimal::from_f64(order["trade_volume"].as_f64().unwrap()).unwrap() * ct_val;
-    let avg_price = Decimal::from_f64(order["trade_avg_price"].as_f64().unwrap_or(0.0)).unwrap();
-
-    let status = order["status"].to_string();
-
-    let custom_status = if ["5", "6", "7"].contains(&&**&status) {
-        "REMOVE".to_string()
-    } else if ["1", "2", "3", "4"].contains(&&**&status) {
-        "NEW".to_string()
-    } else {
-        "NULL".to_string()
-    };
-    Order {
-        id,
-        custom_id,
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["order_price_type"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("73 htx_swap_handle".to_string()),
-    }
-}
-
-// 格式化深度信息
-pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-    let mut depth_items: Vec<MarketOrder> = vec![];
-    for value in value.as_array().unwrap() {
-        depth_items.push(MarketOrder {
-            price: Decimal::from_f64(value[0].as_f64().unwrap()).unwrap(),
-            amount: Decimal::from_f64(value[1].as_f64().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}
-
-// 处理position信息
-pub fn handle_position(res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
-    let res_data_json = res_data.data.as_array().unwrap();
-    res_data_json.iter().map(|item| { format_position_item(item, ct_val) }).collect()
-}
-
-pub fn format_position_item(position: &serde_json::Value, ct_val: &Decimal) -> Position {
-    let symbol = position["pair"].as_str().unwrap().to_string();
-    let margin_level = Decimal::from_str(&position["lever_rate"].to_string()).unwrap();
-    let amount = Decimal::from_f64(position["volume"].as_f64().unwrap()).unwrap() * ct_val;
-
-    let frozen_amount = Decimal::from_f64(position["frozen"].as_f64().unwrap()).unwrap();
-    let price = Decimal::from_f64(position["cost_hold"].as_f64().unwrap()).unwrap();
-    let profit = Decimal::from_f64(position["profit_unreal"].as_f64().unwrap()).unwrap();
-    let position_mode = match position["position_mode"].as_str().unwrap() {
-        "dual_side" => {
-            match position["direction"].as_str().unwrap() {
-                "sell" => {
-                    PositionModeEnum::Short
-                }
-                "buy" => {
-                    PositionModeEnum::Long
-                }
-                _ => {
-                    panic!("htx_usdt_swap: 未知的持仓模式与持仓方向: {}, {}",
-                           position["direction"].as_str().unwrap(), position["direction"].as_str().unwrap())
-                }
-            }
-        }
-        "single_side" => {
-            PositionModeEnum::Both
-        }
-        _ => {
-            panic!("htx_usdt_swap: 未知的持仓模式: {}", position["position_mode"].as_str().unwrap())
-        }
-    };
-    let margin = Decimal::from_f64(position["position_margin"].as_f64().unwrap()).unwrap();
-
-    Position {
-        symbol,
-        margin_level,
-        amount,
-        frozen_amount,
-        price,
-        profit,
-        position_mode,
-        margin,
-    }
-}

+ 0 - 155
standard/src/kucoin_handle.rs

@@ -1,155 +0,0 @@
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use serde_json::Value;
-use tokio::time::Instant;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker, utils};
-use crate::exchange::ExchangeEnum;
-use crate::handle_info::HandleSwapInfo;
-
-// 处理账号信息
-pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account {
-    format_account_info(&res_data.data, symbol)
-}
-
-pub fn format_account_info(data: &Value, symbol: &String) -> Account {
-    let symbol_upper = symbol.to_uppercase();
-    let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-    let available_balance = Decimal::from_str(data["availableBalance"].as_str().unwrap()).unwrap();
-    let frozen_balance = Decimal::from_str(data["holdBalance"].as_str().unwrap()).unwrap();
-    let balance = available_balance + frozen_balance;
-    Account {
-        coin: symbol_array[1].to_string(),
-        balance,
-        available_balance,
-        frozen_balance,
-        stocks: Decimal::ZERO,
-        available_stocks: Decimal::ZERO,
-        frozen_stocks: Decimal::ZERO,
-    }
-}
-
-// 处理特殊Ticket信息
-pub fn handle_book_ticker(res_data: &ResponseData) -> SpecialDepth {
-    format_special_ticker(&res_data.data, &res_data.label)
-}
-
-pub fn format_special_ticker(data: &Value, label: &String) -> SpecialDepth {
-    let bp = Decimal::from_str(&data["bestBidPrice"].as_str().unwrap()).unwrap();
-    let bq = Decimal::from_f64(data["bestBidSize"].as_f64().unwrap()).unwrap();
-    let ap = Decimal::from_str(&data["bestAskPrice"].as_str().unwrap()).unwrap();
-    let aq = Decimal::from_f64(data["bestAskSize"].as_f64().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
-    let t = Decimal::from_str(&data["sequence"].to_string()).unwrap();
-    let create_at = (data["ts"].as_f64().unwrap() / 1000.0).floor() as i64;
-
-    let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-    let depth_info = vec![bp, bq, ap, aq];
-    SpecialDepth {
-        name: label.clone(),
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
-
-pub fn format_position_item(position: &Value, ct_val: &Decimal) -> Position {
-    let symbol = position["symbol"].as_str().unwrap_or("");
-    let symbol_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, symbol);
-    let real_leverage = Decimal::from_f64(position["realLeverage"].as_f64().unwrap()).unwrap();
-    let currency = position["settleCurrency"].as_str().unwrap_or("");
-    let coin = &symbol_mapper[..symbol_mapper.find(currency).unwrap_or(0)];
-    let avg_entry_price = Decimal::from_f64(position["avgEntryPrice"].as_f64().unwrap()).unwrap();
-    let unrealised_pnl = Decimal::from_f64(position["unrealisedPnl"].as_f64().unwrap()).unwrap();
-    let pos_margin = Decimal::from_f64(position["posMargin"].as_f64().unwrap()).unwrap();
-
-    let current_qty = Decimal::from_f64(position["currentQty"].as_f64().unwrap()).unwrap();
-    let amount = current_qty * ct_val;
-    let position_mode = match amount {
-        amount if amount > Decimal::ZERO => PositionModeEnum::Long,
-        amount if amount < Decimal::ZERO => PositionModeEnum::Short,
-        _ => { PositionModeEnum::Both }
-    };
-    Position {
-        symbol: format!("{}_{}", coin, currency),
-        margin_level: real_leverage,
-        amount,
-        frozen_amount: Decimal::ZERO,
-        price: avg_entry_price,
-        profit: unrealised_pnl,
-        position_mode,
-        margin: pos_margin,
-    }
-}
-
-// 处理position信息
-pub fn handle_position(res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
-    let result = format_position_item(&res_data.data, ct_val);
-    return vec![result];
-}
-
-// 处理order信息
-pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-    let res_data_json = vec![res_data.data];
-    let mut order_info = Vec::new();
-    for item in res_data_json.iter() {
-        order_info.push(format_order_item(item, ct_val));
-    }
-    SpecialOrder {
-        name: res_data.label.clone(),
-        order: order_info,
-    }
-}
-
-// ws处理
-pub fn format_order_item(order: &Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
-    let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
-    let status = order["status"].as_str().unwrap_or("");
-    let type_ = order["type"].as_str().unwrap_or("");
-    let filled_size = Decimal::from_str(order["filledSize"].as_str().unwrap()).unwrap();
-
-    let avg_price = price;
-
-    let amount = size * ct_val;
-    let deal_amount = filled_size * ct_val;
-    let custom_status;
-    if ["filled", "canceled"].contains(&type_) {
-        custom_status = "REMOVE".to_string();
-    } else if ["open"].contains(&status) {
-        custom_status = "NEW".to_string();
-    } else {
-        custom_status = "NULL".to_string();
-    }
-    Order {
-        id: order["orderId"].as_str().unwrap().to_string(),
-        custom_id: order["clientOid"].as_str().unwrap_or("").to_string(),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["type"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("136 kucoin_handle".to_string()),
-    }
-}
-
-// 处理特殊深度数据
-pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-    HandleSwapInfo::handle_special_depth(ExchangeEnum::KucoinSwap, &res_data)
-}
-
-pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-    let mut depth_items: Vec<MarketOrder> = vec![];
-    for value in value.as_array().unwrap() {
-        depth_items.push(MarketOrder {
-            price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-            amount: Decimal::from_f64(value[1].as_f64().unwrap()).unwrap(),
-        })
-    }
-    return depth_items;
-}

+ 0 - 738
standard/src/kucoin_spot.rs

@@ -1,738 +0,0 @@
-// use std::collections::{BTreeMap, HashMap};
-// use std::io::{Error, ErrorKind};
-// use std::str::FromStr;
-// use tokio::sync::mpsc::Sender;
-// use async_trait::async_trait;
-// use futures::stream::FuturesUnordered;
-// use futures::TryStreamExt;
-// use rust_decimal::Decimal;
-// use rust_decimal::prelude::FromPrimitive;
-// use serde::{Deserialize, Serialize};
-// use serde_json::json;
-// use tokio::time::Instant;
-// use tracing::error;
-// use exchanges::kucoin_spot_rest::KucoinSpotRest;
-// use global::trace_stack::TraceStack;
-// use crate::exchange::ExchangeEnum;
-// use crate::{Account, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
-//
-// /// Kucoin交易所账户信息请求数据结构
-// /// 接口`"/api/v1/accounts"`;
-// ///
-// /// struct SpotAccount
-// /// - `id`: String, accountId
-// /// - `currency`: String, 币种
-// /// - `account_type`: String, 账户类型,资金(main)账户,现货交易(trade)账户,现货高频交易(trade_hf)账户,杠杆(margin)账户
-// /// - `balance`: Decimal, 资金总额
-// /// - `available`: Decimal, 可用余额
-// /// - `holds`: Decimal, 冻结金额
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SpotAccount {
-//     id: String,
-//     currency: String,
-//     account_type: String,
-//     balance: Decimal,
-//     available: Decimal,
-//     holds: Decimal,
-// }
-//
-// impl SpotAccount {
-//     fn new() -> SpotAccount {
-//         SpotAccount {
-//             id: "".to_string(),
-//             currency: "".to_string(),
-//             account_type: "".to_string(),
-//             balance: Default::default(),
-//             available: Default::default(),
-//             holds: Default::default(),
-//         }
-//     }
-// }
-//
-// /// Kucoin交易所Ticker信息请求数据结构
-// /// 接口`"/api/v1/market/orderbook/level1"`;
-// ///
-// /// struct SpotTicker
-// /// - `sequence`: String, 序列号
-// /// - `price`: Decimal, 最新成交价格
-// /// - `size`: Decimal, 最新成交数量
-// /// - `best_ask`: Decimal, 最佳卖一价
-// /// - `best_ask_size`: Decimal, 最佳卖一数量
-// /// - `best_bid`: Decimal, 最佳买一价
-// /// - `best_bid_size`: Decimal, 最佳买一数量
-// /// - `time`: i64, 时间戳
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SpotTicker {
-//     sequence: String,
-//     price: Decimal,
-//     size: Decimal,
-//     best_ask: Decimal,
-//     best_ask_size: Decimal,
-//     best_bid: Decimal,
-//     best_bid_size: Decimal,
-//     time: i64,
-// }
-//
-// /// Kucoin交易所Market信息请求数据结构
-// /// 接口`"/api/v2/symbols"`;
-// ///
-// /// struct SpotTicker
-// /// - `symbol: String, 交易对唯一标识码
-// /// - `name: String, 交易对名称
-// /// - `base_currency: String, 商品货币
-// /// - `quote_currency: String, 计价币种
-// /// - `fee_currency: String, 交易计算手续费的币种
-// /// - `market: String, 交易市场
-// /// - `base_min_size: Decimal, 下单时size的最小值
-// /// - `quote_min_size: Decimal, 下市价单,funds的最小值
-// /// - `base_max_size: Decimal, 下单,size的最大值
-// /// - `quote_max_size: Decimal, 下市价单,funds的最大值
-// /// - `base_increment: Decimal, 数量增量,下单的size必须为数量增量的正整数倍
-// /// - `quote_increment: Decimal, 市价单:资金增量,下单的funds必须为资金增量的正整数倍
-// /// - `price_increment: Decimal, 限价单:价格增量,下单的price必须为价格增量的正整数倍
-// /// - `price_limit_rate: Decimal, 价格保护阈值
-// /// - `min_funds: Option<Decimal>, 最小交易金额
-// /// - `is_margin_enabled: bool, 是否支持杠杆
-// /// - `enable_trading: bool, 是否可以用于交易
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SpotMarket {
-//     symbol: String,
-//     name: String,
-//     base_currency: String,
-//     quote_currency: String,
-//     fee_currency: String,
-//     market: String,
-//     base_min_size: Decimal,
-//     quote_min_size: Decimal,
-//     base_max_size: Decimal,
-//     quote_max_size: Decimal,
-//     base_increment: Decimal,
-//     quote_increment: Decimal,
-//     price_increment: Decimal,
-//     price_limit_rate: Decimal,
-//     min_funds: Option<Decimal>,
-//     is_margin_enabled: bool,
-//     enable_trading: bool,
-// }
-//
-// /// Kucoin交易所Order信息请求数据结构
-// /// 接口`"/api/v1/orders/{orderId}"`;
-// ///
-// /// struct SpotOrder
-// /// - `id`: String,
-// /// - `symbol`: String,
-// /// - `op_type`: String,
-// /// - `order_type`: String,
-// /// - `side`: String,
-// /// - `price`: Decimal,
-// /// - `size`: Decimal,
-// /// - `funds`: Decimal,
-// /// - `deal_funds`: Decimal,
-// /// - `deal_size`: Decimal,
-// /// - `fee`: Decimal,
-// /// - `fee_currency`: String,
-// /// - `stp`: String,
-// /// - `stop`: String,
-// /// - `stop_triggered`: bool,
-// /// - `stop_price`: Decimal,
-// /// - `time_in_force`: String,
-// /// - `post_only`: bool,
-// /// - `hidden`: bool,
-// /// - `iceberg`: bool,
-// /// - `visible_size`: Decimal,
-// /// - `cancel_after`: i64,
-// /// - `channel`: String,
-// /// - `client_oid`: String,
-// /// - `remark`: String,
-// /// - `tags`: String,
-// /// - `is_active`: bool,
-// /// - `cancel_exist`: bool,
-// /// - `created_at`: i64,
-// /// - `trade_type`: String,
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SpotOrder {
-//     id: String,
-//     symbol: String,
-//     op_type: String,
-//     #[serde(rename = "type")]
-//     order_type: String,
-//     side: String,
-//     price: Decimal,
-//     size: Decimal,
-//     funds: Decimal,
-//     deal_funds: Decimal,
-//     deal_size: Decimal,
-//     fee: Decimal,
-//     fee_currency: String,
-//     stp: String,
-//     stop: String,
-//     stop_triggered: bool,
-//     stop_price: Decimal,
-//     time_in_force: String,
-//     post_only: bool,
-//     hidden: bool,
-//     iceberg: bool,
-//     visible_size: Decimal,
-//     cancel_after: i64,
-//     channel: String,
-//     client_oid: String,
-//     remark: String,
-//     tags: String,
-//     is_active: bool,
-//     cancel_exist: bool,
-//     created_at: i64,
-//     trade_type: String,
-// }
-//
-// #[allow(dead_code)]
-// #[derive(Clone)]
-// pub struct KucoinSpot {
-//     exchange: ExchangeEnum,
-//     symbol: String,
-//     is_colo: bool,
-//     params: BTreeMap<String, String>,
-//     request: KucoinSpotRest,
-//     market: Market,
-//     order_sender: Sender<Order>,
-//     error_sender: Sender<Error>,
-// }
-//
-// impl KucoinSpot {
-//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> KucoinSpot {
-//         let market = Market::new();
-//         let mut kucoin_spot = KucoinSpot {
-//             exchange: ExchangeEnum::KucoinSpot,
-//             symbol: symbol.to_uppercase(),
-//             is_colo,
-//             params: params.clone(),
-//             request: KucoinSpotRest::new(is_colo, params.clone()),
-//             market,
-//             order_sender,
-//             error_sender,
-//         };
-//         kucoin_spot.market = KucoinSpot::get_market(&mut kucoin_spot).await.unwrap_or(kucoin_spot.market);
-//
-//         return kucoin_spot;
-//     }
-// }
-//
-// #[async_trait]
-// impl Platform for KucoinSpot {
-//     // 克隆方法
-//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-//     fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::KucoinSpot }
-//     // 获取交易对
-//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
-//     // 获取是否使用高速通道
-//     fn get_self_is_colo(&self) -> bool {
-//         self.is_colo
-//     }
-//     // 获取params信息
-//     fn get_self_params(&self) -> BTreeMap<String, String> {
-//         self.params.clone()
-//     }
-//     // 获取market信息
-//     fn get_self_market(&self) -> Market { self.market.clone() }
-//     // 获取请求时间
-//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-//     // 获取请求平均时间
-//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-//     // 获取请求最大时间
-//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-//     // 获取服务器时间
-//     async fn get_server_time(&mut self) -> Result<String, Error> {
-//         let res_data = self.request.get_server_time().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let result = res_data_str.clone();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_account(&mut self) -> Result<Account, Error> {
-//         let coin_array: Vec<&str> = self.symbol.split("_").collect();
-//         let res_data = self.request.get_accounts(coin_array[1].to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let balance_info_list: Vec<SpotAccount> = serde_json::from_str(res_data_str).unwrap();
-//             let mut balance_info_default = SpotAccount::new();
-//             balance_info_default.currency = coin_array[1].to_string();
-//             let balance_info = balance_info_list.iter().find(|&item| item.currency == coin_array[1].to_string()).unwrap_or(&balance_info_default);
-//             let mut stocks_info_default = SpotAccount::new();
-//             stocks_info_default.currency = coin_array[0].to_string();
-//             let stocks_info = balance_info_list.iter().find(|&item| item.currency == coin_array[0].to_string()).unwrap_or(&balance_info_default);
-//             let result = Account {
-//                 coin: format!("{}_{}", balance_info.currency, stocks_info.currency),
-//                 balance: balance_info.available + balance_info.holds,
-//                 available_balance: balance_info.available,
-//                 frozen_balance: balance_info.holds,
-//                 stocks: stocks_info.available + stocks_info.holds,
-//                 available_stocks: stocks_info.available,
-//                 frozen_stocks: stocks_info.holds,
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-//         let res_data = self.request.get_accounts("".to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let balance_info_list: Vec<SpotAccount> = serde_json::from_str(res_data_str).unwrap();
-//             let result = balance_info_list.iter().map(|item| {
-//                 Account {
-//                     coin: item.currency.to_string(),
-//                     balance: item.available + item.holds,
-//                     available_balance: item.available,
-//                     frozen_balance: item.holds,
-//                     stocks: Decimal::ZERO,
-//                     available_stocks: Decimal::ZERO,
-//                     frozen_stocks: Decimal::ZERO,
-//                 }
-//             }).collect();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-//         let res_data = self.request.get_level1(symbol_format).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let ticker_info: SpotTicker = serde_json::from_str(res_data_str).unwrap();
-//             let result = Ticker {
-//                 time: ticker_info.time,
-//                 high: ticker_info.best_ask,
-//                 low: ticker_info.best_bid,
-//                 sell: ticker_info.best_ask,
-//                 buy: ticker_info.best_bid,
-//                 last: ticker_info.price,
-//                 volume: ticker_info.size,
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
-//         let res_data = self.request.get_level1(symbol_format).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let ticker_info: SpotTicker = serde_json::from_str(res_data_str).unwrap();
-//             let result = Ticker {
-//                 time: ticker_info.time,
-//                 high: ticker_info.best_ask,
-//                 low: ticker_info.best_bid,
-//                 sell: ticker_info.best_ask,
-//                 buy: ticker_info.best_bid,
-//                 last: ticker_info.price,
-//                 volume: ticker_info.size,
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_market(&mut self) -> Result<Market, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-//         let res_data = self.request.get_symbols().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let market_info_list: Vec<SpotMarket> = serde_json::from_str(res_data_str).unwrap();
-//             let market_info = market_info_list.iter().find(|&item| item.symbol == symbol_format).unwrap();
-//             let result = Market {
-//                 symbol: market_info.symbol.replace("-", "_"),
-//                 base_asset: market_info.base_currency.clone(),
-//                 quote_asset: market_info.quote_currency.clone(),
-//                 tick_size: market_info.price_increment,
-//                 amount_size: market_info.base_increment,
-//                 price_precision: Decimal::from_u32(market_info.price_increment.scale()).unwrap(),
-//                 amount_precision: Decimal::from_u32(market_info.base_increment.scale()).unwrap(),
-//                 min_qty: market_info.base_min_size,
-//                 max_qty: market_info.base_max_size,
-//                 min_notional: market_info.price_increment * market_info.base_min_size,
-//                 max_notional: market_info.price_increment * market_info.base_max_size,
-//                 ct_val: Decimal::ONE,
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
-//         let res_data = self.request.get_symbols().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let market_info_list: Vec<SpotMarket> = serde_json::from_str(res_data_str).unwrap();
-//             let market_info = market_info_list.iter().find(|&item| item.symbol == symbol_format).unwrap();
-//             let result = Market {
-//                 symbol: market_info.symbol.replace("-", "_"),
-//                 base_asset: market_info.base_currency.clone(),
-//                 quote_asset: market_info.quote_currency.clone(),
-//                 tick_size: market_info.price_increment,
-//                 amount_size: market_info.base_increment,
-//                 price_precision: Decimal::from_u32(market_info.price_increment.scale()).unwrap(),
-//                 amount_precision: Decimal::from_u32(market_info.base_increment.scale()).unwrap(),
-//                 min_qty: market_info.base_min_size,
-//                 max_qty: market_info.base_max_size,
-//                 min_notional: market_info.price_increment * market_info.base_min_size,
-//                 max_notional: market_info.price_increment * market_info.base_max_size,
-//                 ct_val: Decimal::ONE,
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-//         let res_data = if order_id != "" { self.request.get_order_by_order_id(order_id.to_string()).await } else { self.request.get_order_by_client_id(custom_id.to_string()).await };
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let result = format_order_item(res_data_str.clone());
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-//         let res_data = self.request.get_order().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let order_info_list: Vec<String> = serde_json::from_str(res_data_str).unwrap();
-//             let result = order_info_list.iter().map(|item| format_order_item(item.clone())).collect();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-//         let mut params = json!({
-//             "symbol": symbol_format.to_string(),
-//             "clientOid": custom_id,
-//             "price": price.to_string(),
-//             "size": amount.to_string()
-//         });
-//         if price.eq(&Decimal::ZERO) {
-//             params["type"] = json!("market");
-//         } else {
-//             params["type"] = json!("limit");
-//         };
-//         match origin_side {
-//             "kd" => {
-//                 params["side"] = json!("buy");
-//             }
-//             "pd" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "kk" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "pk" => {
-//                 params["side"] = json!("buy");
-//             }
-//             _ => { error!("下单参数错误"); }
-//         };
-//         let res_data = self.request.spot_order(params).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let result = Order {
-//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
-//                 custom_id: custom_id.to_string(),
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "NEW".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("550 kucoin_spot".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
-//         let mut params = json!({
-//             "symbol": symbol_format.to_string(),
-//             "clientOid": custom_id,
-//             "price": price.to_string(),
-//             "size": amount * ct_val,
-//         });
-//         if price.eq(&Decimal::ZERO) {
-//             params["type"] = json!("market");
-//         } else {
-//             params["type"] = json!("limit");
-//         };
-//         match origin_side {
-//             "kd" => {
-//                 params["side"] = json!("buy");
-//             }
-//             "pd" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "kk" => {
-//                 params["side"] = json!("sell");
-//             }
-//             "pk" => {
-//                 params["side"] = json!("buy");
-//             }
-//             _ => { error!("下单参数错误"); }
-//         };
-//         let res_data = self.request.spot_order(params).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let result = Order {
-//                 id: res_data_json["orderId"].as_str().unwrap().to_string(),
-//                 custom_id: custom_id.to_string(),
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "NEW".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("599 kucoin_spot".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-//         let res_data = if order_id != "" { self.request.cancel_order_by_order_id(order_id.to_string()).await } else { self.request.cancel_order_by_client_id(custom_id.to_string()).await };
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let id = if order_id != "" { order_info["cancelledOrderIds"][0].as_str().unwrap().to_string() } else { order_info["cancelledOrderId"].as_str().unwrap().to_string() };
-//             let custom_id = if order_id != "" { "".to_string() } else { order_info["clientOid"].as_str().unwrap().to_string() };
-//             let result = Order {
-//                 id,
-//                 custom_id,
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "REMOVE".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("623 kucoin_spot".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-//         let res_data = self.request.cancel_order_all(symbol_format).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let id_list = order_info["cancelledOrderIds"].as_array().unwrap();
-//             let result = id_list.iter().map(|item| Order {
-//                 id: item["id"].as_str().unwrap().to_string(),
-//                 custom_id: "".to_string(),
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "REMOVE".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("647 kucoin_spot".to_string()),
-//             }).collect();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-//         let res_data = self.request.cancel_order_all("".to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let order_info: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let id_list = order_info["cancelledOrderIds"].as_array().unwrap();
-//             let result = id_list.iter().map(|item| Order {
-//                 id: item["id"].as_str().unwrap().to_string(),
-//                 custom_id: "".to_string(),
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "REMOVE".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("670 kucoin_spot".to_string()),
-//             }).collect();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "kucoin_spot:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-//         let mut handles = vec![];
-//         // 撤销订单
-//         let cancel = order_command.cancel;
-//         for item in cancel.keys() {
-//             let mut self_clone = self.clone();
-//             let cancel_clone = cancel.clone();
-//             let item_clone = item.clone();
-//             let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let handle = tokio::spawn(async move {
-//                 let result = self_clone.cancel_order(&order_id, &custom_id).await;
-//                 match result {
-//                     Ok(_) => {
-//                         // result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         // 取消失败去查订单。
-//                         let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-//                         match query_rst {
-//                             Ok(order) => {
-//                                 result_sd.send(order).await.unwrap();
-//                             }
-//                             Err(_query_err) => {
-//                                 // error!(?_query_err);
-//                                 // error!("撤单失败,而且查单也失败了,bitget_spot,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-//                             }
-//                         }
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//         // 下单指令
-//         let mut limits = HashMap::new();
-//         limits.extend(order_command.limits_open);
-//         limits.extend(order_command.limits_close);
-//         for item in limits.keys() {
-//             let mut self_clone = self.clone();
-//             let limits_clone = limits.clone();
-//             let item_clone = item.clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let ts = trace_stack.clone();
-//
-//             let handle = tokio::spawn(async move {
-//                 let value = limits_clone[&item_clone].clone();
-//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-//                 let side = value.get(1).unwrap();
-//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-//                 let cid = value.get(3).unwrap();
-//
-//                 //  order_name: [数量,方向,价格,c_id]
-//                 let result = self_clone.take_order(cid, side, price, amount).await;
-//                 match result {
-//                     Ok(mut result) => {
-//                         // 记录此订单完成时间
-//                         // ts.on_after_send();
-//                         result.trace_stack = ts;
-//
-//                         result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         let mut err_order = Order::new();
-//                         err_order.custom_id = cid.clone();
-//                         err_order.status = "REMOVE".to_string();
-//
-//                         result_sd.send(err_order).await.unwrap();
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//         // 检查订单指令
-//         let check = order_command.check;
-//         for item in check.keys() {
-//             let mut self_clone = self.clone();
-//             let check_clone = check.clone();
-//             let item_clone = item.clone();
-//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let handle = tokio::spawn(async move {
-//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-//                 match result {
-//                     Ok(result) => {
-//                         result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//
-//         let futures = FuturesUnordered::from_iter(handles);
-//         let _: Result<Vec<_>, _> = futures.try_collect().await;
-//     }
-// }
-//
-// pub fn format_order_item(data: String) -> Order {
-//     let order_info: SpotOrder = serde_json::from_str(&data).unwrap();
-//     Order {
-//         id: order_info.id,
-//         custom_id: order_info.client_oid,
-//         price: order_info.price,
-//         amount: order_info.size,
-//         deal_amount: order_info.deal_size,
-//         avg_price: order_info.deal_funds / order_info.deal_size,
-//         status: if order_info.is_active { "NEW".to_string() } else { "REMOVE".to_string() },
-//         order_type: order_info.order_type,
-//         trace_stack: TraceStack::new(0, Instant::now()).on_special("811 kucoin_spot".to_string()),
-//     }
-// }

+ 0 - 136
standard/src/kucoin_spot_handle.rs

@@ -1,136 +0,0 @@
-// use std::str::FromStr;
-// use rust_decimal::Decimal;
-// use rust_decimal_macros::dec;
-// use serde_json::json;
-// use tokio::time::Instant;
-// use tracing::trace;
-// use exchanges::response_base::ResponseData;
-// use global::trace_stack::TraceStack;
-// use crate::{Account, MarketOrder, Order, SpecialDepth, SpecialOrder, SpecialTicker};
-// use crate::exchange::ExchangeEnum;
-// use crate::handle_info::HandleSwapInfo;
-//
-// // 处理账号信息
-// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-//     let symbol_upper = symbol.to_uppercase();
-//     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-//     let res_data_str = res_data.data;
-//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&res_data_str).unwrap();
-//     let balance_info_default = json!({"available":"0","currency": symbol_array[1],"hold":"0"});
-//     let balance_info = res_data_json.iter().find(|&item| item["currency"].as_str().unwrap() == symbol_array[1]).unwrap_or(&balance_info_default);
-//     let stocks_info_default = json!({"available":"0","currency": symbol_array[0],"hold":"0"});
-//     let stocks_info = res_data_json.iter().find(|&item| item["currency"].as_str().unwrap() == symbol_array[0]).unwrap_or(&stocks_info_default);
-//     format_account_info(balance_info.clone(), stocks_info.clone())
-// }
-//
-// pub fn format_account_info(balance_data: serde_json::Value, stocks_data: serde_json::Value) -> Account {
-//     let balance_coin = balance_data["currency"].as_str().unwrap().to_string().to_uppercase();
-//     let available_balance = Decimal::from_str(balance_data["available"].as_str().unwrap()).unwrap();
-//     let frozen_balance = Decimal::from_str(balance_data["hold"].as_str().unwrap()).unwrap();
-//     let balance = available_balance + frozen_balance;
-//
-//     let stocks_coin = stocks_data["currency"].as_str().unwrap().to_string().to_uppercase();
-//     let available_stocks = Decimal::from_str(stocks_data["available"].as_str().unwrap()).unwrap();
-//     let frozen_stocks = Decimal::from_str(stocks_data["hold"].as_str().unwrap()).unwrap();
-//     let stocks = available_stocks + frozen_stocks;
-//
-//     Account {
-//         coin: format!("{}_{}", stocks_coin, balance_coin),
-//         balance,
-//         available_balance,
-//         frozen_balance,
-//         stocks,
-//         available_stocks,
-//         frozen_stocks,
-//     }
-// }
-//
-// // 处理order信息
-// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-//     let res_data_str = res_data.data;
-//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-//     let mut order_info = Vec::new();
-//     for item in res_data_json.iter() {
-//         order_info.push(format_order_item(item.clone(), ct_val));
-//     }
-//     trace!(?order_info);
-//     SpecialOrder {
-//         name: res_data.label,
-//         order: order_info,
-//     }
-// }
-//
-// // 处理订单信息
-// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-//     let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
-//     let size = Decimal::from_str(order["size"].as_str().unwrap()).unwrap();
-//     let status = order["status"].as_str().unwrap_or("");
-//     let filled_size = Decimal::from_str(order["filledSize"].as_str().unwrap()).unwrap();
-//
-//     let avg_price = price;
-//
-//     let amount = size * ct_val;
-//     let deal_amount = filled_size * ct_val;
-//     let custom_status = if ["done"].contains(&status) {
-//         "REMOVE".to_string()
-//     } else if ["open", "match", "update"].contains(&status) {
-//         "NEW".to_string()
-//     } else {
-//         "NULL".to_string()
-//     };
-//     Order {
-//         id: order["orderId"].as_str().unwrap().to_string(),
-//         custom_id: order["clientOid"].as_str().unwrap().to_string(),
-//         price,
-//         amount,
-//         deal_amount,
-//         avg_price,
-//         status: custom_status,
-//         order_type: order["orderType"].as_str().unwrap().to_string(),
-//         trace_stack: TraceStack::new(0, Instant::now()).on_special("89 bitget_spot_handle".to_string()),
-//     }
-// }
-//
-// // 处理特殊深度数据
-// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-//     HandleSwapInfo::handle_special_depth(ExchangeEnum::KucoinSpot, res_data)
-// }
-//
-// // 格式化深度信息
-// pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-//     let mut depth_items: Vec<MarketOrder> = vec![];
-//     for value in value.as_array().unwrap() {
-//         depth_items.push(MarketOrder {
-//             price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-//         })
-//     }
-//     return depth_items;
-// }
-//
-// // 处理特殊Ticker信息
-// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-//     let res_data_str = res_data.data;
-//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-//     format_special_ticker(res_data_json, res_data.label)
-// }
-//
-// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-//     let bp = Decimal::from_str(data["bestBid"].as_str().unwrap()).unwrap();
-//     let bq = Decimal::from_str(data["bestBidSize"].as_str().unwrap()).unwrap();
-//     let ap = Decimal::from_str(data["bestAsk"].as_str().unwrap()).unwrap();
-//     let aq = Decimal::from_str(data["bestAskSize"].as_str().unwrap()).unwrap();
-//     let mp = (bp + ap) * dec!(0.5);
-//     let t = Decimal::from_str(data["sequence"].as_str().unwrap()).unwrap();
-//     let create_at = data["time"].as_i64().unwrap() * 1000;
-//
-//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-//     let depth_info = vec![bp, bq, ap, aq];
-//     SpecialDepth {
-//         name: label,
-//         depth: depth_info,
-//         ticker: ticker_info,
-//         t,
-//         create_at,
-//     }
-// }

+ 0 - 675
standard/src/kucoin_swap.rs

@@ -1,675 +0,0 @@
-use std::collections::{BTreeMap};
-use std::io::{Error, ErrorKind};
-use std::str::FromStr;
-use tokio::sync::mpsc::Sender;
-use async_trait::async_trait;
-use futures::stream::FuturesUnordered;
-use futures::TryStreamExt;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
-use rust_decimal_macros::dec;
-use serde_json::{json, Value};
-use tokio::time::Instant;
-use tracing::{error, info};
-use exchanges::kucoin_swap_rest::KucoinSwapRest;
-use global::trace_stack::TraceStack;
-use crate::exchange::ExchangeEnum;
-use crate::{Account, kucoin_handle, Market, Order, OrderCommand, Platform, Position, Ticker, utils};
-
-#[allow(dead_code)]
-#[derive(Clone)]
-pub struct KucoinSwap {
-    exchange: ExchangeEnum,
-    symbol: String,
-    is_colo: bool,
-    params: BTreeMap<String, String>,
-    request: KucoinSwapRest,
-    market: Market,
-    order_sender: Sender<Order>,
-    error_sender: Sender<Error>,
-}
-
-impl KucoinSwap {
-    pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> KucoinSwap {
-        let market = Market::new();
-        let mut kucoin_swap = KucoinSwap {
-            exchange: ExchangeEnum::KucoinSwap,
-            symbol: symbol.to_uppercase(),
-            is_colo,
-            params: params.clone(),
-            request: KucoinSwapRest::new(is_colo, params.clone()),
-            market,
-            order_sender,
-            error_sender,
-        };
-        kucoin_swap.market = KucoinSwap::get_market(&mut kucoin_swap).await.unwrap_or(kucoin_swap.market);
-
-        // 开启自动追加保证金
-        let append_rst = kucoin_swap.set_auto_deposit_status(true).await;
-
-        info!("设置自动追加保证金:{:?}", append_rst.unwrap());
-
-        return kucoin_swap;
-    }
-}
-
-#[async_trait]
-impl Platform for KucoinSwap {
-    // 克隆方法
-    fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-    fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::KucoinSwap
-    }
-    // 获取交易对
-    fn get_self_symbol(&self) -> String { self.symbol.clone() }
-    // 获取是否使用高速通道
-    fn get_self_is_colo(&self) -> bool {
-        self.is_colo
-    }
-    // 获取params信息
-    fn get_self_params(&self) -> BTreeMap<String, String> {
-        self.params.clone()
-    }
-    // 获取market信息
-    fn get_self_market(&self) -> Market { self.market.clone() }
-    // 获取请求时间
-    fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-    // 获取请求平均时间
-    fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-    // 获取请求最大时间
-    fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-    // 获取服务器时间
-    async fn get_server_time(&mut self) -> Result<String, Error> {
-        let res_data = self.request.get_server_time().await;
-        if res_data.code == 200 {
-            Ok(res_data.data.to_string())
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-    // 获取账号信息
-    async fn get_account(&mut self) -> Result<Account, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
-        let res_data = self.request.get_account(symbol_array[1].to_string()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-
-            let balance = Decimal::from_f64(res_data_json["marginBalance"].as_f64().unwrap()).unwrap();
-            let available_balance = Decimal::from_f64(res_data_json["availableBalance"].as_f64().unwrap()).unwrap();
-            let frozen_balance = balance - available_balance;
-            let result = Account {
-                coin: symbol_array[1].to_string(),
-                balance,
-                available_balance,
-                frozen_balance,
-                stocks: Decimal::ZERO,
-                available_stocks: Decimal::ZERO,
-                frozen_stocks: Decimal::ZERO,
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_position(symbol_format).await;
-        if res_data.code == 200 {
-            let result = kucoin_handle::format_position_item(&res_data.data, &ct_val);
-            Ok(vec![result])
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_array: Vec<&str> = symbol_mapper.split("_").collect();
-        let res_data = self.request.get_positions(symbol_array[1].to_string()).await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let res_data_json = res_data.data.as_array().unwrap();
-            let mut result = Vec::new();
-            for item in res_data_json.iter() {
-                result.push(kucoin_handle::format_position_item(item, &Decimal::ONE))
-            }
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.get_ticker(symbol_format).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let ticker_info = res_data_json;
-            let time = (Decimal::from_str(&*ticker_info["ts"].to_string()).unwrap() / dec!(1000000)).floor().to_i64().unwrap();
-
-            let result = Ticker {
-                time,
-                high: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
-                sell_volume: Default::default(),
-                buy: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
-                buy_volume: Default::default(),
-                last: Decimal::from_str(ticker_info["price"].as_str().unwrap()).unwrap(),
-                volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper, ""));
-        let res_data = self.request.get_ticker(symbol_format).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let ticker_info = res_data_json;
-            let time = (Decimal::from_str(&*ticker_info["ts"].to_string()).unwrap() / dec!(1000000)).floor().to_i64().unwrap();
-            let result = Ticker {
-                time,
-                high: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
-                low: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
-                sell: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
-                sell_volume: Default::default(),
-                buy: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
-                buy_volume: Default::default(),
-                last: Decimal::from_str(ticker_info["price"].as_str().unwrap()).unwrap(),
-                volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market(&mut self) -> Result<Market, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.get_market_details().await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-
-            let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
-            match market_info {
-                None => {
-                    error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
-                    let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
-                    let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
-                    let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
-                    let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
-                    let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
-                    let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
-                        base_asset: base_asset_mapper,
-                        quote_asset: quote_asset_mapper,
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
-                        min_notional,
-                        max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-        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_market_details().await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data.as_array().unwrap();
-            let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
-            match market_info {
-                None => {
-                    error!("kucoin_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
-                    Err(Error::new(ErrorKind::Other, res_data.to_string()))
-                }
-                Some(value) => {
-                    let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
-                    let base_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, base_asset.as_str());
-                    let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
-                    let quote_asset_mapper = utils::symbol_out_mapper(ExchangeEnum::KucoinSwap, quote_asset.as_str());
-                    let tick_size = Decimal::from_f64(value["tickSize"].as_f64().unwrap()).unwrap();
-                    let min_qty = Decimal::from_f64(value["lotSize"].as_f64().unwrap()).unwrap();
-                    let ct_val = Decimal::from_f64(value["multiplier"].as_f64().unwrap()).unwrap();
-
-                    let amount_size = min_qty * ct_val;
-                    let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
-                    let amount_precision = Decimal::from_u32(ct_val.scale()).unwrap();
-                    let min_notional = min_qty * ct_val;
-
-                    let result = Market {
-                        symbol: format!("{}_{}", base_asset_mapper, quote_asset_mapper),
-                        base_asset: base_asset_mapper,
-                        quote_asset: quote_asset_mapper,
-                        tick_size,
-                        amount_size,
-                        price_precision,
-                        amount_precision,
-                        min_qty,
-                        max_qty: Decimal::from_f64(value["maxOrderQty"].as_f64().unwrap()).unwrap(),
-                        min_notional,
-                        max_notional: Decimal::from_f64(value["maxPrice"].as_f64().unwrap()).unwrap(),
-                        ct_val,
-                    };
-                    Ok(result)
-                }
-            }
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_orders_details(order_id.to_string(), custom_id.to_string()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let result = format_order_item(res_data_json, ct_val);
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let ct_val = self.market.ct_val;
-        let res_data = self.request.get_orders(status.to_string(), symbol_format.clone()).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let order_list = res_data_json["items"].as_array().unwrap().clone();
-            let order_info: Vec<_> = order_list.iter().filter(|item| item["symbol"].as_str().unwrap_or("") == symbol_format.clone()).collect();
-            let result = order_info.iter().map(|&item| format_order_item(item.clone(), ct_val)).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let ct_val = self.market.ct_val;
-        let mut params = json!({
-            "clientOid": custom_id,
-            "symbol": symbol_format,
-            "leverage": "10",
-            "reduceOnly":false,
-            "price": price.to_string(),
-        });
-        params["type"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
-        let size = (amount / ct_val).floor();
-        params["size"] = json!(size);
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-
-        let res_data = self.request.swap_order(params).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let id = res_data_json["orderId"].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id: custom_id.to_string(),
-                price,
-                amount,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("359 kucoin_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let mut params = json!({
-            "clientOid": custom_id,
-            "symbol": symbol_format,
-            "leverage": "10",
-            "reduceOnly":false,
-            "price": price.to_string(),
-        });
-        let size = (amount / ct_val).floor();
-        params["size"] = json!(size);
-        if price.eq(&Decimal::ZERO){
-            params["type"] = json!("market");
-        }
-        match origin_side {
-            "kd" => {
-                params["side"] = json!("buy");
-            }
-            "pd" => {
-                params["side"] = json!("sell");
-            }
-            "kk" => {
-                params["side"] = json!("sell");
-            }
-            "pk" => {
-                params["side"] = json!("buy");
-            }
-            _ => { error!("下单参数错误"); }
-        };
-
-        let res_data = self.request.swap_order(params).await;
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let id = res_data_json["orderId"].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id: custom_id.to_string(),
-                price,
-                amount,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "NEW".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("408 kucoin_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-        let res_data = self.request.cancel_order(order_id.to_string(), custom_id.to_string()).await;
-        if order_id == "" {
-            error!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id);
-            panic!("Kucoin:撤销订单错误,该交易所为提供自定义订单号撤销订单!\ncancel_order:order_id={:?},custom_id={:?}", order_id, custom_id)
-        }
-        if res_data.code == 200 {
-            let res_data_json = res_data.data;
-            let cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
-            let id = cancel_ids[0].as_str().unwrap().to_string();
-            let result = Order {
-                id,
-                custom_id: custom_id.to_string(),
-                price: Decimal::ZERO,
-                amount: Decimal::ZERO,
-                deal_amount: Decimal::ZERO,
-                avg_price: Decimal::ZERO,
-                status: "REMOVE".to_string(),
-                order_type: "".to_string(),
-                trace_stack: TraceStack::new(0, Instant::now()).on_special("436 kucoin_swap".to_string()),
-            };
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.cancel_orders(symbol_format).await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let res_data_json = res_data.data;
-            let cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
-            let result = cancel_ids.iter().map(|item|
-                Order {
-                    id: item.as_str().unwrap().to_string(),
-                    custom_id: "".to_string(),
-                    price: Decimal::ZERO,
-                    amount: Decimal::ZERO,
-                    deal_amount: Decimal::ZERO,
-                    avg_price: Decimal::ZERO,
-                    status: "REMOVE".to_string(),
-                    order_type: "".to_string(),
-                    trace_stack: TraceStack::new(0, Instant::now()).on_special("461 kucoin_swap".to_string()),
-                }
-            ).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-        let res_data = self.request.cancel_order_all().await;
-        if res_data.code == 200 {
-            info!("{}", res_data.data.to_string());
-            let res_data_json = res_data.data;
-            let cancel_ids = res_data_json["cancelledOrderIds"].as_array().unwrap();
-            let result = cancel_ids.iter().map(|item|
-                Order {
-                    id: item.as_str().unwrap().to_string(),
-                    custom_id: "".to_string(),
-                    price: Decimal::ZERO,
-                    amount: Decimal::ZERO,
-                    deal_amount: Decimal::ZERO,
-                    avg_price: Decimal::ZERO,
-                    status: "REMOVE".to_string(),
-                    order_type: "".to_string(),
-                    trace_stack: TraceStack::new(0, Instant::now()).on_special("486 kucoin_swap".to_string()),
-                }
-            ).collect();
-            Ok(result)
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    async fn set_auto_deposit_status(&mut self, status: bool) -> Result<String, Error> {
-        let symbol_mapper = utils::symbol_enter_mapper(ExchangeEnum::KucoinSwap, self.symbol.as_str());
-        let symbol_format = format!("{}M", utils::format_symbol(symbol_mapper.clone(), ""));
-        let res_data = self.request.auto_deposit_status(symbol_format, status).await;
-        if res_data.code == 200 {
-            Ok(res_data.data.to_string())
-        } else {
-            Err(Error::new(ErrorKind::Other, res_data.to_string()))
-        }
-    }
-
-    async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
-        Err(Error::new(ErrorKind::NotFound, "kucoin_swap:该交易所方法未实现".to_string()))
-    }
-
-    // 指令下单
-    async fn command_order(&mut self, order_command: &mut OrderCommand, trace_stack: &TraceStack) {
-        let mut handles = vec![];
-        // 下单指令,limits_open里已经包含了limits_close,在core里面处理过了
-        for item in order_command.limits_open.keys() {
-            let mut ts = trace_stack.clone();
-
-            let amount = Decimal::from_str(&*order_command.limits_open[item].get(0).unwrap().clone()).unwrap();
-            let side = order_command.limits_open[item].get(1).unwrap().clone();
-            let price = Decimal::from_str(&*order_command.limits_open[item].get(2).unwrap().clone()).unwrap();
-            let cid = order_command.limits_open[item].get(3).unwrap().clone();
-
-            let mut self_clone = self.clone();
-            let handle = tokio::spawn(async move {
-                ts.on_before_send();
-                let result = self_clone.take_order(&cid, &side, price, amount).await;
-                ts.on_after_send();
-
-                match result {
-                    Ok(mut result) => {
-                        // ts.on_after_send();
-                        result.trace_stack = ts.clone();
-
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        let mut err_order = Order::new();
-                        err_order.custom_id = cid.clone();
-                        err_order.status = "REMOVE".to_string();
-
-                        self_clone.order_sender.send(err_order).await.unwrap();
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            handles.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(handles);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 撤销订单
-        let mut cancel_handlers = vec![];
-        for item in order_command.cancel.keys() {
-            let order_id = order_command.cancel[item].get(1).unwrap().clone();
-            let custom_id = order_command.cancel[item].get(0).unwrap().clone();
-
-            let mut self_clone = self.clone();
-
-            let handle = tokio::spawn(async move {
-                if order_id != "" {
-                    let result = self_clone.cancel_order(&order_id, &custom_id).await;
-                    match result {
-                        Ok(_) => {
-                            // result_sd.send(result).await.unwrap();
-                        }
-                        Err(error) => {
-                            // 取消失败去查订单。
-                            let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-                            match query_rst {
-                                Ok(order) => {
-                                    self_clone.order_sender.send(order).await.unwrap();
-                                }
-                                Err(_query_err) => {
-                                    // error!(?_query_err);
-                                    // error!("撤单失败,而且查单也失败了,kucoin_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-                                }
-                            }
-                            self_clone.error_sender.send(error).await.unwrap();
-                        }
-                    }
-                }
-            });
-            cancel_handlers.push(handle)
-        }
-        let futures = FuturesUnordered::from_iter(cancel_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-
-        // 检查订单指令
-        let mut check_handlers = vec![];
-        for item in order_command.check.keys() {
-            let order_id = order_command.check[item].get(1).unwrap().clone();
-            let custom_id = order_command.check[item].get(0).unwrap().clone();
-
-            let mut self_clone = self.clone();
-
-            let handle = tokio::spawn(async move {
-                let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-                match result {
-                    Ok(result) => {
-                        self_clone.order_sender.send(result).await.unwrap();
-                    }
-                    Err(error) => {
-                        self_clone.error_sender.send(error).await.unwrap();
-                    }
-                }
-            });
-            check_handlers.push(handle)
-        }
-
-        let futures = FuturesUnordered::from_iter(check_handlers);
-        // 等待所有任务完成
-        let _: Result<Vec<_>, _> = futures.try_collect().await;
-    }
-}
-
-pub fn format_order_item(order: Value, ct_val: Decimal) -> Order {
-    let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
-    let size = Decimal::from_f64(order["size"].as_f64().unwrap()).unwrap();
-    let status = order["status"].as_str().unwrap_or("");
-    let filled_size = Decimal::from_f64(order["filledSize"].as_f64().unwrap()).unwrap();
-    let filled_value = Decimal::from_str(order["filledValue"].as_str().unwrap()).unwrap();
-
-    let amount = size * ct_val;
-    let deal_amount = filled_size * ct_val;
-    let avg_price = if deal_amount.is_zero() { Decimal::ZERO } else { filled_value / deal_amount };
-    let custom_status;
-    if ["cancelled", "closed", "finished"].contains(&status) {
-        custom_status = "REMOVE".to_string();
-    } else if status == "open" {
-        custom_status = "NEW".to_string();
-    } else {
-        custom_status = "NULL".to_string();
-    };
-    Order {
-        id: order["id"].as_str().unwrap().to_string(),
-        custom_id: order["clientOid"].as_str().unwrap_or("").to_string(),
-        price,
-        amount,
-        deal_amount,
-        avg_price,
-        status: custom_status,
-        order_type: order["type"].as_str().unwrap().to_string(),
-        trace_stack: TraceStack::new(0, Instant::now()).on_special("655 kucoin_swap".to_string()),
-    }
-}

+ 0 - 21
standard/src/lib.rs

@@ -15,31 +15,10 @@ pub mod utils;
 // 引入exchange模块
 // 引入exchange模块
 pub mod exchange;
 pub mod exchange;
 pub mod handle_info;
 pub mod handle_info;
-// 引入binance模块
-mod binance_swap;
-mod binance_spot;
-pub mod binance_swap_handle;
-pub mod binance_spot_handle;
 // 引入gate模块
 // 引入gate模块
 mod gate_swap;
 mod gate_swap;
 mod gate_spot;
 mod gate_spot;
 pub mod gate_swap_handle;
 pub mod gate_swap_handle;
-mod kucoin_swap;
-pub mod kucoin_handle;
-mod okx_swap;
-pub mod okx_handle;
-mod bitget_spot;
-pub mod bitget_spot_handle;
-mod kucoin_spot;
-pub mod kucoin_spot_handle;
-mod bybit_swap;
-mod bybit_swap_handle;
-mod bitget_swap;
-mod bitget_swap_handle;
-mod coinex_swap;
-mod coinex_swap_handle;
-mod htx_swap;
-pub mod htx_swap_handle;
 
 
 /// 持仓模式枚举
 /// 持仓模式枚举
 /// - `Both`:单持仓方向
 /// - `Both`:单持仓方向

+ 0 - 198
standard/src/okx_handle.rs

@@ -1,198 +0,0 @@
-// use std::str::FromStr;
-// use rust_decimal::Decimal;
-// use rust_decimal_macros::dec;
-// use serde::{Deserialize, Serialize};
-// use tokio::time::Instant;
-// use tracing::trace;
-// use exchanges::response_base::ResponseData;
-// use global::trace_stack::TraceStack;
-// use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
-// use crate::exchange::ExchangeEnum;
-// use crate::handle_info::HandleSwapInfo;
-// use crate::okx_swap::SwapPosition;
-//
-//
-// #[derive(Debug, Clone, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// pub struct SwapBalanceAndPositionSubscribe {
-//     pos_data: Vec<SwapBalanceAndPositionPosDataSubscribe>,
-// }
-//
-// #[derive(Debug, Clone, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// pub struct SwapBalanceAndPositionPosDataSubscribe {
-//     pos_id: String,
-//     trade_id: String,
-//     inst_id: String,
-//     inst_type: String,
-//     mgn_mode: String,
-//     pos_side: String,
-//     pos: Decimal,
-//     ccy: String,
-//     pos_ccy: String,
-//     avg_px: Decimal,
-//     u_time: String,
-// }
-//
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SwapPositionSubscribe {
-//     arg: SwapPositionSubscribeArg,
-//     data: Vec<SwapPosition>,
-// }
-//
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SwapPositionSubscribeArg {
-//     channel: String,
-//     uid: String,
-//     inst_type: String,
-// }
-//
-// // 处理账号信息
-// pub fn handle_account_info(res_data: ResponseData, symbol: String) -> Account {
-//     let res_data_str = res_data.data;
-//     let res_data_json: serde_json::Value = serde_json::from_str(&res_data_str).unwrap();
-//     let account_info = res_data_json[0]["details"].clone();
-//     let details = account_info[0].clone();
-//     format_account_info(details, symbol)
-// }
-//
-// pub fn format_account_info(data: serde_json::Value, symbol: String) -> Account {
-//     let symbol_upper = symbol.to_uppercase();
-//     let symbol_array: Vec<&str> = symbol_upper.split("_").collect();
-//     Account {
-//         coin: symbol_array[1].to_string(),
-//         balance: Decimal::from_str(data["cashBal"].as_str().unwrap()).unwrap(),
-//         available_balance: Decimal::from_str(data["availBal"].as_str().unwrap()).unwrap(),
-//         frozen_balance: Decimal::from_str(data["fixedBal"].as_str().unwrap()).unwrap(),
-//         stocks: Decimal::ZERO,
-//         available_stocks: Decimal::ZERO,
-//         frozen_stocks: Decimal::ZERO,
-//     }
-// }
-//
-// // 处理order信息
-// pub fn handle_order(res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-//     let res_data_str = res_data.data;
-//     let res_data_json: Vec<serde_json::Value> = serde_json::from_str(&*res_data_str).unwrap();
-//     trace!(?res_data_json);
-//     let mut order_info = Vec::new();
-//     for item in res_data_json.iter() {
-//         order_info.push(format_order_item(item.clone(), ct_val));
-//     }
-//     trace!(?order_info);
-//     SpecialOrder {
-//         name: res_data.label,
-//         order: order_info,
-//     }
-// }
-//
-// // 处理订单信息
-// pub fn format_order_item(order: serde_json::Value, ct_val: Decimal) -> Order {
-//     let price = Decimal::from_str(order["px"].as_str().unwrap()).unwrap();
-//     let size = Decimal::from_str(order["sz"].as_str().unwrap()).unwrap();
-//     let status = order["state"].as_str().unwrap_or("");
-//     let filled_size = Decimal::from_str(order["accFillSz"].as_str().unwrap()).unwrap();
-//
-//     let avg_price = Decimal::from_str(order["avgPx"].as_str().unwrap()).unwrap();
-//
-//     let amount = size * ct_val;
-//     let deal_amount = filled_size * ct_val;
-//     let custom_status = if ["canceled", "filled", "mmp_canceled"].contains(&status) {
-//         "REMOVE".to_string()
-//     } else if ["live", "partially_filled"].contains(&status) {
-//         "NEW".to_string()
-//     } else {
-//         "NULL".to_string()
-//     };
-//     Order {
-//         id: order["ordId"].as_str().unwrap().to_string(),
-//         custom_id: order["clOrdId"].as_str().unwrap().to_string(),
-//         price,
-//         amount,
-//         deal_amount,
-//         avg_price,
-//         status: custom_status,
-//         order_type: order["ordType"].as_str().unwrap().to_string(),
-//         trace_stack: TraceStack::new(0, Instant::now()).on_special("77 okx_handle".to_string()),
-//     }
-// }
-//
-// // 处理特殊深度数据
-// pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
-//     HandleSwapInfo::handle_special_depth(ExchangeEnum::OkxSwap, res_data)
-// }
-//
-// // 格式化深度信息
-// pub fn format_depth_items(value: serde_json::Value) -> Vec<MarketOrder> {
-//     let mut depth_items: Vec<MarketOrder> = vec![];
-//     for value in value.as_array().unwrap() {
-//         depth_items.push(MarketOrder {
-//             price: Decimal::from_str(value[0].as_str().unwrap()).unwrap(),
-//             amount: Decimal::from_str(value[1].as_str().unwrap()).unwrap(),
-//         })
-//     }
-//     return depth_items;
-// }
-//
-// // 处理特殊Ticker信息
-// pub fn handle_special_ticker(res_data: ResponseData) -> SpecialDepth {
-//     let res_data_str = res_data.data;
-//     let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-//     format_special_ticker(res_data_json[0].clone(), res_data.label)
-// }
-//
-// pub fn format_special_ticker(data: serde_json::Value, label: String) -> SpecialDepth {
-//     let bids = data["bids"][0].as_array().unwrap();
-//     let asks = data["asks"][0].as_array().unwrap();
-//     let bp = Decimal::from_str(bids[0].as_str().unwrap()).unwrap();
-//     let bq = Decimal::from_str(bids[1].as_str().unwrap()).unwrap();
-//     let ap = Decimal::from_str(asks[0].as_str().unwrap()).unwrap();
-//     let aq = Decimal::from_str(asks[1].as_str().unwrap()).unwrap();
-//     let mp = (bp + ap) * dec!(0.5);
-//     let t = Decimal::from_str(&data["seqId"].to_string()).unwrap();
-//     let create_at = data["ts"].as_str().unwrap().parse::<i64>().unwrap() * 1000;
-//
-//     let ticker_info = SpecialTicker { sell: ap, buy: bp, mid_price: mp, t, create_at };
-//     let depth_info = vec![bp, bq, ap, aq];
-//     SpecialDepth {
-//         name: label,
-//         depth: depth_info,
-//         ticker: ticker_info,
-//         t,
-//         create_at,
-//     }
-// }
-//
-//
-// // 处理position信息
-// pub fn handle_position(res_data: ResponseData, ct_val: Decimal) -> Vec<Position> {
-//     let res_data_str = res_data.data;
-//     let data_list: Vec<SwapBalanceAndPositionSubscribe> = serde_json::from_str(&res_data_str).unwrap();
-//
-//     let position_data = data_list[0].pos_data.clone();
-//     if position_data.len() > 0 {
-//         position_data.iter().map(|item| format_position_item(item, ct_val)).collect()
-//     } else {
-//         vec![]
-//     }
-// }
-//
-// pub fn format_position_item(value: &SwapBalanceAndPositionPosDataSubscribe, ct_val: Decimal) -> Position {
-//     let position_mode = match value.pos_side.as_str() {
-//         "long" => { PositionModeEnum::Long }
-//         "short" => { PositionModeEnum::Short }
-//         _ => { PositionModeEnum::Both }
-//     };
-//     Position {
-//         symbol: value.inst_id.replace("-SWAP", ""),
-//         margin_level: Decimal::ZERO,
-//         amount: value.pos * ct_val,
-//         frozen_amount: Decimal::ZERO,
-//         price: value.avg_px,
-//         profit: Decimal::ZERO,
-//         position_mode,
-//         margin: Decimal::ZERO,
-//     }
-// }

+ 0 - 1072
standard/src/okx_swap.rs

@@ -1,1072 +0,0 @@
-// use std::collections::{BTreeMap, HashMap};
-// use std::io::{Error, ErrorKind};
-// use std::str::FromStr;
-// use tokio::sync::mpsc::Sender;
-// use async_trait::async_trait;
-// use futures::stream::FuturesUnordered;
-// use futures::TryStreamExt;
-// use rust_decimal::Decimal;
-// use rust_decimal::prelude::FromPrimitive;
-// use serde::{Deserialize, Serialize};
-// use serde_json::json;
-// use tokio::time::Instant;
-// use tracing::{debug, error};
-// use exchanges::okx_swap_rest::OkxSwapRest;
-// use global::trace_stack::TraceStack;
-// use crate::exchange::ExchangeEnum;
-// use crate::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, Ticker, utils};
-//
-// /// Okx交易所账户信息请求数据结构
-// /// - 接口`"/api/v5/account/balance"`
-// ///
-// /// struct SwapAccount
-// /// - `adj_eq`: String, 美金层面有效保证金
-// /// - `borrow_froz`: String, 账户美金层面潜在借币占用保证金
-// /// - `details`: Vec<SwapAccountDetails>, 各币种资产详细信息
-// /// - `imr`: String, 美金层面占用保证金
-// /// - `iso_eq`: String, 美金层面逐仓仓位权益
-// /// - `mgn_ratio`: String, 美金层面保证金率
-// /// - `mmr`: String, 美金层面维持保证金
-// /// - `notional_usd`: String, 以美金价值为单位的持仓数量,即仓位美金价值
-// /// - `ord_froz`: String, 美金层面全仓挂单占用保证金
-// /// - `total_eq`: String, 美金层面权益
-// /// - `u_time`: String, 账户信息的更新时间
-// ///
-// /// struct SwapAccountDetails
-// /// - `avail_bal`: Decimal, 可用余额
-// /// - `avail_eq`: Decimal, 可用保证金
-// /// - `cash_bal`: Decimal, 币种余额
-// /// - `ccy`: String, 币种
-// /// - `cross_liab`: String, 币种全仓负债额
-// /// - `dis_eq`: Decimal, 美金层面币种折算权益
-// /// - `eq`: Decimal, 币种总权益
-// /// - `eq_usd`: Decimal, 币种权益美金价值
-// /// - `fixed_bal`: Decimal, 币种冻结金额
-// /// - `frozen_bal`: Decimal, 币种占用金额
-// /// - `interest`:String, 计息,应扣未扣利息。
-// /// - `iso_eq`: Decimal, 币种逐仓仓位权益
-// /// - `iso_liab`: String, 逐仓未实现盈亏
-// /// - `iso_upl`: Decimal, 币种逐仓负债额
-// /// - `liab`: String, 币种负债额
-// /// - `max_loan`: String, 币种最大可借
-// /// - `mgn_ratio`: String, 保证金率
-// /// - `notional_lever`: Decimal, 币种杠杆倍数
-// /// - `ord_frozen`: Decimal, 挂单冻结数量
-// /// - `twap`: Decimal, 当前负债币种触发系统自动换币的风险
-// /// - `u_time`: String, 币种余额信息的更新时间
-// /// - `upl`: Decimal, 未实现盈亏
-// /// - `upl_liab`: String, 由于仓位未实现亏损导致的负债
-// /// - `stgy_eq`: Decimal, 策略权益
-// /// - `spot_in_use_amt`: String, 现货对冲占用数量
-// /// - `borrow_froz`: String, 币种美金层面潜在借币占用保证金
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SwapAccount {
-//     adj_eq: String,
-//     borrow_froz: String,
-//     details: Vec<SwapAccountDetails>,
-//     imr: String,
-//     iso_eq: String,
-//     mgn_ratio: String,
-//     mmr: String,
-//     notional_usd: String,
-//     ord_froz: String,
-//     total_eq: String,
-//     u_time: String,
-// }
-//
-// #[derive(Debug, Clone, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SwapAccountDetails {
-//     avail_bal: Decimal,
-//     avail_eq: Decimal,
-//     cash_bal: Decimal,
-//     ccy: String,
-//     cross_liab: String,
-//     dis_eq: Decimal,
-//     eq: Decimal,
-//     eq_usd: Decimal,
-//     fixed_bal: Decimal,
-//     frozen_bal: Decimal,
-//     interest: String,
-//     iso_eq: Decimal,
-//     iso_liab: String,
-//     iso_upl: Decimal,
-//     liab: String,
-//     max_loan: String,
-//     mgn_ratio: String,
-//     notional_lever: Decimal,
-//     ord_frozen: Decimal,
-//     twap: Decimal,
-//     u_time: String,
-//     upl: Decimal,
-//     upl_liab: String,
-//     stgy_eq: Decimal,
-//     spot_in_use_amt: String,
-//     borrow_froz: String,
-// }
-//
-// /// Okx交易所持仓信息请求数据结构
-// /// - 接口`"/api/v5/account/positions"`
-// ///
-// /// struct SwapPosition
-// /// - `adl`: Decimal, 信号区
-// /// - `avail_pos`: Decimal, 可平仓数量,适用于 币币杠杆,交割/永续(开平仓模式)
-// /// - `avg_px`: Decimal, 开仓平均价
-// /// - `c_time`: String, 持仓创建时间
-// /// - `ccy`: String, 占用保证金的币种
-// /// - `delta_b_s`: String, 美金本位持仓仓位delta,仅适用于期权
-// /// - `delta_p_a`: String, 币本位持仓仓位delta,仅适用于期权
-// /// - `gamma_b_s`: String, 美金本位持仓仓位gamma,仅适用于期权
-// /// - `gamma_p_a`: String, 币本位持仓仓位gamma,仅适用于期权
-// /// - `imr`: String, 初始保证金,仅适用于全仓
-// /// - `inst_id`: String, 产品ID
-// /// - `inst_type`: String, 产品类型
-// /// - `interest`: Decimal, 利息,已经生成的未扣利息
-// /// - `idx_px`: Decimal, 最新指数价格
-// /// - `last`: Decimal, 最新成交价
-// /// - `usd_px`: String, 美金价格
-// /// - `be_px`: Decimal, 盈亏平衡价
-// /// - `lever`: Decimal, 杠杆倍数,不适用于期权
-// /// - `liab`: String, 负债额,仅适用于币币杠杆
-// /// - `liab_ccy`: String, 负债币种,仅适用于币币杠杆
-// /// - `liq_px`: Decimal, 预估强平价
-// /// - `mark_px`: Decimal, 最新标记价格
-// /// - `margin`: Decimal, 保证金余额,可增减,仅适用于逐仓
-// /// - `mgn_mode`: Decimal, 保证金模式
-// /// - `mgn_ratio`: Decimal, 保证金率
-// /// - `mmr`: Decimal, 维持保证金
-// /// - `notional_usd`: Decimal, 以美金价值为单位的持仓数量
-// /// - `opt_val`: String, 期权市值,仅适用于期权
-// /// - `p_time`: String,
-// /// - `pos`: Decimal, 持仓数量,逐仓自主划转模式下,转入保证金后会产生pos为0的仓位
-// /// - `pos_ccy`: String, 仓位资产币种,仅适用于币币杠杆仓位
-// /// - `pos_id`: Decimal, 持仓ID
-// /// - `pos_side`: String, 持仓方向
-// /// - `spot_in_use_amt`: String,
-// /// - `spot_in_use_ccy`: String,
-// /// - `theta_b_s`: String, 美金本位持仓仓位theta,仅适用于期权
-// /// - `theta_p_a`: String, 币本位持仓仓位theta,仅适用于期权
-// /// - `trade_id`: Decimal, 最新成交ID
-// /// - `biz_ref_id`: String, 外部业务id
-// /// - `biz_ref_type`: String, 外部业务类型
-// /// - `quote_bal`: Decimal, 计价币余额 ,适用于 币币杠杆(逐仓自主划转模式 和 一键借币模式)
-// /// - `base_bal`: Decimal, 交易币余额,适用于 币币杠杆(逐仓自主划转模式 和 一键借币模式)
-// /// - `base_borrowed`: String, 交易币已借,适用于 币币杠杆(逐仓一键借币模式)
-// /// - `base_interest`: String, 交易币计息,适用于 币币杠杆(逐仓一键借币模式)
-// /// - `quote_borrowed`: String, 计价币已借,适用于 币币杠杆(逐仓一键借币模式)
-// /// - `quote_interest`: String, 计价币计息,适用于 币币杠杆(逐仓一键借币模式)
-// /// - `u_time`: String, 最近一次持仓更新时间
-// /// - `upl`: Decimal, 未实现收益(以标记价格计算)
-// /// - `upl_last_px`: Decimal, 以最新成交价格计算的未实现收益,主要做展示使用,实际值还是 upl
-// /// - `upl_ratio`: Decimal, 未实现收益率(以标记价格计算
-// /// - `upl_ratio_last_px`: Decimal, 以最新成交价格计算的未实现收益率
-// /// - `vega_b_s`: String, 美金本位持仓仓位vega,仅适用于期权
-// /// - `vega_p_a`: String, 币本位持仓仓位vega,仅适用于期权
-// /// - `realized_pnl`: Decimal, 已实现收益
-// /// - `pnl`: Decimal, 平仓订单累计收益额
-// /// - `fee`: Decimal, 累计手续费金额,正数代表平台返佣 ,负数代表平台扣除
-// /// - `funding_fee`: Decimal, 累计资金费用
-// /// - `liq_penalty`: Decimal, 累计爆仓罚金,有值时为负数。
-// /// - `close_order_algo`: Vec<SwapPositionCloseOrderAlgo>, 	平仓策略委托订单
-// ///
-// /// struct SwapPositionCloseOrderAlgo
-// ///
-// /// - `algo_id`: String, 策略委托单ID
-// /// - `sl_trigger_px`: Decimal, 止损触发价
-// /// - `sl_trigger_px_type`: String, 止损触发价类型
-// /// - `tp_trigger_px`: Decimal, 止盈委托价
-// /// - `tp_trigger_px_type`: String, 止盈触发价类型
-// /// - `close_fraction`: Decimal, 策略委托触发时
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// pub struct SwapPosition {
-//     pub adl: String,
-//     pub avail_pos: String,
-//     pub avg_px: Decimal,
-//     pub c_time: String,
-//     pub ccy: String,
-//     pub delta_b_s: String,
-//     pub delta_p_a: String,
-//     pub gamma_b_s: String,
-//     pub gamma_p_a: String,
-//     pub imr: String,
-//     pub inst_id: String,
-//     pub inst_type: String,
-//     pub interest: String,
-//     pub idx_px: String,
-//     pub last: String,
-//     pub usd_px: String,
-//     pub be_px: String,
-//     pub lever: Decimal,
-//     pub liab: String,
-//     pub liab_ccy: String,
-//     pub liq_px: String,
-//     pub mark_px: String,
-//     pub margin: String,
-//     pub mgn_mode: String,
-//     pub mgn_ratio: String,
-//     pub mmr: String,
-//     pub notional_usd: String,
-//     pub opt_val: String,
-//     pub pos: Decimal,
-//     pub pos_ccy: String,
-//     pub pos_id: String,
-//     pub pos_side: String,
-//     pub spot_in_use_amt: String,
-//     pub spot_in_use_ccy: String,
-//     pub theta_b_s: String,
-//     pub theta_p_a: String,
-//     pub trade_id: String,
-//     pub biz_ref_id: String,
-//     pub biz_ref_type: String,
-//     pub quote_bal: String,
-//     pub base_bal: String,
-//     pub base_borrowed: String,
-//     pub base_interest: String,
-//     pub quote_borrowed: String,
-//     pub quote_interest: String,
-//     pub u_time: String,
-//     pub upl: Decimal,
-//     pub upl_last_px: String,
-//     pub upl_ratio: String,
-//     pub upl_ratio_last_px: String,
-//     pub vega_b_s: String,
-//     pub vega_p_a: String,
-//     pub realized_pnl: String,
-//     pub pnl: String,
-//     pub fee: String,
-//     pub funding_fee: String,
-//     pub liq_penalty: String,
-//     pub close_order_algo: Vec<SwapPositionCloseOrderAlgo>,
-// }
-//
-// #[derive(Debug, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// pub struct SwapPositionCloseOrderAlgo {
-//     pub algo_id: String,
-//     pub sl_trigger_px: String,
-//     pub sl_trigger_px_type: String,
-//     pub tp_trigger_px: String,
-//     pub tp_trigger_px_type: String,
-//     pub close_fraction: String,
-// }
-//
-// /// Okx交易所行情信息请求数据结构
-// /// - 接口`"/api/v5/market/ticker"`
-// ///
-// /// struct SwapTicker
-// /// - `inst_type`: String, 产品类型
-// /// - `inst_id`: String, 产品ID
-// /// - `last`: Decimal, 最新成交价
-// /// - `last_sz`: Decimal, 最新成交的数量
-// /// - `ask_px`: Decimal, 卖一价
-// /// - `ask_sz`: Decimal, 卖一价的挂单数数量
-// /// - `bid_px`: Decimal, 买一价
-// /// - `bid_sz`: Decimal, 买一价的挂单数量
-// /// - `open24h`: Decimal, 24小时开盘价
-// /// - `high24h`: Decimal, 24小时最高价
-// /// - `low24h`: Decimal, 24小时最低价
-// /// - `vol_ccy24h`: Decimal, 24小时成交量,以币为单位
-// /// - `vol24h`: Decimal, 24小时成交量,以张为单位
-// /// - `ts`: String, ticker数据产生时间
-// /// - `sod_utc0`: Decimal, UTC 0 时开盘价
-// /// - `sod_utc8`: Decimal, UTC+8 时开盘价
-// #[derive(Debug, Clone, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SwapTicker {
-//     inst_type: String,
-//     inst_id: String,
-//     last: Decimal,
-//     last_sz: Decimal,
-//     ask_px: Decimal,
-//     ask_sz: Decimal,
-//     bid_px: Decimal,
-//     bid_sz: Decimal,
-//     open24h: Decimal,
-//     high24h: Decimal,
-//     low24h: Decimal,
-//     vol_ccy24h: Decimal,
-//     vol24h: Decimal,
-//     ts: String,
-//     sod_utc0: Decimal,
-//     sod_utc8: Decimal,
-// }
-//
-// /// Okx交易所市场信息请求数据结构
-// /// - 接口`"/api/v5/public/instruments"`
-// ///
-// /// struct SwapMarket
-// /// - `alias`: String,
-// /// - `base_ccy`: String,
-// /// - `category`: String,
-// /// - `ct_mult`: Decimal,
-// /// - `ct_type`: String,
-// /// - `ct_val`: Decimal,
-// /// - `ct_val_ccy`: String,
-// /// - `exp_time`: String,
-// /// - `inst_family`: String,
-// /// - `inst_id`: String,
-// /// - `inst_type`: String,
-// /// - `lever`: Decimal,
-// /// - `list_time`: String,
-// /// - `lot_sz`: Decimal,
-// /// - `max_iceberg_sz`: Decimal,
-// /// - `max_lmt_sz`: Decimal,
-// /// - `max_mkt_sz`: Decimal,
-// /// - `max_stop_sz`: Decimal,
-// /// - `max_trigger_sz`: Decimal,
-// /// - `max_twap_sz`: Decimal,
-// /// - `min_sz`: Decimal,
-// /// - `opt_type`: String,
-// /// - `quote_ccy`: String,
-// /// - `settle_ccy`: String,
-// /// - `state`: String,
-// /// - `stk`: String,
-// /// - `tick_sz`: Decimal,
-// /// - `uly`: String,
-// #[derive(Debug, Clone, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// struct SwapMarket {
-//     alias: String,
-//     base_ccy: String,
-//     category: String,
-//     ct_mult: Decimal,
-//     ct_type: String,
-//     ct_val: Decimal,
-//     ct_val_ccy: String,
-//     exp_time: String,
-//     inst_family: String,
-//     inst_id: String,
-//     inst_type: String,
-//     lever: Decimal,
-//     list_time: String,
-//     lot_sz: Decimal,
-//     max_iceberg_sz: Decimal,
-//     max_lmt_sz: Decimal,
-//     max_mkt_sz: Decimal,
-//     max_stop_sz: Decimal,
-//     max_trigger_sz: Decimal,
-//     max_twap_sz: Decimal,
-//     min_sz: Decimal,
-//     opt_type: String,
-//     quote_ccy: String,
-//     settle_ccy: String,
-//     state: String,
-//     stk: String,
-//     tick_sz: Decimal,
-//     uly: String,
-// }
-//
-// /// Okx交易所订单信息请求数据结构
-// /// - 接口`"/api/v5/trade/order"`
-// ///
-// /// struct SwapOrder
-// /// - `inst_type`: String, 产品类型
-// /// - `inst_id`: String, 产品ID
-// /// - `ccy`: String, 保证金币种
-// /// - `ord_id`: String, 订单ID
-// /// - `cl_ord_id`: String, 客户自定义订单ID
-// /// - `tag`: String, 订单标签
-// /// - `px`: Decimal, 委托价格
-// /// - `px_usd`: String, 期权价格
-// /// - `px_vol`: String, 期权订单的隐含波动率
-// /// - `px_type`: String, 期权的价格类型
-// /// - `sz`: Decimal, 委托数量
-// /// - `pnl`: Decimal, 收益
-// /// - `ord_type`: String, 订单类型
-// /// - `side`: String, 订单方向
-// /// - `pos_side`: String, 持仓方向
-// /// - `td_mode`: String, 交易模式
-// /// - `acc_fill_sz`: Decimal, 累计成交数量
-// /// - `fill_px`: String, 最新成交价格,如果成交数量为0,该字段为""
-// /// - `trade_id`: String, 最新成交ID
-// /// - `fill_sz`: Decimal, 最新成交数量
-// /// - `fill_time`: String, 最新成交时间
-// /// - `source`: String, 订单来源
-// /// - `state`: String, 订单状态
-// /// - `avg_px`: Decimal, 成交均价,如果成交数量为0,该字段也为""
-// /// - `lever`: Decimal, 杠杆倍数
-// /// - `attach_algo_cl_ord_id`: String, 下单附带止盈止损时,客户自定义的策略订单ID
-// /// - `tp_trigger_px`: Decimal, 止盈触发价
-// /// - `tp_trigger_px_type`: String, 止盈触发价类型
-// /// - `tp_ord_px`: Decimal, 止盈委托价
-// /// - `sl_trigger_px`: Decimal, 止损触发价
-// /// - `sl_trigger_px_type`: String, 止损触发价类型
-// /// - `sl_ord_px`: Decimal, 止损委托价
-// /// - `stp_id`: String, 自成交保护ID
-// /// - `stp_mode`: String, 自成交保护模式
-// /// - `fee_ccy`: String, 交易手续费币种
-// /// - `fee`: Decimal, 手续费与返佣
-// /// - `rebate_ccy`: String, 返佣金币种
-// /// - `rebate`: String, 返佣金额,仅适用于币币和杠杆
-// /// - `tgt_ccy`: String, 币币市价单委托数量sz的单位
-// /// - `category`: String, 订单种类
-// /// - `reduce_only`: String, 是否只减仓
-// /// - `cancel_source`: String, 	订单取消来源的原因枚举值代码
-// /// - `cancel_source_reason`: String, 订单取消来源的对应具体原因
-// /// - `quick_mgn_type`: String, 一键借币类型,仅适用于杠杆逐仓的一键借币模式
-// /// - `algo_cl_ord_id`: String, 客户自定义策略订单ID
-// /// - `algo_id`: String, 策略委托单ID,策略订单触发时有值,否则为""
-// /// - `u_time`: String, 订单状态更新时间
-// /// - `c_time`: String, 订单创建时间
-// #[derive(Debug, Clone, Deserialize, Serialize)]
-// #[serde(rename_all = "camelCase")]
-// pub struct SwapOrder {
-//     inst_type: String,
-//     inst_id: String,
-//     ccy: String,
-//     ord_id: String,
-//     cl_ord_id: String,
-//     tag: String,
-//     px: Decimal,
-//     px_usd: String,
-//     px_vol: String,
-//     px_type: String,
-//     sz: Decimal,
-//     pnl: String,
-//     ord_type: String,
-//     side: String,
-//     pos_side: String,
-//     td_mode: String,
-//     acc_fill_sz: Decimal,
-//     fill_px: String,
-//     trade_id: String,
-//     fill_sz: String,
-//     fill_time: String,
-//     source: String,
-//     state: String,
-//     avg_px: String,
-//     lever: String,
-//     attach_algo_cl_ord_id: String,
-//     tp_trigger_px: String,
-//     tp_trigger_px_type: String,
-//     tp_ord_px: String,
-//     sl_trigger_px: String,
-//     sl_trigger_px_type: String,
-//     sl_ord_px: String,
-//     stp_id: String,
-//     stp_mode: String,
-//     fee_ccy: String,
-//     fee: String,
-//     rebate_ccy: String,
-//     rebate: String,
-//     tgt_ccy: String,
-//     category: String,
-//     reduce_only: String,
-//     cancel_source: String,
-//     cancel_source_reason: String,
-//     quick_mgn_type: String,
-//     algo_cl_ord_id: String,
-//     algo_id: String,
-//     u_time: String,
-//     c_time: String,
-// }
-//
-// #[allow(dead_code)]
-// #[derive(Clone)]
-// pub struct OkxSwap {
-//     exchange: ExchangeEnum,
-//     symbol: String,
-//     is_colo: bool,
-//     params: BTreeMap<String, String>,
-//     request: OkxSwapRest,
-//     market: Market,
-//     order_sender: Sender<Order>,
-//     error_sender: Sender<Error>,
-// }
-//
-// impl OkxSwap {
-//     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> OkxSwap {
-//         let market = Market::new();
-//         let mut okx_swap = OkxSwap {
-//             exchange: ExchangeEnum::OkxSwap,
-//             symbol: symbol.to_uppercase(),
-//             is_colo,
-//             params: params.clone(),
-//             request: OkxSwapRest::new(is_colo, params.clone()),
-//             market,
-//             order_sender,
-//             error_sender,
-//         };
-//         okx_swap.market = OkxSwap::get_market(&mut okx_swap).await.unwrap_or(okx_swap.market);
-//         return okx_swap;
-//     }
-// }
-//
-// #[async_trait]
-// impl Platform for OkxSwap {
-//     fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
-//
-//     fn get_self_exchange(&self) -> ExchangeEnum { ExchangeEnum::OkxSwap }
-//
-//     fn get_self_symbol(&self) -> String { self.symbol.clone() }
-//
-//     fn get_self_is_colo(&self) -> bool { self.is_colo }
-//
-//     fn get_self_params(&self) -> BTreeMap<String, String> { self.params.clone() }
-//
-//     fn get_self_market(&self) -> Market { self.market.clone() }
-//
-//     fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
-//
-//     fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
-//
-//     fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
-//
-//     async fn get_server_time(&mut self) -> Result<String, Error> {
-//         let res_data = self.request.get_server_time().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
-//             let result = res_data_json[0]["ts"].as_str().unwrap().to_string();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_account(&mut self) -> Result<Account, Error> {
-//         let symbol_array: Vec<&str> = self.symbol.split("_").collect();
-//         let res_data = self.request.get_balance(symbol_array[1].to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let balance_info_list: Vec<SwapAccount> = serde_json::from_str(res_data_str).unwrap();
-//             let detail = balance_info_list[0].details.iter().find(|&item| item.ccy == symbol_array[1]);
-//             match detail {
-//                 None => {
-//                     error!("Okx:获取Account信息错误!\nhandle_swap_account:res_data={:?}", res_data);
-//                     panic!("Okx:获取Account信息错误!\nhandle_swap_account:res_data={:?}", res_data)
-//                 }
-//                 Some(value) => {
-//                     let result = Account {
-//                         coin: value.ccy.to_uppercase(),
-//                         balance: value.avail_bal + value.fixed_bal,
-//                         available_balance: value.avail_bal,
-//                         frozen_balance: value.fixed_bal,
-//                         stocks: Decimal::ZERO,
-//                         available_stocks: Decimal::ZERO,
-//                         frozen_stocks: Decimal::ZERO,
-//                     };
-//                     Ok(result)
-//                 }
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.to_string(), "-"));
-//         let ct_val = self.market.ct_val;
-//         let res_data = self.request.get_positions("SWAP".to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let data_list: Vec<SwapPosition> = serde_json::from_str(&res_data_str).unwrap();
-//             let position_info: Vec<&SwapPosition> = data_list.iter().filter(|item| item.inst_id == symbol_format).collect();
-//             let result = position_info.iter().map(|item| format_position_item(item, ct_val)).collect();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
-//         let res_data = self.request.get_positions("SWAP".to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let data_list: Vec<SwapPosition> = serde_json::from_str(&res_data_str).unwrap();
-//             let result = data_list.iter().map(|item| format_position_item(item, Decimal::ONE)).collect();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_ticker(&mut self) -> Result<Ticker, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-//         let res_data = self.request.get_ticker(symbol_format.clone()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let ticker_info_list: Vec<SwapTicker> = serde_json::from_str(&res_data_str).unwrap();
-//             let ticker_info = ticker_info_list.iter().find(|item| item.inst_id == symbol_format);
-//             match ticker_info {
-//                 None => {
-//                     error!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str);
-//                     panic!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str)
-//                 }
-//                 Some(value) => {
-//                     let result = Ticker {
-//                         time: value.ts.parse().unwrap(),
-//                         high: value.high24h,
-//                         low: value.low24h,
-//                         sell: value.ask_px,
-//                         buy: value.bid_px,
-//                         last: value.last,
-//                         volume: value.last_sz,
-//                     };
-//                     Ok(result)
-//                 }
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_ticker_symbol(&mut self, symbol: String) -> Result<Ticker, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(symbol.clone(), "-"));
-//         let res_data = self.request.get_ticker(symbol_format.clone()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let ticker_info_list: Vec<SwapTicker> = serde_json::from_str(&res_data_str).unwrap();
-//             let ticker_info = ticker_info_list.iter().find(|item| item.inst_id == symbol_format);
-//             match ticker_info {
-//                 None => {
-//                     error!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str);
-//                     panic!("okx_swap:获取Ticker信息错误!\nget_ticker:res_data={:?}", res_data_str)
-//                 }
-//                 Some(value) => {
-//                     let result = Ticker {
-//                         time: value.ts.parse().unwrap(),
-//                         high: value.high24h,
-//                         low: value.low24h,
-//                         sell: value.ask_px,
-//                         buy: value.bid_px,
-//                         last: value.last,
-//                         volume: value.last_sz,
-//                     };
-//                     Ok(result)
-//                 }
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_market(&mut self) -> Result<Market, Error> {
-//         let symbol_format = utils::format_symbol(self.symbol.clone(), "-");
-//         let res_data = self.request.get_instruments().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<SwapMarket> = serde_json::from_str(res_data_str).unwrap();
-//             let market_info = res_data_json.iter().find(|item| item.inst_id == format!("{}-SWAP", symbol_format));
-//             match market_info {
-//                 None => {
-//                     error!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str);
-//                     panic!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str)
-//                 }
-//                 Some(value) => {
-//                     println!("{:?}", value);
-//                     let symbol_array: Vec<&str> = value.inst_family.split("-").collect();
-//                     let result = Market {
-//                         symbol: format!("{}_{}", symbol_array[0], symbol_array[1]),
-//                         base_asset: symbol_array[0].to_string(),
-//                         quote_asset: symbol_array[1].to_string(),
-//                         tick_size: value.tick_sz,
-//                         amount_size: value.min_sz * value.ct_val,
-//                         price_precision: Decimal::from_u32(value.tick_sz.scale()).unwrap(),
-//                         amount_precision: Decimal::from_u32((value.min_sz * value.ct_val).scale()).unwrap(),
-//                         min_qty: value.min_sz,
-//                         max_qty: value.max_lmt_sz,
-//                         min_notional: value.min_sz * value.ct_val,
-//                         max_notional: value.max_lmt_sz * value.ct_val,
-//                         ct_val: value.ct_val,
-//                     };
-//                     Ok(result)
-//                 }
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
-//         let symbol_format = utils::format_symbol(symbol.clone(), "-");
-//         let res_data = self.request.get_instruments().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<SwapMarket> = serde_json::from_str(res_data_str).unwrap();
-//             let market_info = res_data_json.iter().find(|item| item.inst_id == format!("{}-SWAP", symbol_format));
-//             match market_info {
-//                 None => {
-//                     error!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str);
-//                     panic!("okx_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data_str)
-//                 }
-//                 Some(value) => {
-//                     let symbol_array: Vec<&str> = value.inst_family.split("-").collect();
-//                     let result = Market {
-//                         symbol: format!("{}_{}", symbol_array[0], symbol_array[1]),
-//                         base_asset: symbol_array[0].to_string(),
-//                         quote_asset: symbol_array[1].to_string(),
-//                         tick_size: value.tick_sz,
-//                         amount_size: value.min_sz * value.ct_val,
-//                         price_precision: Decimal::from_u32(value.tick_sz.scale()).unwrap(),
-//                         amount_precision: Decimal::from_u32((value.min_sz * value.ct_val).scale()).unwrap(),
-//                         min_qty: value.min_sz,
-//                         max_qty: value.max_lmt_sz,
-//                         min_notional: value.min_sz * value.ct_val,
-//                         max_notional: value.max_lmt_sz * value.ct_val,
-//                         ct_val: value.ct_mult,
-//                     };
-//                     Ok(result)
-//                 }
-//             }
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-//         let ct_val = self.market.ct_val;
-//         let res_data = self.request.get_order(symbol_format, order_id.to_string(), custom_id.to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<SwapOrder> = serde_json::from_str(res_data_str).unwrap();
-//             let order_info = res_data_json[0].clone();
-//             let result = format_order_item(order_info, ct_val);
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-//         let ct_val = self.market.ct_val;
-//         let res_data = self.request.get_incomplete_order(symbol_format.clone()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             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)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-//         let ct_val = self.market.ct_val;
-//         let mut params = json!({
-//             "tdMode": "cross",
-//             "clOrdId": custom_id.to_string(),
-//             "instId": symbol_format,
-//             "px": price.to_string(),
-//         });
-//         params["ordType"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
-//         let size = (amount / ct_val).floor();
-//         params["sz"] = json!(size);
-//         match origin_side {
-//             "kd" => {
-//                 params["side"] = json!("buy");
-//                 params["posSide"] = json!("long");
-//             }
-//             "pd" => {
-//                 params["side"] = json!("sell");
-//                 params["posSide"] = json!("long");
-//             }
-//             "kk" => {
-//                 params["side"] = json!("sell");
-//                 params["posSide"] = json!("short");
-//             }
-//             "pk" => {
-//                 params["side"] = json!("buy");
-//                 params["posSide"] = json!("short");
-//             }
-//             _ => { error!("下单参数错误"); }
-//         };
-//         let res_data = self.request.swap_order(params).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
-//             let order_info = res_data_json[0].clone();
-//             let id = order_info["ordId"].as_str().unwrap().to_string();
-//             let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
-//             let result = Order {
-//                 id,
-//                 custom_id,
-//                 price,
-//                 amount,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "NEW".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("799 okx_swap".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn take_order_symbol(&mut self, symbol: String, ct_val: Decimal, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(symbol.clone(), "-"));
-//         let mut params = json!({
-//             "tdMode": "cross",
-//             "clOrdId": custom_id.to_string(),
-//             "instId": symbol_format,
-//             "px": price.to_string(),
-//         });
-//         params["ordType"] = if price.eq(&Decimal::ZERO) { json!("market") } else { json!("limit") };
-//         let size = (amount / ct_val).floor();
-//         params["sz"] = json!(size);
-//         match origin_side {
-//             "kd" => {
-//                 params["side"] = json!("buy");
-//                 params["posSide"] = json!("long");
-//             }
-//             "pd" => {
-//                 params["side"] = json!("sell");
-//                 params["posSide"] = json!("long");
-//             }
-//             "kk" => {
-//                 params["side"] = json!("sell");
-//                 params["posSide"] = json!("short");
-//             }
-//             "pk" => {
-//                 params["side"] = json!("buy");
-//                 params["posSide"] = json!("short");
-//             }
-//             _ => { error!("下单参数错误"); }
-//         };
-//         let res_data = self.request.swap_order(params).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
-//             let order_info = res_data_json[0].clone();
-//             let id = order_info["ordId"].as_str().unwrap().to_string();
-//             let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
-//             let result = Order {
-//                 id,
-//                 custom_id,
-//                 price,
-//                 amount,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "NEW".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("853 okx_swap".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_order(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-//         let res_data = self.request.cancel_order(symbol_format, order_id.to_string(), custom_id.to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
-//             let order_info = res_data_json[0].clone();
-//             let id = order_info["ordId"].as_str().unwrap().to_string();
-//             let custom_id = order_info["clOrdId"].as_str().unwrap().to_string();
-//             let result = Order {
-//                 id,
-//                 custom_id,
-//                 price: Decimal::ZERO,
-//                 amount: Decimal::ZERO,
-//                 deal_amount: Decimal::ZERO,
-//                 avg_price: Decimal::ZERO,
-//                 status: "REMOVE".to_string(),
-//                 order_type: "".to_string(),
-//                 trace_stack: TraceStack::new(0, Instant::now()).on_special("879 okx_swap".to_string()),
-//             };
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
-//         Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string()))
-//     }
-//
-//     async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
-//         let res_data = self.request.set_position_mode().await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let result = res_data_str.clone();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn set_dual_leverage(&mut self, leverage: &str) -> Result<String, Error> {
-//         let symbol_format = format!("{}-SWAP", utils::format_symbol(self.symbol.clone(), "-"));
-//         let res_data = self.request.set_leverage(symbol_format, leverage.to_string()).await;
-//         if res_data.code == "200" {
-//             let res_data_str = &res_data.data;
-//             let result = res_data_str.clone();
-//             Ok(result)
-//         } else {
-//             Err(Error::new(ErrorKind::Other, res_data.to_string()))
-//         }
-//     }
-//
-//     async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string())) }
-//
-//     async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "okx_swap:该交易所方法未实现".to_string())) }
-//
-//     async fn command_order(&mut self, order_command: OrderCommand, trace_stack: TraceStack) {
-//         let mut handles = vec![];
-//         // 撤销订单
-//         let cancel = order_command.cancel;
-//         for item in cancel.keys() {
-//             let mut self_clone = self.clone();
-//             let cancel_clone = cancel.clone();
-//             let item_clone = item.clone();
-//             let order_id = cancel_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-//             let custom_id = cancel_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let handle = tokio::spawn(async move {
-//                 if order_id != "" {
-//                     let result = self_clone.cancel_order(&order_id, &custom_id).await;
-//                     match result {
-//                         Ok(_) => {
-//                             // result_sd.send(result).await.unwrap();
-//                         }
-//                         Err(error) => {
-//                             // 取消失败去查订单。
-//                             let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
-//                             match query_rst {
-//                                 Ok(order) => {
-//                                     result_sd.send(order).await.unwrap();
-//                                 }
-//                                 Err(query_err) => {
-//                                     error!(?query_err);
-//                                     error!("撤单失败,而且查单也失败了,okx_swap,oid={}, cid={}。", order_id.clone(), custom_id.clone());
-//                                 }
-//                             }
-//                             err_sd.send(error).await.unwrap();
-//                         }
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//         // 下单指令
-//         let mut limits = HashMap::new();
-//         limits.extend(order_command.limits_open);
-//         limits.extend(order_command.limits_close);
-//         for item in limits.keys() {
-//             let mut self_clone = self.clone();
-//             let limits_clone = limits.clone();
-//             let item_clone = item.clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let ts = trace_stack.clone();
-//
-//             let handle = tokio::spawn(async move {
-//                 let value = limits_clone[&item_clone].clone();
-//                 let amount = Decimal::from_str(value.get(0).unwrap_or(&"0".to_string())).unwrap();
-//                 let side = value.get(1).unwrap();
-//                 let price = Decimal::from_str(value.get(2).unwrap_or(&"0".to_string())).unwrap();
-//                 let cid = value.get(3).unwrap();
-//
-//                 //  order_name: [数量,方向,价格,c_id]
-//                 let result = self_clone.take_order(cid, side, price, amount).await;
-//                 match result {
-//                     Ok(mut result) => {
-//                         // ts.on_after_send();
-//                         result.trace_stack = ts.clone();
-//
-//                         result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         let mut err_order = Order::new();
-//                         err_order.custom_id = cid.clone();
-//                         err_order.status = "REMOVE".to_string();
-//
-//                         result_sd.send(err_order).await.unwrap();
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//         // 检查订单指令
-//         let check = order_command.check;
-//         for item in check.keys() {
-//             let mut self_clone = self.clone();
-//             let check_clone = check.clone();
-//             let item_clone = item.clone();
-//             let order_id = check_clone[&item_clone].get(1).unwrap_or(&"".to_string()).clone();
-//             let custom_id = check_clone[&item_clone].get(0).unwrap_or(&"".to_string()).clone();
-//             let result_sd = self.order_sender.clone();
-//             let err_sd = self.error_sender.clone();
-//             let handle = tokio::spawn(async move {
-//                 let result = self_clone.get_order_detail(&order_id, &custom_id).await;
-//                 match result {
-//                     Ok(result) => {
-//                         result_sd.send(result).await.unwrap();
-//                     }
-//                     Err(error) => {
-//                         err_sd.send(error).await.unwrap();
-//                     }
-//                 }
-//             });
-//             handles.push(handle)
-//         }
-//
-//         let futures = FuturesUnordered::from_iter(handles);
-//         let _: Result<Vec<_>, _> = futures.try_collect().await;
-//     }
-// }
-//
-// pub fn format_order_item(data: SwapOrder, ct_val: Decimal) -> Order {
-//     debug!("format-order-start, okx_swap");
-//     debug!(?data);
-//     let custom_status = if ["canceled", "filled", "mmp_canceled"].contains(&data.state.as_str()) {
-//         "REMOVE".to_string()
-//     } else if ["live", "partially_filled"].contains(&data.state.as_str()) {
-//         "NEW".to_string()
-//     } else {
-//         "NULL".to_string()
-//     };
-//
-//     let result = Order {
-//         id: data.ord_id,
-//         custom_id: data.cl_ord_id,
-//         price: data.px,
-//         amount: data.sz * ct_val,
-//         deal_amount: data.acc_fill_sz * ct_val,
-//         avg_price: if data.avg_px != "" { Decimal::from_str(&data.avg_px).unwrap() } else { Decimal::ZERO },
-//         status: custom_status,
-//         order_type: data.ord_type,
-//         trace_stack: TraceStack::new(0, Instant::now()).on_special("1049 okx_swap".to_string()),
-//     };
-//     debug!(?result);
-//     debug!("format-order-end, okx_swap");
-//     result
-// }
-//
-// pub fn format_position_item(value: &SwapPosition, ct_val: Decimal) -> Position {
-//     let position_mode = match value.pos_side.as_str() {
-//         "long" => { PositionModeEnum::Long }
-//         "short" => { PositionModeEnum::Short }
-//         _ => { PositionModeEnum::Both }
-//     };
-//     Position {
-//         symbol: value.inst_id.replace("-SWAP", ""),
-//         margin_level: value.lever,
-//         amount: value.pos * ct_val,
-//         frozen_amount: Decimal::ZERO,
-//         price: value.avg_px,
-//         profit: value.upl,
-//         position_mode,
-//         margin: if value.margin != "" { Decimal::from_str(&value.margin).unwrap() } else { Decimal::ZERO },
-//     }
-// }

+ 10 - 10
standard/src/utils.rs

@@ -22,11 +22,11 @@ pub fn proxy_handle() {
 pub fn symbol_enter_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
 pub fn symbol_enter_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
     let symbol_upper = symbol.to_uppercase();
     let symbol_upper = symbol.to_uppercase();
     match exchange_enum {
     match exchange_enum {
-        ExchangeEnum::KucoinSwap => {
-            if symbol_upper.contains("BTC") {
-                symbol_upper.replace("BTC", "XBT")
-            } else { symbol_upper.to_string() }
-        }
+        // ExchangeEnum::KucoinSwap => {
+        //     if symbol_upper.contains("BTC") {
+        //         symbol_upper.replace("BTC", "XBT")
+        //     } else { symbol_upper.to_string() }
+        // }
         _ => {
         _ => {
             symbol_upper.to_string()
             symbol_upper.to_string()
         }
         }
@@ -49,11 +49,11 @@ pub fn get_tick_size(precision: u32) -> Decimal {
 pub fn symbol_out_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
 pub fn symbol_out_mapper(exchange_enum: ExchangeEnum, symbol: &str) -> String {
     let symbol_upper = symbol.to_uppercase();
     let symbol_upper = symbol.to_uppercase();
     match exchange_enum {
     match exchange_enum {
-        ExchangeEnum::KucoinSwap => {
-            if symbol_upper.contains("XBT") {
-                symbol_upper.replace("XBT", "BTC")
-            } else { symbol_upper.to_string() }
-        }
+        // ExchangeEnum::KucoinSwap => {
+        //     if symbol_upper.contains("XBT") {
+        //         symbol_upper.replace("XBT", "BTC")
+        //     } else { symbol_upper.to_string() }
+        // }
         _ => {
         _ => {
             symbol_upper.to_string()
             symbol_upper.to_string()
         }
         }

+ 0 - 31
standard/tests/binance_handle_test.rs

@@ -1,31 +0,0 @@
-// mod exchange_test;
-// use tracing::instrument;
-// use exchanges::binance_swap_ws::BinanceSwapSubscribeType;
-// use standard::exchange::ExchangeEnum;
-// use crate::exchange_test::test_new_exchange_wss;
-// 
-// const SYMBOL: &str = "BTC_USDT";
-// 
-// // 测试订阅深度信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_depth() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_subscribe_type = vec![
-//         BinanceSwapSubscribeType::PuDepth20levels100ms,
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "depth").await;
-// }
-// 
-// // 测试订阅Ticker信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_subscribe_type = vec![
-//         BinanceSwapSubscribeType::PuBookTicker,
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BinanceSwap, SYMBOL, binance_subscribe_type, "ticker").await;
-// }

+ 0 - 31
standard/tests/binance_spot_handle_test.rs

@@ -1,31 +0,0 @@
-// mod exchange_test;
-// use tracing::instrument;
-// use exchanges::binance_spot_ws::BinanceSpotSubscribeType;
-// use standard::exchange::ExchangeEnum;
-// use crate::exchange_test::test_new_exchange_wss;
-// 
-// const SYMBOL: &str = "BTC_USDT";
-// 
-// // 测试订阅深度信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_depth() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_subscribe_type = vec![
-//         BinanceSpotSubscribeType::PuDepth20levels100ms,
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BinanceSpot, SYMBOL, binance_subscribe_type, "depth").await;
-// }
-// 
-// // 测试订阅Ticker信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_subscribe_type = vec![
-//         BinanceSpotSubscribeType::PuBookTicker,
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BinanceSpot, SYMBOL, binance_subscribe_type, "ticker").await;
-// }

+ 0 - 172
standard/tests/binance_swap_test.rs

@@ -1,172 +0,0 @@
-// mod exchange_test;
-// 
-// use tracing::{instrument, trace};
-// use standard::exchange::{ExchangeEnum};
-// use standard::{Platform};
-// use crate::exchange_test::test_new_exchange;
-// 
-// 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 binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_self_exchange = binance_swap_exchange.get_self_exchange();
-//     trace!(?binance_get_self_exchange);
-// }
-// 
-// // 测试获取交易对信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_symbol() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_self_symbol = binance_swap_exchange.get_self_symbol();
-//     trace!(?binance_get_self_symbol);
-// }
-// 
-// // 测试获取是否使用高速通道
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_is_colo() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_self_is_colo = binance_swap_exchange.get_self_is_colo();
-//     trace!(?binance_get_self_is_colo);
-// }
-// 
-// // 测试获取登录params信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_params() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_self_params = binance_swap_exchange.get_self_params();
-//     trace!("binance_get_self_params={:?}",binance_get_self_params);
-// }
-// 
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_market() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_self_market = binance_swap_exchange.get_self_market();
-//     trace!(?binance_get_self_market);
-// }
-// 
-// // 测试获取请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_delays() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_request_delays = binance_swap_exchange.get_request_delays();
-//     trace!(?binance_get_request_delays);
-// }
-// 
-// // 测试获取请求平均时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_avg_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_request_avg_delay = binance_swap_exchange.get_request_avg_delay();
-//     trace!(?binance_get_request_avg_delay);
-// }
-// 
-// // 测试获取最大请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_max_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_request_max_delay = binance_swap_exchange.get_request_max_delay();
-//     trace!(?binance_get_request_max_delay);
-// }
-// 
-// // 测试获取服务器时间
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_server_time() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_server_time = binance_swap_exchange.get_server_time().await;
-//     trace!(?binance_get_server_time);
-// }
-// 
-// // 测试获取账号信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_account = binance_swap_exchange.get_account().await;
-//     trace!(?binance_get_account);
-// }
-// 
-// // 测试获取持仓信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_position() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_position = binance_swap_exchange.get_position().await;
-//     trace!(?binance_get_position);
-// }
-// 
-// // 测试获取所有持仓信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_positions() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_position = binance_swap_exchange.get_positions().await;
-//     trace!(?binance_get_position);
-// }
-// 
-// // 测试获取Ticker信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_ticker = binance_swap_exchange.get_ticker().await;
-//     trace!(?binance_get_ticker);
-// }
-// 
-// // 测试获取订单详情信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_order_detail() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_order_detail = binance_swap_exchange.get_order_detail("", "9999").await;
-//     trace!(?binance_get_order_detail);
-// }
-// // 测试获取订单详情信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_orders_list() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut binance_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BinanceSwap, SYMBOL).await;
-//     let binance_get_orders_list = binance_swap_exchange.get_orders_list("open").await;
-//     trace!(?binance_get_orders_list);
-// }

+ 0 - 56
standard/tests/bitget_spot_handle_test.rs

@@ -1,56 +0,0 @@
-// mod exchange_test;
-// 
-// use tracing::{instrument};
-// use exchanges::bitget_spot_ws::{BitgetSpotSubscribeType};
-// use standard::exchange::ExchangeEnum;
-// use crate::exchange_test::test_new_exchange_wss;
-// 
-// const SYMBOL: &str = "BLZ_USDT";
-// 
-// // 测试订阅深度订阅
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_depth() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_subscribe_type = vec![
-//         BitgetSpotSubscribeType::PuBooks5
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BitgetSpot, SYMBOL, bitget_subscribe_type, "depth").await;
-// }
-// 
-// // 测试订阅Ticker信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_subscribe_type = vec![
-//         BitgetSpotSubscribeType::PuTicker
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BitgetSpot, SYMBOL, bitget_subscribe_type, "ticker").await;
-// }
-// 
-// // 测试订阅Account信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_subscribe_type = vec![
-//         BitgetSpotSubscribeType::PrAccount
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BitgetSpot, SYMBOL, bitget_subscribe_type, "account").await;
-// }
-// 
-// // 测试订阅Orders信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_subscribe_type = vec![
-//         BitgetSpotSubscribeType::PrOrders
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::BitgetSpot, SYMBOL, bitget_subscribe_type, "orders").await;
-// }

+ 0 - 195
standard/tests/bitget_spot_test.rs

@@ -1,195 +0,0 @@
-// use rust_decimal_macros::dec;
-// use tracing::{instrument, trace};
-// use standard::exchange::ExchangeEnum;
-// use standard::Platform;
-// use crate::exchange_test::test_new_exchange;
-// 
-// mod exchange_test;
-// 
-// const SYMBOL: &str = "BLZ_USDT";
-// 
-// // 测试获取Exchange实体
-// #[tokio::test]
-// async fn test_get_self_exchange() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_self_exchange = bitget_swap_exchange.get_self_exchange();
-//     trace!(?bitget_get_self_exchange);
-// }
-// 
-// // 测试获取交易对信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_symbol() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_self_symbol = bitget_swap_exchange.get_self_symbol();
-//     trace!(?bitget_get_self_symbol);
-// }
-// 
-// // 测试获取是否使用高速通道
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_is_colo() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_self_is_colo = bitget_swap_exchange.get_self_is_colo();
-//     trace!(?bitget_get_self_is_colo);
-// }
-// 
-// // 测试获取登录params信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_params() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_self_params = bitget_swap_exchange.get_self_params();
-//     trace!("bitget_get_self_params={:?}",bitget_get_self_params);
-// }
-// 
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_market() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_self_market = bitget_swap_exchange.get_self_market();
-//     trace!(?bitget_get_self_market);
-// }
-// 
-// // 测试获取请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_delays() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_request_delays = bitget_swap_exchange.get_request_delays();
-//     trace!(?bitget_get_request_delays);
-// }
-// 
-// // 测试获取请求平均时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_avg_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_request_avg_delay = bitget_swap_exchange.get_request_avg_delay();
-//     trace!(?bitget_get_request_avg_delay);
-// }
-// 
-// // 测试获取最大请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_max_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_request_max_delay = bitget_swap_exchange.get_request_max_delay();
-//     trace!(?bitget_get_request_max_delay);
-// }
-// 
-// // 测试获取服务器时间
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_server_time() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_server_time = bitget_swap_exchange.get_server_time().await;
-//     trace!(?bitget_get_server_time);
-// }
-// 
-// // 测试获取账号信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_spot_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_spot_account = bitget_swap_exchange.get_spot_account().await;
-//     trace!(?bitget_get_spot_account);
-// }
-// 
-// // 测试获取Ticker信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_ticker = bitget_swap_exchange.get_ticker().await;
-//     trace!(?bitget_get_ticker);
-// }
-// 
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_market() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_market = bitget_swap_exchange.get_market().await;
-//     trace!(?bitget_get_market);
-// }
-// 
-// // 测试获取Order详情信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_order_detail() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_order_detail = bitget_swap_exchange.get_order_detail("", "999998").await;
-//     trace!(?bitget_get_order_detail);
-// }
-// 
-// // 测试获取Order列表信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_orders_list() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_get_orders_list = bitget_swap_exchange.get_orders_list("").await;
-//     trace!(?bitget_get_orders_list);
-// }
-// 
-// // 测试下单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_take_order() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_take_order = bitget_swap_exchange.take_order("9999922", "kd", dec!(0.21), dec!(30)).await;
-//     trace!(?bitget_take_order);
-// }
-// 
-// // 测试撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_order() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_cancel_order = bitget_swap_exchange.cancel_order("", "999997").await;
-//     trace!(?bitget_cancel_order);
-// }
-// 
-// // 测试撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-//     let bitget_cancel_order = bitget_swap_exchange.cancel_orders().await;
-//     trace!(?bitget_cancel_order);
-// }

+ 0 - 56
standard/tests/htx_handle_test.rs

@@ -1,56 +0,0 @@
-// mod exchange_test;
-// 
-// use tracing::{instrument};
-// use exchanges::htx_swap_ws::HtxSwapSubscribeType;
-// use standard::exchange::ExchangeEnum;
-// use crate::exchange_test::{test_new_exchange_wss};
-// 
-// const SYMBOL: &str = "USTC_USDT";
-// 
-// // 测试订阅深度订阅
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_depth() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let htx_subscribe_type = vec![
-//         HtxSwapSubscribeType::PuFuturesDepth
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::HtxSwap, SYMBOL, htx_subscribe_type, "depth").await;
-// }
-// 
-// // 测试订阅Account信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let htx_subscribe_type = vec![
-//         HtxSwapSubscribeType::PrFuturesBalances
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::HtxSwap, SYMBOL, htx_subscribe_type, "account").await;
-// }
-// 
-// // 测试订阅Position信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_position() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let htx_subscribe_type = vec![
-//         HtxSwapSubscribeType::PrFuturesPositions
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::HtxSwap, SYMBOL, htx_subscribe_type, "position").await;
-// }
-// 
-// // 测试订阅Orders信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let htx_subscribe_type = vec![
-//         HtxSwapSubscribeType::PrFuturesOrders
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::HtxSwap, SYMBOL, htx_subscribe_type, "orders").await;
-// }

+ 0 - 282
standard/tests/htx_swap_test.rs

@@ -1,282 +0,0 @@
-// mod exchange_test;
-//
-// use std::collections::BTreeMap;
-// use std::env;
-// use std::io::Error;
-// use chrono::Utc;
-// use rust_decimal_macros::dec;
-// use tokio::sync::mpsc;
-// use tokio::time::Instant;
-// use tracing::{instrument, trace};
-// use global::trace_stack::TraceStack;
-// use standard::exchange::{Exchange, ExchangeEnum};
-// use standard::{Order, OrderCommand, Platform, utils};
-// use crate::exchange_test::{test_new_exchange};
-//
-// const SYMBOL: &str = "USTC_USDT";
-//
-// // 测试获取Exchange实体
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_exchange() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_self_exchange = htx_swap_exchange.get_self_exchange();
-//     trace!(?htx_get_self_exchange);
-// }
-//
-// // 测试获取交易对信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_symbol() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_self_symbol = htx_swap_exchange.get_self_symbol();
-//     trace!(?htx_get_self_symbol);
-// }
-//
-// // 测试获取是否使用高速通道
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_is_colo() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_self_is_colo = htx_swap_exchange.get_self_is_colo();
-//     trace!(?htx_get_self_is_colo);
-// }
-//
-// // 测试获取登录params信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_params() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_self_params = htx_swap_exchange.get_self_params();
-//     trace!("htx_get_self_params={:?}",htx_get_self_params);
-// }
-//
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_market() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_self_market = htx_swap_exchange.get_self_market();
-//     trace!(?htx_get_self_market);
-// }
-//
-// // 测试获取请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_delays() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_request_delays = htx_swap_exchange.get_request_delays();
-//     trace!(?htx_get_request_delays);
-// }
-//
-// // 测试获取请求平均时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_avg_delay() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_request_avg_delay = htx_swap_exchange.get_request_avg_delay();
-//     trace!(?htx_get_request_avg_delay);
-// }
-//
-// // 测试获取最大请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_max_delay() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_request_max_delay = htx_swap_exchange.get_request_max_delay();
-//     trace!(?htx_get_request_max_delay);
-// }
-//
-// // 测试获取服务器时间
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_server_time() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_server_time = htx_swap_exchange.get_server_time().await;
-//     trace!(?htx_get_server_time);
-// }
-//
-// // 测试获取账号信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_account() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_account = htx_swap_exchange.get_account().await;
-//     trace!(?htx_get_account);
-// }
-//
-// // 测试获取持仓信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_position() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_position = htx_swap_exchange.get_position().await;
-//     trace!(?htx_get_position);
-// }
-//
-// // 测试获取所有持仓信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_positions() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_positions = htx_swap_exchange.get_positions().await;
-//     trace!(?htx_get_positions);
-// }
-//
-// // 测试获取Ticker信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_ticker() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_ticker = htx_swap_exchange.get_ticker().await;
-//     trace!(?htx_get_ticker);
-// }
-//
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_market() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_market = htx_swap_exchange.get_market().await;
-//     trace!(?htx_get_market);
-// }
-//
-// // 测试获取Order详情信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_order_detail() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_order_detail = htx_swap_exchange.get_order_detail("1234925996822429696", "9999992").await;
-//     trace!(?htx_get_order_detail);
-// }
-//
-// // 测试获取Order列表信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_orders_list() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_get_orders_list = htx_swap_exchange.get_orders_list("finished").await;
-//     trace!(?htx_get_orders_list);
-// }
-//
-// // 测试下单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_take_order() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_take_order = htx_swap_exchange.take_order("999999914", "kd", dec!(0.02320), dec!(20)).await;
-//     trace!(?htx_take_order);
-// }
-//
-// // 测试撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_order() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_cancel_order = htx_swap_exchange.cancel_order("", "999999900").await;
-//     trace!(?htx_cancel_order);
-// }
-//
-// // 测试批量撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_orders() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_cancel_orders = htx_swap_exchange.cancel_orders_all().await;
-//     trace!(?htx_cancel_orders);
-// }
-//
-// // 测试设置持仓模式
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_set_dual_mode() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_set_dual_mode = htx_swap_exchange.set_dual_mode("usdt", true).await;
-//     trace!(?htx_set_dual_mode);
-// }
-//
-// // 测试设置杠杆
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_set_dual_leverage() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::HtxSwap, SYMBOL).await;
-//     let htx_set_dual_leverage = htx_swap_exchange.set_dual_leverage("10").await;
-//     trace!(?htx_set_dual_leverage);
-// }
-//
-// // 测试指令下单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_command_order() {
-//     global::log_utils::init_log_with_trace();
-//     utils::proxy_handle();
-//
-//     let (order_sender, mut order_receiver): (mpsc::Sender<Order>, mpsc::Receiver<Order>) = mpsc::channel(1024);
-//     let (error_sender, mut error_receiver): (mpsc::Sender<Error>, mpsc::Receiver<Error>) = mpsc::channel(1024);
-//
-//     let mut params: BTreeMap<String, String> = BTreeMap::new();
-//     let access_key = env::var("htx_access_key").unwrap_or("".to_string());
-//     let secret_key = env::var("htx_secret_key").unwrap_or("".to_string());
-//     params.insert("access_key".to_string(), access_key);
-//     params.insert("secret_key".to_string(), secret_key);
-//
-//     let mut htx_swap_exchange: Box<dyn Platform> = Exchange::new(ExchangeEnum::HtxSwap, SYMBOL.to_string(), false, params, order_sender, error_sender).await;
-//
-//     let mut command = OrderCommand::new();
-//     command.cancel.insert("888888".to_string(), vec!["888888".to_string(), "".to_string()]);
-//     command.limits_open.insert("888888".to_string(), vec!["100".to_string(), "kd".to_string(), "0.18".to_string(), "888888".to_string()]);
-//     command.limits_close.insert("999999".to_string(), vec!["100".to_string(), "kk".to_string(), "0.25".to_string(), "999999".to_string()]);
-//     command.check.insert("888888".to_string(), vec!["999999".to_string(), "".to_string()]);
-//     htx_swap_exchange.command_order(&mut command, &TraceStack::new(Utc::now().timestamp_micros(), Instant::now())).await;
-//
-//     loop {
-//         if let Ok(order) = order_receiver.try_recv() {
-//             trace!(?order);
-//         }
-//         if let Ok(error) = error_receiver.try_recv() {
-//             trace!(?error);
-//         }
-//     }
-// }

+ 0 - 68
standard/tests/kucoin_handle_test.rs

@@ -1,68 +0,0 @@
-// mod exchange_test;
-// 
-// use tracing::{instrument};
-// use exchanges::kucoin_swap_ws::{KucoinSwapSubscribeType};
-// use standard::exchange::ExchangeEnum;
-// use crate::exchange_test::test_new_exchange_wss;
-// 
-// const SYMBOL: &str = "BLZ_USDT";
-// 
-// // 测试订阅深度订阅
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_depth() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSwapSubscribeType::PuContractMarketLevel2Depth50
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSwap, SYMBOL, kucoin_subscribe_type, "depth").await;
-// }
-// 
-// // 测试订阅Ticker信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSwapSubscribeType::PuContractMarkettickerV2
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSwap, SYMBOL, kucoin_subscribe_type, "ticker").await;
-// }
-// 
-// // 测试订阅Account信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSwapSubscribeType::PrContractAccountWallet
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSwap, SYMBOL, kucoin_subscribe_type, "account").await;
-// }
-// 
-// // 测试订阅Position信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_position() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSwapSubscribeType::PrContractPosition
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSwap, SYMBOL, kucoin_subscribe_type, "position").await;
-// }
-// 
-// // 测试订阅Orders信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSwapSubscribeType::PrContractMarketTradeOrders
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSwap, SYMBOL, kucoin_subscribe_type, "orders").await;
-// }

+ 0 - 56
standard/tests/kucoin_spot_handle_test.rs

@@ -1,56 +0,0 @@
-// mod exchange_test;
-// 
-// use tracing::{instrument};
-// use exchanges::kucoin_spot_ws::{KucoinSpotSubscribeType};
-// use standard::exchange::ExchangeEnum;
-// use crate::exchange_test::test_new_exchange_wss;
-// 
-// const SYMBOL: &str = "BTC_USDT";
-// 
-// // 测试订阅深度订阅
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_depth() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSpot, SYMBOL, kucoin_subscribe_type, "depth").await;
-// }
-// 
-// // 测试订阅Ticker信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSpotSubscribeType::PuMarketTicker
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSpot, SYMBOL, kucoin_subscribe_type, "ticker").await;
-// }
-// 
-// // 测试订阅Account信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSpotSubscribeType::PrAccountBalance
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSpot, SYMBOL, kucoin_subscribe_type, "account").await;
-// }
-// 
-// // 测试订阅Orders信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_subscribe_type = vec![
-//         KucoinSpotSubscribeType::PrSpotMarketTradeOrders
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::KucoinSpot, SYMBOL, kucoin_subscribe_type, "orders").await;
-// }

+ 0 - 145
standard/tests/kucoin_spot_test.rs

@@ -1,145 +0,0 @@
-// mod exchange_test;
-//
-// use std::collections::BTreeMap;
-// use std::env;
-// use std::io::Error;
-// use rust_decimal_macros::dec;
-// use tokio::sync::mpsc;
-// use tracing::{instrument, trace};
-// use standard::exchange::{Exchange, ExchangeEnum};
-// use standard::{Order, OrderCommand, Platform, utils};
-// use crate::exchange_test::{test_new_exchange};
-//
-// 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 kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_self_exchange = kucoin_spot_exchange.get_self_exchange();
-//     trace!(?kucoin_get_self_exchange);
-// }
-//
-// // 测试获取交易对信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_symbol() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_self_symbol = kucoin_spot_exchange.get_self_symbol();
-//     trace!(?kucoin_get_self_symbol);
-// }
-//
-// // 测试获取是否使用高速通道
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_is_colo() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_self_is_colo = kucoin_spot_exchange.get_self_is_colo();
-//     trace!(?kucoin_get_self_is_colo);
-// }
-//
-// // 测试获取登录params信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_params() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_self_params = kucoin_spot_exchange.get_self_params();
-//     trace!("kucoin_get_self_params={:?}",kucoin_get_self_params);
-// }
-//
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_market() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_self_market = kucoin_spot_exchange.get_self_market();
-//     trace!(?kucoin_get_self_market);
-// }
-//
-// // 测试获取请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_delays() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_request_delays = kucoin_spot_exchange.get_request_delays();
-//     trace!(?kucoin_get_request_delays);
-// }
-//
-// // 测试获取请求平均时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_avg_delay() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_request_avg_delay = kucoin_spot_exchange.get_request_avg_delay();
-//     trace!(?kucoin_get_request_avg_delay);
-// }
-//
-// // 测试获取最大请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_max_delay() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_request_max_delay = kucoin_spot_exchange.get_request_max_delay();
-//     trace!(?kucoin_get_request_max_delay);
-// }
-//
-// // 测试获取服务器时间
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_server_time() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_server_time = kucoin_spot_exchange.get_server_time().await;
-//     trace!(?kucoin_get_server_time);
-// }
-//
-// // 测试获取账号信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_account() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_account = kucoin_spot_exchange.get_account().await;
-//     trace!(?kucoin_get_account);
-// }
-//
-// // 测试获取Ticker信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_ticker() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_ticker = kucoin_spot_exchange.get_ticker().await;
-//     trace!(?kucoin_get_ticker);
-// }
-//
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_market() {
-//     global::log_utils::init_log_with_trace();
-//
-//     let mut kucoin_spot_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSpot, SYMBOL).await;
-//     let kucoin_get_market = kucoin_spot_exchange.get_market().await;
-//     trace!(?kucoin_get_market);
-// }

+ 0 - 271
standard/tests/kucoin_swap_test.rs

@@ -1,271 +0,0 @@
-// mod exchange_test;
-// 
-// use std::collections::BTreeMap;
-// use std::env;
-// use std::io::Error;
-// use rust_decimal_macros::dec;
-// use tokio::sync::mpsc;
-// use tracing::{instrument, trace};
-// use standard::exchange::{Exchange, ExchangeEnum};
-// use standard::{Order, OrderCommand, Platform, utils};
-// use crate::exchange_test::{test_new_exchange};
-// 
-// const SYMBOL: &str = "BTC_USDT";
-// 
-// // 测试获取Exchange实体
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_exchange() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_self_exchange = kucoin_swap_exchange.get_self_exchange();
-//     trace!(?kucoin_get_self_exchange);
-// }
-// 
-// // 测试获取交易对信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_symbol() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_self_symbol = kucoin_swap_exchange.get_self_symbol();
-//     trace!(?kucoin_get_self_symbol);
-// }
-// 
-// // 测试获取是否使用高速通道
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_is_colo() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_self_is_colo = kucoin_swap_exchange.get_self_is_colo();
-//     trace!(?kucoin_get_self_is_colo);
-// }
-// 
-// // 测试获取登录params信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_params() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_self_params = kucoin_swap_exchange.get_self_params();
-//     trace!("kucoin_get_self_params={:?}",kucoin_get_self_params);
-// }
-// 
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_market() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_self_market = kucoin_swap_exchange.get_self_market();
-//     trace!(?kucoin_get_self_market);
-// }
-// 
-// // 测试获取请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_delays() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_request_delays = kucoin_swap_exchange.get_request_delays();
-//     trace!(?kucoin_get_request_delays);
-// }
-// 
-// // 测试获取请求平均时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_avg_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_request_avg_delay = kucoin_swap_exchange.get_request_avg_delay();
-//     trace!(?kucoin_get_request_avg_delay);
-// }
-// 
-// // 测试获取最大请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_max_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_request_max_delay = kucoin_swap_exchange.get_request_max_delay();
-//     trace!(?kucoin_get_request_max_delay);
-// }
-// 
-// // 测试获取服务器时间
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_server_time() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_server_time = kucoin_swap_exchange.get_server_time().await;
-//     trace!(?kucoin_get_server_time);
-// }
-// 
-// // 测试获取账号信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_account = kucoin_swap_exchange.get_account().await;
-//     trace!(?kucoin_get_account);
-// }
-// 
-// // 测试获取持仓信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_position() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_position = kucoin_swap_exchange.get_position().await;
-//     trace!(?kucoin_get_position);
-// }
-// 
-// // 测试获取所有持仓信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_positions() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_positions = kucoin_swap_exchange.get_positions().await;
-//     trace!(?kucoin_get_positions);
-// }
-// 
-// // 测试获取Ticker信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_ticker = kucoin_swap_exchange.get_ticker().await;
-//     trace!(?kucoin_get_ticker);
-// }
-// 
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_market() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_market = kucoin_swap_exchange.get_market().await;
-//     trace!(?kucoin_get_market);
-// }
-// 
-// // 测试获取Order详情信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_order_detail() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_order_detail = kucoin_swap_exchange.get_order_detail("", "999999").await;
-//     trace!(?kucoin_get_order_detail);
-// }
-// 
-// // 测试获取Order列表信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_orders_list() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_get_orders_list = kucoin_swap_exchange.get_orders_list("active").await;
-//     trace!(?kucoin_get_orders_list);
-// }
-// 
-// // 测试下单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_take_order() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_take_order = kucoin_swap_exchange.take_order("999999", "kk", dec!(0), dec!(100)).await;
-//     trace!(?kucoin_take_order);
-// }
-// 
-// // 测试撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_order() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_cancel_order = kucoin_swap_exchange.cancel_order("108721685804371970", "").await;
-//     trace!(?kucoin_cancel_order);
-// }
-// 
-// // 测试撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_cancel_orders = kucoin_swap_exchange.cancel_orders().await;
-//     trace!(?kucoin_cancel_orders);
-// }
-// 
-// 
-// // 测试设置自动追加保证金
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_set_auto_deposit_status() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_set_auto_deposit_status = kucoin_swap_exchange.set_auto_deposit_status(true).await;
-//     trace!(?kucoin_set_auto_deposit_status);
-// }
-// 
-// // 测试指令下单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_command_order() {
-//     global::log_utils::init_log_with_trace();
-//     utils::proxy_handle();
-// 
-//     let (order_sender, mut order_receiver): (mpsc::Sender<Order>, mpsc::Receiver<Order>) = mpsc::channel(1024);
-//     let (error_sender, mut error_receiver): (mpsc::Sender<Error>, mpsc::Receiver<Error>) = mpsc::channel(1024);
-// 
-//     let mut params: BTreeMap<String, String> = BTreeMap::new();
-//     let access_key = env::var("kucoin_access_key").unwrap_or("".to_string());
-//     let secret_key = env::var("kucoin_secret_key").unwrap_or("".to_string());
-//     let pass_key = env::var("kucoin_pass_key").unwrap_or("".to_string());
-//     params.insert("access_key".to_string(), access_key);
-//     params.insert("secret_key".to_string(), secret_key);
-//     params.insert("pass_key".to_string(), pass_key);
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = Exchange::new(ExchangeEnum::KucoinSwap, SYMBOL.to_string(), false, params, order_sender, error_sender).await;
-//     let mut command = OrderCommand::new();
-//     // command.cancel.insert("888888".to_string(), vec!["888888".to_string(), "94647166466789377".to_string()]);
-//     command.limits_open.insert("888888".to_string(), vec!["100".to_string(), "kd".to_string(), "0.18".to_string(), "888888".to_string()]);
-//     command.limits_close.insert("999999".to_string(), vec!["100".to_string(), "kk".to_string(), "0.25".to_string(), "999999".to_string()]);
-//     // command.check.insert("888888".to_string(), vec!["999999".to_string(), "94647166466789377".to_string()]);
-//     kucoin_swap_exchange.command_order(command, Default::default()).await;
-// 
-// 
-//     loop {
-//         if let Ok(order) = order_receiver.try_recv() {
-//             trace!(?order);
-//         }
-//         if let Ok(error) = error_receiver.try_recv() {
-//             trace!(?error);
-//         }
-//     }
-// }

+ 0 - 68
standard/tests/okx_handle_test.rs

@@ -1,68 +0,0 @@
-// mod exchange_test;
-// 
-// use tracing::{instrument};
-// use exchanges::okx_swap_ws::OkxSwapSubscribeType;
-// use standard::exchange::ExchangeEnum;
-// use crate::exchange_test::test_new_exchange_wss;
-// 
-// const SYMBOL: &str = "BTC_USDT";
-// 
-// // 测试订阅深度订阅
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_depth() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_subscribe_type = vec![
-//         OkxSwapSubscribeType::PuBooks5
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::OkxSwap, SYMBOL, okx_subscribe_type, "depth").await;
-// }
-// 
-// // 测试订阅Ticker信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_subscribe_type = vec![
-//         OkxSwapSubscribeType::PuBooks5
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::OkxSwap, SYMBOL, okx_subscribe_type, "ticker").await;
-// }
-// 
-// // 测试订阅Account信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_subscribe_type = vec![
-//         OkxSwapSubscribeType::PrAccount("USDT".to_string())
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::OkxSwap, SYMBOL, okx_subscribe_type, "account").await;
-// }
-// 
-// // 测试订阅Position信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_position() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_subscribe_type = vec![
-//         OkxSwapSubscribeType::PrPositions
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::OkxSwap, SYMBOL, okx_subscribe_type, "position").await;
-// }
-// 
-// // 测试订阅Orders信息
-// #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-// #[instrument(level = "TRACE")]
-// async fn test_get_wss_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_subscribe_type = vec![
-//         OkxSwapSubscribeType::PrOrders
-//     ];
-//     test_new_exchange_wss(ExchangeEnum::OkxSwap, SYMBOL, okx_subscribe_type, "orders").await;
-// }

+ 0 - 229
standard/tests/okx_swap_test.rs

@@ -1,229 +0,0 @@
-// use rust_decimal_macros::dec;
-// use tracing::{instrument, trace};
-// use standard::exchange::ExchangeEnum;
-// use standard::Platform;
-// use crate::exchange_test::test_new_exchange;
-// 
-// mod exchange_test;
-// 
-// const SYMBOL: &str = "CRO_USDT";
-// 
-// // 测试获取Exchange实体
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_exchange() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_self_exchange = okx_swap_exchange.get_self_exchange();
-//     trace!(?okx_get_self_exchange);
-// }
-// 
-// // 测试获取交易对信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_symbol() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_self_symbol = okx_swap_exchange.get_self_symbol();
-//     trace!(?okx_get_self_symbol);
-// }
-// 
-// // 测试获取是否使用高速通道
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_is_colo() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_self_is_colo = okx_swap_exchange.get_self_is_colo();
-//     trace!(?okx_get_self_is_colo);
-// }
-// 
-// // 测试获取登录params信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_params() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_self_params = okx_swap_exchange.get_self_params();
-//     trace!("okx_get_self_params={:?}",okx_get_self_params);
-// }
-// 
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_self_market() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_self_market = okx_swap_exchange.get_self_market();
-//     trace!(?okx_get_self_market);
-// }
-// 
-// // 测试获取请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_delays() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_request_delays = okx_swap_exchange.get_request_delays();
-//     trace!(?okx_get_request_delays);
-// }
-// 
-// // 测试获取请求平均时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_avg_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_request_avg_delay = okx_swap_exchange.get_request_avg_delay();
-//     trace!(?okx_get_request_avg_delay);
-// }
-// 
-// // 测试获取最大请求时间信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_request_max_delay() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_request_max_delay = okx_swap_exchange.get_request_max_delay();
-//     trace!(?okx_get_request_max_delay);
-// }
-// 
-// // 测试获取服务器时间
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_server_time() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_server_time = okx_swap_exchange.get_server_time().await;
-//     trace!(?okx_get_server_time);
-// }
-// 
-// // 测试获取账号信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_account() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_account = okx_swap_exchange.get_account().await;
-//     trace!(?okx_get_account);
-// }
-// 
-// // 测试获取仓位信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_position() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_position = okx_swap_exchange.get_position().await;
-//     trace!(?okx_get_position);
-// }
-// 
-// // 测试获取Ticker信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_ticker() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_ticker = okx_swap_exchange.get_ticker().await;
-//     trace!(?okx_get_ticker);
-// }
-// 
-// // 测试获取Market信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_market() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_market = okx_swap_exchange.get_market().await;
-//     trace!(?okx_get_market);
-// }
-// 
-// // 测试获取Order详情信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_order_detail() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_order_detail = okx_swap_exchange.get_order_detail("", "999997").await;
-//     trace!(?okx_get_order_detail);
-// }
-// 
-// // 测试获取Order列表信息
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_get_orders_list() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_get_orders_list = okx_swap_exchange.get_orders_list("active").await;
-//     trace!(?okx_get_orders_list);
-// }
-// 
-// // 测试下单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_take_order() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_take_order = okx_swap_exchange.take_order("999997", "kk", dec!(0.0901), dec!(100)).await;
-//     trace!(?okx_take_order);
-// }
-// 
-// // 测试撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_order() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_cancel_order = okx_swap_exchange.cancel_order("", "999998").await;
-//     trace!(?okx_cancel_order);
-// }
-// 
-// // 测试撤销订单
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_cancel_orders() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut kucoin_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::KucoinSwap, SYMBOL).await;
-//     let kucoin_cancel_orders = kucoin_swap_exchange.cancel_orders().await;
-//     trace!(?kucoin_cancel_orders);
-// }
-// 
-// // 测试设置持仓模式
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_set_dual_mode() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_set_dual_mode = okx_swap_exchange.set_dual_mode("usdt", true).await;
-//     trace!(?okx_set_dual_mode);
-// }
-// 
-// // 测试设置杠杆
-// #[tokio::test]
-// #[instrument(level = "TRACE")]
-// async fn test_set_dual_leverage() {
-//     global::log_utils::init_log_with_trace();
-// 
-//     let mut okx_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::OkxSwap, SYMBOL).await;
-//     let okx_set_dual_leverage = okx_swap_exchange.set_dual_leverage("10").await;
-//     trace!(?okx_set_dual_leverage);
-// }

+ 0 - 137
strategy/src/binance_spot.rs

@@ -1,137 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// use futures_util::StreamExt;
-// use rust_decimal::Decimal;
-// use tokio::spawn;
-// use tokio::sync::Mutex;
-// use exchanges::binance_spot_ws::{BinanceSpotSubscribeType, BinanceSpotWs, BinanceSpotWsType};
-// use exchanges::response_base::ResponseData;
-// use global::trace_stack::TraceStack;
-// use standard::exchange::ExchangeEnum::BinanceSpot;
-// use crate::exchange_disguise::on_special_depth;
-// use crate::core::Core;
-//
-// // 参考 币安 现货 启动
-// pub async fn reference_binance_spot_run(is_shutdown_arc :Arc<AtomicBool>,
-//                                         core_arc: Arc<Mutex<Core>>,
-//                                         name: String,
-//                                         symbols: Vec<String>,
-//                                         is_colo: bool,
-//                                         _exchange_params: BTreeMap<String, String>) {
-//     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-//     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
-//
-//     let mut ws = BinanceSpotWs::new_label(name.clone(), is_colo, None, BinanceSpotWsType::PublicAndPrivate);
-//     ws.set_symbols(symbols.clone());
-//     ws.set_subscribe(vec![
-//         BinanceSpotSubscribeType::PuBookTicker,
-//         // BinanceSpotSubscribeType::PuDepth20levels100ms
-//     ]);
-//
-//     // 开启数据读取线程
-//     let write_tx_am = Arc::new(Mutex::new(write_tx));
-//     let core_arc_clone = core_arc.clone();
-//
-//     spawn(async move {
-//         //链接
-//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
-//         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//     });
-//
-//     spawn(async move {
-//         // trade
-//         let mut max_buy = Decimal::ZERO;
-//         let mut min_sell = Decimal::ZERO;
-//         // ticker
-//         let mut update_flag_u = Decimal::ZERO;
-//
-//         loop {
-//             if let Some(data) = read_rx.next().await {
-//                 on_data(core_arc_clone.clone(),
-//                         &mut update_flag_u,
-//                         &mut max_buy,
-//                         &mut min_sell,
-//                         data).await;
-//             }
-//         }
-//     });
-//
-//     // let (tx, mut rx) = channel(100);
-//     // spawn(async move {
-//     //     let mut ba_exc = BinanceSpotWs::new_label(name, false, None, BinanceSpotWsType::PublicAndPrivate);
-//     //     ba_exc.set_subscribe(vec![
-//     //         // BinanceSpotSubscribeType::PuAggTrade,
-//     //         // BinanceSpotSubscribeType::PuBookTicker,
-//     //         BinanceSpotSubscribeType::PuDepth20levels100ms
-//     //     ]);
-//     //     ba_exc.custom_subscribe(is_shutdown_arc, symbols.clone()).await;
-//     // });
-//     //
-//     // spawn(async move {
-//     //     let core_arc_clone = Arc::clone(&core_arc);
-//     //     // trade
-//     //     let mut max_buy = Decimal::ZERO;
-//     //     let mut min_sell = Decimal::ZERO;
-//     //     // ticker
-//     //     let mut update_flag_u = 0i64;
-//     //     loop {
-//     //         // sleep(Duration::from_micros(10)).await;
-//     //
-//     //         match rx.try_recv() {
-//     //             Ok(data) => {
-//     //                 on_data(core_arc_clone.clone(), &mut update_flag_u, &mut max_buy, &mut min_sell, data).await;
-//     //             },
-//     //             Err(_e) => { }
-//     //         }
-//     //
-//     //     }
-//     // });
-// }
-//
-// async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
-//                  update_flag_u: &mut Decimal,
-//                  _max_buy: &mut Decimal,
-//                  _min_sell: &mut Decimal,
-//                  data: ResponseData) {
-//     let mut trace_stack = TraceStack::new(0, Instant::now());
-//     trace_stack.on_after_network(data.time);
-//     trace_stack.on_before_unlock_core();
-//
-//     if data.code != "200".to_string() {
-//         return;
-//     }
-//     if data.channel == "aggTrade" {
-//         // let trade: OriginalTradeBa = serde_json::from_str(data.data.as_str()).unwrap();
-//         // let str = data.label.clone();
-//         // let mut core = core_arc_clone.lock().await;
-//         // if core.is_update.contains_key(&data.label) && *core.is_update.get(str.as_str()).unwrap() {
-//         //     *max_buy = Decimal::ZERO;
-//         //     *min_sell = Decimal::ZERO;
-//         //     core.is_update.remove(str.as_str());
-//         // }
-//         // if trade.p > *max_buy || *max_buy == Decimal::ZERO{
-//         //     *max_buy = trade.p
-//         // }
-//         // if trade.p < *min_sell || *min_sell == Decimal::ZERO{
-//         //     *min_sell = trade.p
-//         // }
-//         // {
-//         //     core.max_buy_min_sell_cache.insert(data.label, vec![*max_buy, *min_sell]);
-//         // }
-//     } else if data.channel == "bookTicker" {
-//         trace_stack.on_before_format();
-//         let special_depth = standard::handle_info::HandleSwapInfo::handle_special_ticker(BinanceSpot, data.clone());
-//         trace_stack.on_after_format();
-//         trace_stack.on_before_network(special_depth.create_at);
-//
-//         on_special_depth(core_arc_clone, update_flag_u, data.label, trace_stack, special_depth).await;
-//     } else if data.channel == "depth" {
-//         trace_stack.on_before_format();
-//         let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(BinanceSpot, data.clone());
-//         trace_stack.on_after_format();
-//         trace_stack.on_before_network(special_depth.create_at);
-//
-//         on_special_depth(core_arc_clone, update_flag_u, data.label, trace_stack, special_depth).await;
-//     }
-// }

+ 0 - 104
strategy/src/binance_usdt_swap.rs

@@ -1,104 +0,0 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use rust_decimal::Decimal;
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::Message;
-use tracing::error;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::{TraceStack};
-use standard::exchange::ExchangeEnum::BinanceSwap;
-use crate::core::Core;
-use exchanges::binance_swap_ws::{BinanceSwapSubscribeType, BinanceSwapWs, BinanceSwapWsType};
-use crate::exchange_disguise::{on_special_depth};
-
-// 参考 币安 合约 启动
-pub(crate) async fn reference_binance_swap_run(is_shutdown_arc: Arc<AtomicBool>,
-                                               core_arc: Arc<Mutex<Core>>,
-                                               name: String,
-                                               symbols: Vec<String>,
-                                               is_colo: bool,
-                                               _exchange_params: BTreeMap<String, String>) {
-    tokio::spawn(async move {
-        //创建读写通道
-        let (write_tx, write_rx) = futures_channel::mpsc::unbounded::<Message>();
-        let mut ws = BinanceSwapWs::new_label(name, is_colo, None, BinanceSwapWsType::PublicAndPrivate);
-        ws.set_symbols(symbols);
-        ws.set_subscribe(vec![
-            // BinanceSwapSubscribeType::PuDepth20levels100ms,
-            BinanceSwapSubscribeType::PuBookTicker,
-            // BinanceSwapSubscribeType::PuAggTrade
-        ]);
-
-        // 读取数据
-        let mut update_flag_u = Decimal::ZERO;
-        let core_arc_clone = Arc::clone(&core_arc);
-        let fun = move |data: ResponseData| {
-            // 在 async 块之前克隆 Arc
-            let core_arc_cc = core_arc_clone.clone();
-            async move {
-                // 使用克隆后的 Arc,避免 move 语义
-                on_data(core_arc_cc,
-                        &mut update_flag_u,
-                        data).await
-            }
-        };
-
-        // 链接
-        let write_tx_am = Arc::new(Mutex::new(write_tx));
-        ws.ws_connect_async(is_shutdown_arc, fun, &write_tx_am, write_rx).await.expect("链接失败");
-    });
-}
-
-async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
-                 update_flag_u: &mut Decimal,
-                 response: ResponseData) {
-    let mut trace_stack = TraceStack::new(response.time, response.ins);
-    trace_stack.on_after_span_line();
-
-    match response.channel.as_str() {
-        "aggTrade" => {
-            // let trade: OriginalTradeBa = serde_json::from_str(data.data.as_str()).unwrap();
-            // let name = data.label.clone();
-
-            // 订单流逻辑
-            // on_trade(trade.clone(), core_arc_clone.clone()).await;
-
-            // 原本的逻辑
-            // let mut core = core_arc_clone.lock().await;
-            // let str = data.label.clone();
-            // if core.is_update.contains_key(&data.label) && *core.is_update.get(str.as_str()).unwrap() {
-            //     *_max_buy = Decimal::ZERO;
-            //     *_min_sell = Decimal::ZERO;
-            //     core.is_update.remove(str.as_str());
-            // }
-            // if trade.p > *_max_buy || *_max_buy == Decimal::ZERO {
-            //     *_max_buy = trade.p
-            // }
-            // if trade.p < *_min_sell || *_min_sell == Decimal::ZERO {
-            //     *_min_sell = trade.p
-            // }
-            // core.max_buy_min_sell_cache.insert(data.label, vec![*_max_buy, *_min_sell]);
-        }
-        "bookTicker" => {
-            trace_stack.set_source("binance_usdt_swap.bookTicker".to_string());
-            // 将ticker数据转换为模拟深度
-            let special_depth = standard::handle_info::HandleSwapInfo::handle_book_ticker(BinanceSwap, &response).await;
-            trace_stack.on_after_format();
-
-            on_special_depth(core_arc_clone, update_flag_u, &response.label, &mut trace_stack, &special_depth).await;
-        }
-        "depth" => {
-            trace_stack.set_source("binance_usdt_swap.depth".to_string());
-            // 将depth数据转换为模拟深度
-            let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(BinanceSwap, &response);
-            trace_stack.on_after_format();
-
-            on_special_depth(core_arc_clone, update_flag_u, &response.label, &mut trace_stack, &special_depth).await;
-        }
-        _ => {
-            error!("未知推送类型");
-            error!(?response);
-        }
-    }
-}

+ 0 - 222
strategy/src/bitget_spot.rs

@@ -1,222 +0,0 @@
-// use std::collections::BTreeMap;
-// use std::sync::Arc;
-// use std::sync::atomic::AtomicBool;
-// use std::time::Duration;
-// use futures_util::StreamExt;
-// use rust_decimal::Decimal;
-// use tokio::spawn;
-// use tokio::sync::Mutex;
-// use tokio::time::sleep;
-// use exchanges::bitget_spot_ws::{BitgetSpotLogin, BitgetSpotSubscribeType, BitgetSpotWs, BitgetSpotWsType};
-// use exchanges::response_base::ResponseData;
-// use global::trace_stack::TraceStack;
-// use standard::exchange::ExchangeEnum::BitgetSpot;
-// use crate::exchange_disguise::on_special_depth;
-// use crate::model::{OrderInfo, OriginalTradeGa};
-// use crate::core::Core;
-//
-// pub async fn bitget_spot_run(is_shutdown_arc :Arc<AtomicBool>,
-//                              is_trade: bool,
-//                              core_arc: Arc<Mutex<Core>>,
-//                              name: String,
-//                              symbols: Vec<String>,
-//                              is_colo: bool,
-//                              exchange_params: BTreeMap<String, String>) {
-//     // 开启公共频道
-//     let (write_tx_public, write_rx_public) = futures_channel::mpsc::unbounded();
-//     let (read_tx_public, mut read_rx_public) = futures_channel::mpsc::unbounded();
-//     let mut ku_public = BitgetSpotWs::new_label(name.clone(),
-//                                                 is_colo,
-//                                                 None,
-//                                                 BitgetSpotWsType::Public);
-//     ku_public.set_symbols(symbols.clone());
-//     // 交易交易所只用订阅深度数据
-//     if is_trade {
-//         ku_public.set_subscribe(vec![
-//             BitgetSpotSubscribeType::PuBooks5
-//         ]);
-//     } else {
-//         // 参考交易所还要订阅实时订单流数据
-//         ku_public.set_subscribe(vec![
-//             BitgetSpotSubscribeType::PuTrade,
-//             BitgetSpotSubscribeType::PuBooks5
-//         ]);
-//     }
-//     // 开启公共连接
-//     let is_shutdown_arc_c1 = is_shutdown_arc.clone();
-//     let write_tx_am_public = Arc::new(Mutex::new(write_tx_public));
-//     spawn(async move {
-//         ku_public.ws_connect_async(is_shutdown_arc_c1,
-//                                    &write_tx_am_public,
-//                                    write_rx_public,
-//                                    read_tx_public)
-//             .await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//     });
-//     // 消费数据
-//     let core_arc_clone = core_arc.clone();
-//     spawn(async move {
-//         // ticker
-//         let mut update_flag_u = Decimal::ZERO;
-//         let mut max_buy = Decimal::ZERO;
-//         let mut min_sell = Decimal::ZERO;
-//
-//         loop {
-//             if let Some(data) = read_rx_public.next().await {
-//                 on_public_data(core_arc_clone.clone(),
-//                         &mut update_flag_u,
-//                         &mut max_buy,
-//                         &mut min_sell,
-//                         data).await;
-//             }
-//         }
-//     });
-//
-//     // 开启私有频道
-//     if is_trade {
-//         // 新增获取余额的协程
-//         let account_core_arc = core_arc.clone();
-//         spawn(async move {
-//             loop {
-//                 // 每30秒重新获取一次
-//                 sleep(Duration::from_secs(30)).await;
-//
-//                 {
-//                     let mut core = account_core_arc.lock().await;
-//                     core.update_equity_rest_spot().await;
-//                 }
-//             }
-//         });
-//
-//         // 其余也要再开两个通道,不能与公共频道混用
-//         let (write_tx_private, write_rx_public) = futures_channel::mpsc::unbounded();
-//         let (read_tx_private, mut read_rx_public) = futures_channel::mpsc::unbounded();
-//         let is_shutdown_arc_c2 = is_shutdown_arc.clone();
-//         let write_tx_am_private = Arc::new(Mutex::new(write_tx_private));
-//         spawn(async move {
-//             let login_params = parse_btree_map_to_bitget_spot_login(exchange_params);
-//             let mut ku_private = BitgetSpotWs::new_label(name.clone(),
-//                                                          is_colo,
-//                                                          Some(login_params),
-//                                                          BitgetSpotWsType::Private);
-//             ku_private.set_symbols(symbols.clone());
-//             ku_private.set_subscribe(vec![
-//                 BitgetSpotSubscribeType::PrAccount,
-//                 BitgetSpotSubscribeType::PrOrders,
-//             ]);
-//
-//             ku_private.ws_connect_async(is_shutdown_arc_c2,
-//                                         &write_tx_am_private,
-//                                         write_rx_public,
-//                                         read_tx_private)
-//                 .await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-//         });
-//
-//         // 消费数据
-//         let core_arc_clone = core_arc.clone();
-//         spawn(async move {
-//             let ct_val = core_arc.clone().lock().await.platform_rest.get_self_market().ct_val;
-//
-//             loop {
-//                 if let Some(data) = read_rx_public.next().await {
-//                     on_private_data(core_arc_clone.clone(),
-//                                    ct_val,
-//                                    data).await;
-//                 }
-//             }
-//         });
-//     }
-// }
-//
-// async fn on_private_data(core_arc_clone: Arc<Mutex<Core>>, ct_val: Decimal, data: ResponseData) {
-//     let mut trace_stack = TraceStack::new(0, Instant::now());
-//
-//     trace_stack.on_after_network(data.time);
-//     trace_stack.on_before_unlock_core();
-//
-//     if data.code != "200".to_string() {
-//         return;
-//     }
-//
-//     if data.channel == "orders" {
-//         trace_stack.on_before_format();
-//         let orders = standard::handle_info::HandleSwapInfo::handle_order(BitgetSpot, data.clone(), ct_val);
-//         trace_stack.on_after_format();
-//         let mut order_infos:Vec<OrderInfo> = Vec::new();
-//         for order in orders.order {
-//             if order.status == "NULL" {
-//                 continue;
-//             }
-//             let order_info = OrderInfo {
-//                 symbol: "".to_string(),
-//                 amount: order.amount.abs(),
-//                 side: "".to_string(),
-//                 price: order.price,
-//                 client_id: order.custom_id,
-//                 filled_price: order.avg_price,
-//                 filled: order.deal_amount.abs(),
-//                 order_id: order.id,
-//                 local_time: 0,
-//                 create_time: 0,
-//                 status: order.status,
-//                 fee: Default::default(),
-//                 trace_stack: Default::default(),
-//             };
-//             order_infos.push(order_info);
-//         }
-//         {
-//             let mut core = core_arc_clone.lock().await;
-//             core.update_order(order_infos, trace_stack);
-//         }
-//     } else if data.channel == "account" {
-//         // let account = standard::handle_info::HandleSwapInfo::handle_account_info(BitgetSpot, data, run_symbol.clone());
-//         // {
-//         //     let mut core = core_arc_clone.lock().await;
-//         //     core.update_equity(account);
-//         // }
-//     }
-// }
-//
-// async fn on_public_data(core_arc_clone: Arc<Mutex<Core>>, update_flag_u: &mut Decimal, max_buy: &mut Decimal, min_sell: &mut Decimal, data: ResponseData) {
-//     let mut trace_stack = TraceStack::new(0, Instant::now());
-//
-//     trace_stack.on_after_network(data.time);
-//     trace_stack.on_before_unlock_core();
-//
-//     if data.code != "200".to_string() {
-//         return;
-//     }
-//
-//     if data.channel == "books5" {
-//         trace_stack.on_before_format();
-//         let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(BitgetSpot, data.clone());
-//         trace_stack.on_after_format();
-//
-//         on_special_depth(core_arc_clone, update_flag_u, data.label, trace_stack, special_depth).await;
-//     } else if data.channel == "trade" {
-//         let mut core = core_arc_clone.lock().await;
-//         let str = data.label.clone();
-//         if core.is_update.contains_key(&data.label) && *core.is_update.get(str.as_str()).unwrap() {
-//             *max_buy = Decimal::ZERO;
-//             *min_sell = Decimal::ZERO;
-//             core.is_update.remove(str.as_str());
-//         }
-//         let trades: Vec<OriginalTradeGa> = serde_json::from_str(data.data.as_str()).unwrap();
-//         for trade in trades {
-//             if trade.price > *max_buy || *max_buy == Decimal::ZERO {
-//                 *max_buy = trade.price
-//             }
-//             if trade.price < *min_sell || *min_sell == Decimal::ZERO {
-//                 *min_sell = trade.price
-//             }
-//         }
-//         core.max_buy_min_sell_cache.insert(data.label, vec![*max_buy, *min_sell]);
-//     }
-// }
-//
-// fn parse_btree_map_to_bitget_spot_login(exchange_params: BTreeMap<String, String>) -> BitgetSpotLogin {
-//     BitgetSpotLogin {
-//         api_key: exchange_params.get("access_key").unwrap().clone(),
-//         secret_key: exchange_params.get("secret_key").unwrap().clone(),
-//         passphrase_key: exchange_params.get("pass_key").unwrap().clone(),
-//     }
-// }

+ 0 - 189
strategy/src/bitget_usdt_swap.rs

@@ -1,189 +0,0 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use rust_decimal::Decimal;
-use tokio::spawn;
-use tokio::sync::Mutex;
-use tracing::{error, info};
-use exchanges::bitget_swap_ws::{BitgetSwapLogin, BitgetSwapSubscribeType, BitgetSwapWs, BitgetSwapWsType};
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use standard::exchange::ExchangeEnum::{BitgetSwap};
-use standard::{Position, PositionModeEnum};
-use crate::core::Core;
-use crate::exchange_disguise::on_special_depth;
-use crate::model::OrderInfo;
-
-pub async fn bitget_usdt_swap_run(is_shutdown_arc :Arc<AtomicBool>,
-                                  is_trade: bool,
-                                  core_arc: Arc<Mutex<Core>>,
-                                  name: String,
-                                  symbols: Vec<String>,
-                                  is_colo: bool,
-                                  exchange_params: BTreeMap<String, String>) {
-    // 开启公共频道
-    let (write_tx_public, write_rx_public) = futures_channel::mpsc::unbounded();
-
-    // 开启公共连接
-    let is_shutdown_arc_c1 = is_shutdown_arc.clone();
-    let write_tx_am_public = Arc::new(Mutex::new(write_tx_public));
-    let name_clone = name.clone();
-    let core_arc_clone = core_arc.clone();
-    let symbols_clone = symbols.clone();
-    spawn(async move {
-        // 构建链接ws
-        let mut bg_public = BitgetSwapWs::new_label(name_clone.clone(),
-                                                    is_colo,
-                                                    None,
-                                                    BitgetSwapWsType::Public);
-
-        // 消费数据的函数
-        let mut update_flag_u = Decimal::ZERO;
-        let fun = move |data: ResponseData| {
-            let core_arc_cc = core_arc_clone.clone();
-
-            async move {
-                on_public_data(core_arc_cc, &mut update_flag_u, data).await
-            }
-        };
-
-        // 准备链接
-        bg_public.set_subscribe(vec![BitgetSwapSubscribeType::PuBooks1]); // 只用订阅深度数据
-        bg_public.set_symbols(symbols_clone);
-        bg_public.ws_connect_async(is_shutdown_arc_c1, fun, &write_tx_am_public, write_rx_public).await.expect("bitget_usdt_swap 链接有异常")
-    });
-
-    // 不需要交易就不用开启私有频道了
-    if !is_trade {
-        return;
-    }
-
-    // 开启私有频道
-    let (write_tx_private, write_rx_private) = futures_channel::mpsc::unbounded();
-
-    // 开启公共连接
-    let is_shutdown_arc_c1 = is_shutdown_arc.clone();
-    let write_tx_am_private = Arc::new(Mutex::new(write_tx_private));
-    spawn(async move {
-        // 构建链接ws
-        let mut bg_private = BitgetSwapWs::new_label(name.clone(),
-                                                     is_colo,
-                                                     Some(parse_btree_map_to_bitget_swap_login(exchange_params)),
-                                                     BitgetSwapWsType::Private);
-
-        // 消费数据的函数
-        let core_arc_clone = core_arc.clone();
-        let run_symbol = symbols[0].clone();
-        let ct_val = core_arc_clone.lock().await.platform_rest.get_self_market().ct_val;
-        let fun = move |data: ResponseData| {
-            let core_arc_cc = core_arc_clone.clone();
-            let run_symbol_c = run_symbol.clone();
-
-            async move {
-                on_private_data(core_arc_cc, ct_val, data, &run_symbol_c).await
-            }
-        };
-
-        // 准备链接
-        bg_private.set_subscribe(vec![
-            BitgetSwapSubscribeType::PrOrders,
-            BitgetSwapSubscribeType::PrAccount,
-            BitgetSwapSubscribeType::PrPosition
-        ]);
-        bg_private.set_symbols(symbols.clone());
-        bg_private.ws_connect_async(is_shutdown_arc_c1, fun, &write_tx_am_private, write_rx_private).await.expect("bitget_usdt_swap 链接有异常")
-    });
-}
-
-async fn on_private_data(core_arc_clone: Arc<Mutex<Core>>,
-                         ct_val: Decimal,
-                         response: ResponseData,
-                         run_symbol: &String) {
-    let mut trace_stack = TraceStack::new(response.time, response.ins);
-    trace_stack.on_after_span_line();
-
-    // public类型,目前只考虑订单流数据
-    match response.channel.as_str() {
-        "account" => {
-            let account = standard::handle_info::HandleSwapInfo::handle_account_info(BitgetSwap, &response, run_symbol);
-            let mut core = core_arc_clone.lock().await;
-            core.update_equity(account).await;
-        },
-        "positions" => {
-            let mut positions = standard::handle_info::HandleSwapInfo::handle_position(BitgetSwap, &response, &ct_val);
-
-            // bitget如果没有仓位不会给0,会给个空数组
-            if positions.is_empty() {
-                positions.push(Position {
-                    symbol: run_symbol.replace("_", "").to_uppercase(),
-                    margin_level: Default::default(),
-                    amount: Default::default(),
-                    frozen_amount: Default::default(),
-                    price: Default::default(),
-                    profit: Default::default(),
-                    position_mode: PositionModeEnum::Both,
-                    margin: Default::default(),
-                });
-            }
-
-            let mut core = core_arc_clone.lock().await;
-            core.update_position(positions).await;
-        },
-        "orders" => {
-            trace_stack.set_source("gate_swap.orders".to_string());
-            let orders = standard::handle_info::HandleSwapInfo::handle_order(BitgetSwap, response.clone(), ct_val.clone());
-
-            let mut order_infos:Vec<OrderInfo> = Vec::new();
-            for mut order in orders.order {
-                if order.status == "NULL" {
-                    error!("bitget_usdt_swap 未识别的订单状态:{:?}", response);
-
-                    continue;
-                }
-
-                let order_info = OrderInfo::parse_order_to_order_info(&mut order);
-                order_infos.push(order_info);
-            }
-
-            {
-                let mut core = core_arc_clone.lock().await;
-                core.update_order(order_infos, trace_stack).await;
-            }
-        },
-        "pong" => {}
-        _ => {
-            info!("bitget_usdt_swap 113 未知的订阅数据: {:?}", response);
-        }
-    }
-}
-
-async fn on_public_data(core_arc_clone: Arc<Mutex<Core>>,
-                        update_flag_u: &mut Decimal,
-                        response: ResponseData) {
-    let mut trace_stack = TraceStack::new(response.time, response.ins);
-    trace_stack.on_after_span_line();
-
-    // public类型,目前只考虑订单流数据
-    match response.channel.as_str() {
-        "books1" => {
-            trace_stack.set_source("bitget_usdt_swap.books1".to_string());
-            let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(BitgetSwap, &response);
-            trace_stack.on_after_format();
-
-            on_special_depth(core_arc_clone, update_flag_u, &response.label, &mut trace_stack, &special_depth).await;
-        },
-        "pong" => {},
-        _ => {
-            info!("bitget_usdt_swap 125 未知的订阅数据");
-            info!(?response)
-        }
-    }
-}
-
-fn parse_btree_map_to_bitget_swap_login(exchange_params: BTreeMap<String, String>) -> BitgetSwapLogin {
-    BitgetSwapLogin {
-        api_key: exchange_params.get("access_key").unwrap().clone(),
-        secret_key: exchange_params.get("secret_key").unwrap().clone(),
-        passphrase_key: exchange_params.get("pass_key").unwrap().clone(),
-    }
-}

+ 0 - 252
strategy/src/bybit_usdt_swap.rs

@@ -1,252 +0,0 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::{AtomicBool};
-use rust_decimal::Decimal;
-use tokio::{spawn};
-use tokio::sync::Mutex;
-use tracing::{error, info};
-use exchanges::bybit_swap_ws::{BybitSwapLogin, BybitSwapSubscribeType, BybitSwapWs, BybitSwapWsType};
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use standard::exchange::ExchangeEnum::BybitSwap;
-use crate::core::Core;
-use crate::exchange_disguise::on_special_depth;
-use crate::model::OrderInfo;
-
-// 1交易、0参考 bybit 合约 启动
-pub async fn bybit_swap_run(is_shutdown_arc: Arc<AtomicBool>,
-                            is_trade: bool,
-                            core_arc: Arc<Mutex<Core>>,
-                            name: String,
-                            symbols: Vec<String>,
-                            is_colo: bool,
-                            exchange_params: BTreeMap<String, String>) {
-    // 启动公共频道
-    let (write_tx_public, write_rx_public) = futures_channel::mpsc::unbounded();
-
-    let mut ws_public = BybitSwapWs::new_label(name.clone(), is_colo, None, BybitSwapWsType::Public);
-    ws_public.set_symbols(symbols.clone());
-    ws_public.set_subscribe(vec![
-        BybitSwapSubscribeType::PuTickers
-    ]);
-    // if is_trade {
-    //     ws_public.set_subscribe(vec![
-    //         BybitSwapSubscribeType::PuBlicTrade
-    //     ]);
-    // }
-    // 挂起公共ws
-    let write_tx_am_public = Arc::new(Mutex::new(write_tx_public));
-    let is_shutdown_clone_public = Arc::clone(&is_shutdown_arc);
-    let core_arc_clone_public = core_arc.clone();
-    spawn(async move {
-        // 消费数据
-        let mut update_flag_u = Decimal::ZERO;
-
-        let fun = move |data: ResponseData| {
-            let core_arc = core_arc_clone_public.clone();
-
-            async move {
-                on_public_data(core_arc,
-                               &mut update_flag_u,
-                               data).await;
-            }
-        };
-
-        ws_public.ws_connect_async(is_shutdown_clone_public,
-                                   fun,
-                                   &write_tx_am_public,
-                                   write_rx_public).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-    });
-    let trade_symbols = symbols.clone();
-    // 交易交易所需要启动私有ws
-    if is_trade {
-        let (write_tx_private, write_rx_private) = futures_channel::mpsc::unbounded();
-        let auth = Some(parse_btree_map_to_bybit_swap_login(exchange_params));
-
-        let mut ws_private = BybitSwapWs::new_label(name.clone(), is_colo, auth, BybitSwapWsType::Private);
-        ws_private.set_symbols(trade_symbols);
-        ws_private.set_subscribe(vec![
-            BybitSwapSubscribeType::PrPosition,
-            BybitSwapSubscribeType::PrOrder,
-            BybitSwapSubscribeType::PrWallet
-        ]);
-
-        // 挂起私有ws
-        let write_tx_am_private = Arc::new(Mutex::new(write_tx_private));
-        let is_shutdown_clone_private = Arc::clone(&is_shutdown_arc);
-        let core_arc_clone_private = core_arc.clone();
-        spawn(async move {
-            let ct_val = core_arc_clone_private.lock().await.platform_rest.get_self_market().ct_val;
-            let run_symbol = symbols.clone()[0].clone();
-
-            let fun = move |data: ResponseData| {
-                let core_arc_clone = core_arc_clone_private.clone();
-                let run_symbol_clone = run_symbol.clone();
-
-                async move {
-                    on_private_data(core_arc_clone.clone(), &ct_val, &run_symbol_clone, data).await;
-                }
-            };
-
-            ws_private.ws_connect_async(is_shutdown_clone_private,
-                                        fun,
-                                        &write_tx_am_private,
-                                        write_rx_private).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-        });
-    }
-}
-
-async fn on_private_data(core_arc_clone: Arc<Mutex<Core>>, ct_val: &Decimal, run_symbol: &String, response: ResponseData) {
-    let mut trace_stack = TraceStack::new(response.time, response.ins);
-    trace_stack.on_after_span_line();
-
-    match response.channel.as_str() {
-        "wallet" => {
-            let account = standard::handle_info::HandleSwapInfo::handle_account_info(BybitSwap, &response, run_symbol);
-            let mut core = core_arc_clone.lock().await;
-            core.update_equity(account).await;
-        }
-        "order" => {
-            let orders = standard::handle_info::HandleSwapInfo::handle_order(BybitSwap, response.clone(), ct_val.clone());
-            trace_stack.on_after_format();
-
-            let mut order_infos:Vec<OrderInfo> = Vec::new();
-            for mut order in orders.order {
-                if order.status == "NULL" {
-                    error!("bybit_usdt_swap 未识别的订单状态:{:?}", response);
-
-                    continue;
-                }
-
-                if order.deal_amount != Decimal::ZERO {
-                    info!("bybit order 消息原文:{:?}", response);
-                }
-
-                let order_info = OrderInfo::parse_order_to_order_info(&mut order);
-                order_infos.push(order_info);
-            }
-
-            let mut core = core_arc_clone.lock().await;
-            core.update_order(order_infos, trace_stack).await;
-        }
-        "position" => {
-            let positions = standard::handle_info::HandleSwapInfo::handle_position(BybitSwap, &response, ct_val);
-            let mut core = core_arc_clone.lock().await;
-            core.update_position(positions).await;
-        }
-        _ => {
-            error!("未知推送类型");
-            error!(?response);
-        }
-    }
-}
-
-async fn on_public_data(core_arc_clone: Arc<Mutex<Core>>, update_flag_u: &mut Decimal, response: ResponseData) {
-    if response.code != 200 {
-        return;
-    }
-
-    let mut trace_stack = TraceStack::new(response.time, response.ins);
-    trace_stack.on_after_span_line();
-
-    match response.channel.as_str() {
-        "tickers" => {
-            trace_stack.set_source("bybit_usdt_swap.tickers".to_string());
-
-            // 处理ticker信息
-            let special_depth = standard::handle_info::HandleSwapInfo::handle_book_ticker(BybitSwap, &response).await;
-            trace_stack.on_after_format();
-
-            on_special_depth(core_arc_clone, update_flag_u, &response.label, &mut trace_stack, &special_depth).await;
-        }
-        "orderbook" => {
-            // let mut is_update = false;
-            // let data_type = data.data_type.clone();
-            // let label = data.label.clone();
-            // if data_type == "delta"  {
-            //     is_update = true;
-            // }
-            // let mut depth_format: DepthParam = format_depth(BybitSwap, &data);
-            // // 是增量更新
-            // if is_update {
-            //     update_order_book(depth_asks, depth_bids, depth_format.depth_asks, depth_format.depth_bids);
-            // } else { // 全量
-            //     depth_asks.clear();
-            //     depth_asks.append(&mut depth_format.depth_asks);
-            //     depth_bids.clear();
-            //     depth_bids.append(&mut depth_format.depth_bids);
-            // }
-            // let depth = make_special_depth(label.clone(), depth_asks, depth_bids, depth_format.t, depth_format.create_at);
-            // trace_stack.on_before_network(depth_format.create_at.clone());
-            // trace_stack.on_after_format();
-            //
-            // on_special_depth(core_arc_clone, update_flag_u, &label, &mut trace_stack, &depth).await;
-        }
-        "trade" => {
-            // let mut core = core_arc_clone.lock().await;
-            // let str = data.label.clone();
-            // if core.is_update.contains_key(&data.label) && *core.is_update.get(str.as_str()).unwrap(){
-            //     *max_buy = Decimal::ZERO;
-            //     *min_sell = Decimal::ZERO;
-            //     core.is_update.remove(str.as_str());
-            // }
-            // let trades: Vec<OriginalTradeBy> = serde_json::from_str(data.data.as_str()).unwrap();
-            // for trade in trades {
-            //     if trade.p > *max_buy || *max_buy == Decimal::ZERO{
-            //         *max_buy = trade.p
-            //     }
-            //     if trade.p < *min_sell || *min_sell == Decimal::ZERO{
-            //         *min_sell = trade.p
-            //     }
-            // }
-            // core.max_buy_min_sell_cache.insert(data.label, vec![*max_buy, *min_sell]);
-        }
-        _ => {}
-    }
-}
-
-fn parse_btree_map_to_bybit_swap_login(exchange_params: BTreeMap<String, String>) -> BybitSwapLogin {
-    BybitSwapLogin {
-        api_key: exchange_params.get("access_key").unwrap().clone(),
-        secret_key: exchange_params.get("secret_key").unwrap().clone(),
-    }
-}
-
-// fn update_order_book(depth_asks: &mut Vec<MarketOrder>, depth_bids: &mut Vec<MarketOrder>, asks : Vec<MarketOrder>, bids: Vec<MarketOrder>) {
-//     for i in asks {
-//         let index_of_value = depth_asks.iter().position(|x| x.price == i.price);
-//         match index_of_value {
-//             Some(index) => {
-//                 if i.amount == Decimal::ZERO {
-//                     depth_asks.remove(index);
-//                 } else {
-//                     depth_asks[index].amount = i.amount.clone();
-//                 }
-//             },
-//             None => {
-//                 depth_asks.push(i.clone());
-//             },
-//         }
-//     }
-//     for i in bids {
-//         let index_of_value = depth_bids.iter().position(|x| x.price == i.price);
-//         match index_of_value {
-//             Some(index) => {
-//                 if i.amount == Decimal::ZERO {
-//                     depth_bids.remove(index);
-//                 } else {
-//                     depth_bids[index].amount = i.amount.clone();
-//                 }
-//             },
-//             None => {
-//                 depth_bids.push(i.clone());
-//             },
-//         }
-//     }
-//     depth_asks.sort_by(|a, b| a.price.partial_cmp(&b.price).unwrap_or(Ordering::Equal));
-//     depth_bids.sort_by(|a, b| b.price.partial_cmp(&a.price).unwrap_or(Ordering::Equal));
-//
-//     // 限制总长度100
-//     depth_asks.truncate(100);
-//     depth_bids.truncate(100);
-// }

+ 2 - 56
strategy/src/clear_core.rs

@@ -18,10 +18,9 @@ use global::params::Params;
 use global::trace_stack::TraceStack;
 use global::trace_stack::TraceStack;
 use standard::{Account, Market, Order, Platform, Position, PositionModeEnum, SpecialTicker};
 use standard::{Account, Market, Order, Platform, Position, PositionModeEnum, SpecialTicker};
 use standard::exchange::{Exchange};
 use standard::exchange::{Exchange};
-use standard::exchange::ExchangeEnum::{BinanceSwap, BitgetSwap, BybitSwap, CoinexSwap, GateSwap, HtxSwap, KucoinSwap};
+use standard::exchange::ExchangeEnum::GateSwap;
 
 
 use crate::model::{LocalPosition, OrderInfo};
 use crate::model::{LocalPosition, OrderInfo};
-use crate::predictor::Predictor;
 use crate::strategy::Strategy;
 use crate::strategy::Strategy;
 use crate::utils;
 use crate::utils;
 use crate::utils::clip;
 use crate::utils::clip;
@@ -89,7 +88,6 @@ pub struct ClearCore {
     pub ref_name: Vec<String>,
     pub ref_name: Vec<String>,
     pub trade_name: String,
     pub trade_name: String,
     pub ready: i8,
     pub ready: i8,
-    pub predictor: Predictor,
     pub market: Market,
     pub market: Market,
     pub platform_rest: Box<dyn Platform + Send + Sync>,
     pub platform_rest: Box<dyn Platform + Send + Sync>,
     // 市场最优买卖价
     // 市场最优买卖价
@@ -173,17 +171,6 @@ impl ClearCore {
             ref_name: Default::default(),
             ref_name: Default::default(),
             trade_name: "".to_string(),
             trade_name: "".to_string(),
             ready: 0,
             ready: 0,
-            predictor: Predictor {
-                loop_count: 0,
-                market_info_list: vec![],
-                mid_price_list: vec![],
-                ref_mid_price_per_exchange_per_frame: vec![],
-                ref_exchange_length: 0,
-                data_length_max: 0,
-                alpha: vec![],
-                gamma: Default::default(),
-                avg_spread_list: vec![],
-            },
             market: Market {
             market: Market {
                 symbol: symbol.clone(),
                 symbol: symbol.clone(),
                 base_asset: "".to_string(),
                 base_asset: "".to_string(),
@@ -199,39 +186,9 @@ impl ClearCore {
                 amount_size: Default::default(),
                 amount_size: Default::default(),
             },
             },
             platform_rest: match exchange.as_str() {
             platform_rest: match exchange.as_str() {
-                "kucoin_usdt_swap" => {
-                    Exchange::new(KucoinSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
                 "gate_usdt_swap" => {
                 "gate_usdt_swap" => {
                     Exchange::new(GateSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
                     Exchange::new(GateSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
                 }
                 }
-                // "gate_usdt_spot" => {
-                //     Exchange::new(GateSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                // }
-                "binance_usdt_swap" => {
-                    Exchange::new(BinanceSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
-                // "binance_spot" => {
-                //     Exchange::new(BinanceSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                // }
-                // "bitget_spot" => {
-                //     Exchange::new(BitgetSpot, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                // }
-                "bitget_usdt_swap" => {
-                    Exchange::new(BitgetSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
-                // "okex_usdt_swap" => {
-                //     Exchange::new(OkxSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                // }
-                "bybit_usdt_swap" => {
-                    Exchange::new(BybitSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
-                "coinex_usdt_swap" => {
-                    Exchange::new(CoinexSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
-                "htx_usdt_swap" => {
-                    Exchange::new(HtxSwap, symbol, params.colo != 0i8, exchange_params, order_sender, error_sender).await
-                }
                 _ => {
                 _ => {
                     error!("203未找到对应的交易所rest枚举!");
                     error!("203未找到对应的交易所rest枚举!");
                     panic!("203未找到对应的交易所rest枚举!");
                     panic!("203未找到对应的交易所rest枚举!");
@@ -288,11 +245,8 @@ impl ClearCore {
             }
             }
         }
         }
         info!("价格系数:{:?}", price_alpha);
         info!("价格系数:{:?}", price_alpha);
-        core_obj.predictor = Predictor::new(core_obj.ref_name.len())
-            .alpha(price_alpha)
-            .gamma(params.gamma);
 
 
-        return core_obj;
+        core_obj
     }
     }
 
 
     pub fn log_ready_status(&mut self, msg: String) {
     pub fn log_ready_status(&mut self, msg: String) {
@@ -305,7 +259,6 @@ impl ClearCore {
     }
     }
 
 
 
 
-    // #[instrument(skip(self, data), level="TRACE")]
     pub async fn update_position(&mut self, data: Vec<Position>) {
     pub async fn update_position(&mut self, data: Vec<Position>) {
         if data.is_empty() {
         if data.is_empty() {
             return;
             return;
@@ -349,13 +302,11 @@ impl ClearCore {
         }
         }
     }
     }
 
 
-    // #[instrument(skip(self), level="TRACE")]
     pub async fn get_exchange_info(&mut self) {
     pub async fn get_exchange_info(&mut self) {
         self.market = self.platform_rest.get_self_market();
         self.market = self.platform_rest.get_self_market();
         info!(?self.market);
         info!(?self.market);
     }
     }
 
 
-    // #[instrument(skip(self, data), level="TRACE")]
     pub async fn update_equity(&mut self, data: Account) {
     pub async fn update_equity(&mut self, data: Account) {
         /*
         /*
            更新保证金信息
            更新保证金信息
@@ -368,7 +319,6 @@ impl ClearCore {
         self.local_cash = data.balance * self.used_pct;
         self.local_cash = data.balance * self.used_pct;
     }
     }
 
 
-    // #[instrument(skip(self), level="TRACE")]
     pub async fn update_equity_rest_swap(&mut self) {
     pub async fn update_equity_rest_swap(&mut self) {
         match self.platform_rest.get_account().await {
         match self.platform_rest.get_account().await {
             Ok(account) => {
             Ok(account) => {
@@ -398,7 +348,6 @@ impl ClearCore {
         }
         }
     }
     }
 
 
-    // #[instrument(skip(self), level="TRACE")]
     pub async fn update_equity_rest_spot(&mut self) {
     pub async fn update_equity_rest_spot(&mut self) {
         match self.platform_rest.get_spot_account().await {
         match self.platform_rest.get_spot_account().await {
             Ok(mut val) => {
             Ok(mut val) => {
@@ -426,7 +375,6 @@ impl ClearCore {
         }
         }
     }
     }
 
 
-    // #[instrument(skip(self, target_hold_coin), level="TRACE")]
     pub async fn check_position(&mut self) -> ClearPositionResult {
     pub async fn check_position(&mut self) -> ClearPositionResult {
         let mut result = ClearPositionResult::new();
         let mut result = ClearPositionResult::new();
         info!("------------------------------------------------------------------------------------------------------------");
         info!("------------------------------------------------------------------------------------------------------------");
@@ -536,7 +484,6 @@ impl ClearCore {
     }
     }
 
 
 
 
-    // #[instrument(skip(self), level="TRACE")]
     pub async fn exit(&mut self, r_id: String) -> bool {
     pub async fn exit(&mut self, r_id: String) -> bool {
         let mut result = self.check_position().await;
         let mut result = self.check_position().await;
         // 设置机器人id
         // 设置机器人id
@@ -553,7 +500,6 @@ impl ClearCore {
         return true;
         return true;
     }
     }
 
 
-    // #[instrument(skip(self), level="TRACE")]
     pub async fn before_trade(&mut self) -> bool {
     pub async fn before_trade(&mut self) -> bool {
         sleep(Duration::from_secs(1)).await;
         sleep(Duration::from_secs(1)).await;
         // 获取市场信息
         // 获取市场信息

+ 0 - 270
strategy/src/coinex_usdt_swap.rs

@@ -1,270 +0,0 @@
-use tracing::{error};
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use rust_decimal::Decimal;
-use tokio::spawn;
-use tokio::sync::Mutex;
-use exchanges::coinex_swap_ws::{CoinexSwapLogin, CoinexSwapSubscribeType, CoinexSwapWs};
-use exchanges::response_base::ResponseData;
-use global::trace_stack::{TraceStack};
-use standard::exchange::ExchangeEnum::{CoinexSwap};
-use crate::model::{OrderInfo};
-use crate::core::Core;
-use crate::exchange_disguise::on_special_depth;
-
-// 1交易、0参考 coinex 合约 启动
-pub async fn coinex_swap_run(is_shutdown_arc: Arc<AtomicBool>,
-                           is_trade: bool,
-                           core_arc: Arc<Mutex<Core>>,
-                           name: String,
-                           symbols: Vec<String>,
-                           _is_colo: bool,
-                           exchange_params: BTreeMap<String, String>) {
-    let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-
-    let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let symbols_clone = symbols.clone();
-    spawn(async move {
-        let mut ws;
-        // 交易
-        if is_trade {
-            let login_param = parse_btree_map_to_coinex_swap_login(exchange_params);
-            ws = CoinexSwapWs::new_label(name.clone(), Some(login_param));
-            ws.set_subscribe(vec![
-                // CoinexSwapSubscribeType::PuFuturesDeals,
-                CoinexSwapSubscribeType::PuFuturesDepth,
-
-                CoinexSwapSubscribeType::PrFuturesOrders,
-                CoinexSwapSubscribeType::PrFuturesPositions,
-                CoinexSwapSubscribeType::PrFuturesBalances,
-            ]);
-        } else { // 参考
-            ws = CoinexSwapWs::new_label(name.clone(), None);
-            ws.set_subscribe(vec![
-                // CoinexSwapSubscribeType::PuFuturesDeals,
-                CoinexSwapSubscribeType::PuFuturesDepth
-            ]);
-        }
-
-        // 读取数据
-        let mut update_flag_u = Decimal::ZERO;
-        let core_arc_clone = Arc::clone(&core_arc);
-        let multiplier = core_arc_clone.lock().await.platform_rest.get_self_market().ct_val;
-        let run_symbol = symbols.clone()[0].clone();
-
-        let fun = move |data: ResponseData| {
-            let core_arc_cc = core_arc_clone.clone();
-            // 在 async 块之前克隆 Arc
-            let mul = multiplier.clone();
-            let rs = run_symbol.clone();
-
-            async move {
-                on_data(core_arc_cc,
-                        &mut update_flag_u,
-                        &mul,
-                        &rs,
-                        data,
-                ).await
-            }
-        };
-
-        // 建立链接
-        ws.set_symbols(symbols_clone);
-        ws.ws_connect_async(is_shutdown_arc, fun, &write_tx_am, write_rx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
-    });
-}
-
-async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
-                 update_flag_u: &mut Decimal,
-                 multiplier: &Decimal,
-                 run_symbol: &String,
-                 response: ResponseData) {
-    let mut trace_stack = TraceStack::new(response.time, response.ins);
-    trace_stack.on_after_span_line();
-
-    match response.channel.as_str() {
-        "depth.update" => {
-            trace_stack.set_source("coinex_usdt_swap.order_book".to_string());
-            let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(CoinexSwap, &response);
-            trace_stack.on_after_format();
-
-            on_special_depth(core_arc_clone, update_flag_u, &response.label, &mut trace_stack, &special_depth).await;
-        }
-        "balance.update" => {
-            let account = standard::handle_info::HandleSwapInfo::handle_account_info(CoinexSwap, &response, run_symbol);
-            let mut core = core_arc_clone.lock().await;
-            core.update_equity(account).await;
-        }
-        "order.update" => {
-            trace_stack.set_source("coinex_swap.orders".to_string());
-            let orders = standard::handle_info::HandleSwapInfo::handle_order(CoinexSwap, response.clone(), multiplier.clone());
-            let mut order_infos:Vec<OrderInfo> = Vec::new();
-            for mut order in orders.order {
-                if order.status == "NULL" {
-                    error!("coinex_usdt_swap 未识别的订单状态:{:?}", response);
-                    continue;
-                }
-
-                let order_info = OrderInfo::parse_order_to_order_info(&mut order);
-                order_infos.push(order_info);
-            }
-
-            if order_infos.is_empty() {
-                error!("coinex_usdt_swap 未识别的订单 格式化失败:{:?}", response);
-                return
-            }
-            let mut new_order = order_infos[0].clone();
-            let mut core = core_arc_clone.lock().await;
-            // 本地订单缓存判断
-            if !core.local_orders_backup.contains_key(&new_order.client_id) {
-                return
-            }
-
-            // 获取订单目的
-            let mut rst = vec![];
-            let side = core.local_orders_backup.get(&new_order.client_id).unwrap().side.as_str();
-            let local_position_by_orders = &core.local_position_by_orders;
-            let long_pos = local_position_by_orders.long_pos;
-            let short_pos = local_position_by_orders.short_pos;
-
-            // 部分成交和新订单的处理,不用走下面的逻辑
-            if new_order.status != "REMOVE" || new_order.filled == Decimal::ZERO {
-                core.update_order(order_infos, trace_stack).await;
-                return
-            }
-
-            // 单向持仓的处理
-            match side {
-                "kd" => {
-                    if short_pos != Decimal::ZERO {
-                        let vir_order_filled;
-                        if short_pos >= new_order.amount {
-                            vir_order_filled = new_order.amount;
-                        } else {
-                            vir_order_filled = short_pos
-                        }
-                        // 构造虚拟订单
-                        let vir_client_id = format!("{}vir", new_order.client_id.clone());
-                        let vir_order = OrderInfo {
-                            symbol: "".to_string(),
-                            amount: vir_order_filled,
-                            side: "pk".to_string(),
-                            price: new_order.price,
-                            client_id: vir_client_id.clone(),
-                            filled_price: new_order.price,
-                            filled: vir_order_filled,
-                            order_id: "".to_string(),
-                            local_time: 0,
-                            create_time: 0,
-                            status: new_order.status.clone(),
-                            fee: Default::default(),
-                            trace_stack: trace_stack.clone(),
-                        };
-                        core.local_orders_backup.insert(vir_client_id.clone(), vir_order.clone());
-
-                        // 原始订单处理
-                        new_order.amount -= vir_order_filled;
-                        new_order.filled -= vir_order_filled;
-
-                        rst.push(vir_order.clone());
-                        if new_order.amount > Decimal::ZERO {
-                            rst.push(new_order.clone());
-                        } else {
-                            core.local_cancel_log.remove(&new_order.client_id);
-                            core.local_orders_backup.remove(&new_order.client_id);
-                            core.local_orders.remove(&new_order.client_id);
-                        }
-                    } else {
-                        rst.push(new_order.clone());
-                    }
-                }
-                "kk" => {
-                    if long_pos != Decimal::ZERO {
-                        let vir_order_filled;
-                        if long_pos >= new_order.amount {
-                            vir_order_filled = new_order.amount;
-                        } else {
-                            vir_order_filled = long_pos
-                        }
-                        // 构造虚拟订单
-                        let vir_client_id = format!("{}vir", new_order.client_id.clone());
-                        let vir_order = OrderInfo {
-                            symbol: "".to_string(),
-                            amount: vir_order_filled,
-                            side: "pd".to_string(),
-                            price: new_order.price,
-                            client_id: vir_client_id.clone(),
-                            filled_price: new_order.price,
-                            filled: vir_order_filled,
-                            order_id: "".to_string(),
-                            local_time: 0,
-                            create_time: 0,
-                            status: new_order.status.clone(),
-                            fee: Default::default(),
-                            trace_stack: trace_stack.clone(),
-                        };
-                        core.local_orders_backup.insert(vir_client_id.clone(), vir_order.clone());
-
-                        // 原始订单处理
-                        new_order.amount -= vir_order_filled;
-                        new_order.filled -= vir_order_filled;
-
-                        rst.push(vir_order.clone());
-                        if new_order.amount > Decimal::ZERO {
-                            rst.push(new_order.clone());
-                        } else {
-                            core.local_cancel_log.remove(&new_order.client_id);
-                            core.local_orders_backup.remove(&new_order.client_id);
-                            core.local_orders.remove(&new_order.client_id);
-                        }
-                    } else {
-                        rst.push(new_order.clone());
-                    }
-                }
-                _ => {
-                    rst = order_infos;
-                }
-            }
-
-            core.update_order(rst, trace_stack).await;
-        }
-        "position.update" => {
-            // info!("coinex_usdt_swap 仓位推送:{:?}", response.data);
-            let positions = standard::handle_info::HandleSwapInfo::handle_position(CoinexSwap, &response, multiplier);
-            let mut core = core_arc_clone.lock().await;
-
-            core.update_position(positions).await;
-        }
-        "deals.update" => {
-            // let mut core = core_arc_clone.lock().await;
-            // let str = data.label.clone();
-            // if core.is_update.contains_key(&data.label) && *core.is_update.get(str.as_str()).unwrap(){
-            //     *max_buy = Decimal::ZERO;
-            //     *min_sell = Decimal::ZERO;
-            //     core.is_update.remove(str.as_str());
-            // }
-            // let trades: Vec<OriginalTradeGa> = serde_json::from_str(data.data.as_str()).unwrap();
-            // for trade in trades {
-            //     if trade.price > *max_buy || *max_buy == Decimal::ZERO{
-            //         *max_buy = trade.price
-            //     }
-            //     if trade.price < *min_sell || *min_sell == Decimal::ZERO{
-            //         *min_sell = trade.price
-            //     }
-            // }
-            // core.max_buy_min_sell_cache.insert(data.label, vec![*max_buy, *min_sell]);
-        }
-        _ => {
-            error!("未知推送类型");
-            error!(?response);
-        }
-    }
-}
-
-fn parse_btree_map_to_coinex_swap_login(exchange_params: BTreeMap<String, String>) -> CoinexSwapLogin {
-    CoinexSwapLogin {
-        api_key: exchange_params.get("access_key").unwrap().clone(),
-        secret: exchange_params.get("secret_key").unwrap().clone()
-    }
-}

Some files were not shown because too many files changed in this diff