JiahengHe hai 11 meses
pai
achega
02ddd7a12f

+ 3 - 4
Cargo.toml

@@ -15,7 +15,6 @@ actix-web = "4.0.0-beta.12"
 ctrlc = "3.2.5"
 serde_json = "1.0.105"
 rust_decimal = { version = "1.32.0", features = ["maths"] }
-rust_decimal_macros = "1.32.0"
 rand = "0.8.5"
 futures-channel = "0.3.29"
 serde_derive = "1.0.190"
@@ -36,6 +35,6 @@ tracing-subscriber = { version = "0.3.17", features = [
     "local-time"
 ] }
 
-[workspace]
-members=[
-]
+#[workspace]
+#members=[
+#]

+ 0 - 65
src/account_info.rs

@@ -1,65 +0,0 @@
-use std::fs::File;
-use std::io::Read;
-use serde_derive::Deserialize;
-use toml::from_str;
-use tracing::{error};
-
-#[derive(Debug, Deserialize, Clone)]
-pub struct AccountInfo {
-    pub gate_access_key: String,
-    pub gate_secret_key: String,
-    pub binance_access_key: String,
-    pub binance_secret_key: String,
-    pub kucoin_access_key: String,
-    pub kucoin_secret_key: String,
-    pub kucoin_pass: String,
-    pub okx_access_key: String,
-    pub okx_secret_key: String,
-    pub okx_pass: String,
-    pub bitget_access_key: String,
-    pub bitget_secret_key: String,
-    pub bitget_pass: String,
-    pub htx_access_key: String,
-    pub htx_secret_key: String,
-    pub htx_pass: String,
-}
-
-impl AccountInfo {
-    pub fn new() -> AccountInfo {
-        AccountInfo {
-            gate_access_key: "".to_string(),
-            gate_secret_key: "".to_string(),
-            binance_access_key: "".to_string(),
-            binance_secret_key: "".to_string(),
-            kucoin_access_key: "".to_string(),
-            kucoin_secret_key: "".to_string(),
-            kucoin_pass: "".to_string(),
-            okx_access_key: "".to_string(),
-            okx_secret_key: "".to_string(),
-            okx_pass: "".to_string(),
-            bitget_access_key: "".to_string(),
-            bitget_secret_key: "".to_string(),
-            bitget_pass: "".to_string(),
-            htx_access_key: "".to_string(),
-            htx_secret_key: "".to_string(),
-            htx_pass: "".to_string(),
-        }
-    }
-}
-
-// 获取文件内容
-pub fn get_account_info(file_path: &str) -> AccountInfo {
-    let file = File::open(file_path);
-    let mut contents = String::new();
-    let result = match file {
-        Ok(mut value) => {
-            value.read_to_string(&mut contents).unwrap_or_default();
-            from_str(&contents).unwrap_or(AccountInfo::new())
-        }
-        Err(_) => {
-            error!("没有获取到账号配置文件!");
-            AccountInfo::new()
-        }
-    };
-    result
-}

+ 5 - 5
src/clear_core.rs

@@ -1,13 +1,13 @@
 use tokio::time::Instant;
 use std::collections::{BTreeMap, HashMap};
 use std::io::Error;
+use std::str::FromStr;
 use std::sync::Arc;
 use std::sync::atomic::AtomicBool;
 use std::time::Duration;
 use chrono::Utc;
 use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
 use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
 use tokio::sync::mpsc::Sender;
 use tokio::sync::Mutex;
 use tokio::time::sleep;
@@ -154,7 +154,7 @@ impl ClearCore {
             exit_msg: "正常退出".to_string(),
             position_check_series: Default::default(),
             stop_loss: params.stop_loss,
-            used_pct: dec!(0.95),
+            used_pct: Decimal::from_str("0.95").unwrap(),
             mode_signal: 0,
             trade_order_update_time: Utc::now().timestamp_millis(),
             on_tick_event_time: Utc::now().timestamp_millis(),
@@ -224,11 +224,11 @@ impl ClearCore {
         let mut price_alpha: Vec<Decimal> = Vec::new();
         for ref_pair_str in params.ref_pair {
             if params.pair.contains("1000") && !ref_pair_str.contains("1000") {
-                price_alpha.push(dec!(1000.0));
+                price_alpha.push(Decimal::from_str("1000.0").unwrap());
             } else if !params.pair.contains("1000") && ref_pair_str.contains("1000") {
-                price_alpha.push(dec!(0.001))
+                price_alpha.push(Decimal::from_str("0.001").unwrap())
             } else {
-                price_alpha.push(dec!(1.0));
+                price_alpha.push(Decimal::from_str("1.0").unwrap());
             }
         }
         info!("价格系数:{:?}", price_alpha);

+ 11 - 12
src/core.rs

@@ -9,7 +9,6 @@ use std::time::Duration;
 use chrono::Utc;
 use rust_decimal::{Decimal, MathematicalOps};
 use rust_decimal::prelude::ToPrimitive;
-use rust_decimal_macros::dec;
 use tokio::spawn;
 use tokio::sync::mpsc::Sender;
 use tokio::sync::Mutex;
@@ -160,7 +159,7 @@ impl Core {
             exit_msg: "正常退出".to_string(),
             position_check_series: Default::default(),
             stop_loss: params.stop_loss,
-            used_pct: dec!(0.95),
+            used_pct: Decimal::from_str("0.95").unwrap(),
             mode_signal: 0,
             trade_order_update_time: Utc::now().timestamp_millis(),
             on_tick_event_time: Utc::now().timestamp_millis(),
@@ -490,7 +489,7 @@ impl Core {
     pub fn check_ready(&mut self) {
         // 检查 ticker 行情
         if self.tickers.contains_key(&self.trade_name) {
-            if self.tickers.get(&self.trade_name).unwrap().buy == dec!(0) || self.tickers.get(&self.trade_name).unwrap().sell == dec!(0) {
+            if self.tickers.get(&self.trade_name).unwrap().buy == Decimal::ZERO || self.tickers.get(&self.trade_name).unwrap().sell == Decimal::ZERO {
                 self.log_ready_status(format!("540交易盘口ticker未准备好: {:?}", self.tickers));
                 return;
             }
@@ -527,11 +526,11 @@ impl Core {
         let now_time = Utc::now().timestamp_millis();
         if self.market_update_time.contains_key(name_ref) && *self.market_update_time.get(name_ref).unwrap() != 0i64 {
             let interval = Decimal::from(now_time - self.market_update_time.get(name_ref).unwrap());
-            if *self.market_update_interval.get(name_ref).unwrap() == dec!(0) {
+            if *self.market_update_interval.get(name_ref).unwrap() == Decimal::ZERO {
                 self.market_update_interval.insert(name_ref.clone(), interval);
             } else {
                 let value = self.market_update_interval.get(name_ref).unwrap();
-                self.market_update_interval.insert(name_ref.clone(), value * dec!(0.999) + interval * dec!(0.001));
+                self.market_update_interval.insert(name_ref.clone(), value * Decimal::from_str("0.999").unwrap() + interval * Decimal::from_str("0.001").unwrap());
             }
         }
         self.market_update_time.insert(name_ref.clone(), now_time);
@@ -557,7 +556,7 @@ impl Core {
         let mut flag = 0;
         let bid_price_rate = (depth[BID_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[BID_PRICE_INDEX]).abs() / depth[BID_PRICE_INDEX];
         let ask_price_rate = (depth[ASK_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[ASK_PRICE_INDEX]).abs() / depth[ASK_PRICE_INDEX];
-        let rate = dec!(0.0002);
+        let rate = Decimal::from_str("0.0002").unwrap();
         if bid_price_rate > rate || ask_price_rate > rate || Utc::now().timestamp_millis() - self.on_tick_event_time > 50 {
             // 允许交易
             flag = 1;
@@ -976,7 +975,7 @@ impl Core {
             self.stop().await;
         }
         // 报单延迟风控,平均延迟允许上限5000ms
-        if self.ready == 1 && self.platform_rest.get_request_avg_delay() > dec!(5000) {
+        if self.ready == 1 && self.platform_rest.get_request_avg_delay() > Decimal::from_str("5000").unwrap() {
             let exit_msg = format!("{} 延迟爆表 触发风控 准备停机。", self.params.account_name);
             warn!(exit_msg);
             self.exit_msg = exit_msg;
@@ -1050,7 +1049,7 @@ impl Core {
         // 持仓均价异常风控(浮盈风控)
         if self.strategy.long_pos_bias != Decimal::ZERO {
             if self.strategy.long_hold_value > Decimal::TWO * self.strategy._min_amount_value {
-                if self.strategy.long_pos_bias > dec!(4) || self.strategy.long_pos_bias < -Decimal::TWO {
+                if self.strategy.long_pos_bias > Decimal::TWO*Decimal::TWO || self.strategy.long_pos_bias < -Decimal::TWO {
                     let exit_msg = format!("{} long_pos_bias: {},持仓均价异常(mp: {}, avg: {}),退出。", self.params.account_name, self.strategy.long_pos_bias, self.strategy.mp, self.strategy.pos.long_avg);
                     warn!(exit_msg);
                     self.exit_msg = exit_msg;
@@ -1060,7 +1059,7 @@ impl Core {
         }
         if self.strategy.short_pos_bias != Decimal::ZERO {
             if self.strategy.short_hold_value > Decimal::TWO * self.strategy._min_amount_value {
-                if self.strategy.short_pos_bias > dec!(4) || self.strategy.short_pos_bias < -Decimal::TWO {
+                if self.strategy.short_pos_bias > Decimal::TWO*Decimal::TWO || self.strategy.short_pos_bias < -Decimal::TWO {
                     let exit_msg = format!("{} short_pos_bias: {},持仓均价异常(mp: {}, avg: {}),退出。", self.params.account_name, self.strategy.short_pos_bias, self.strategy.mp, self.strategy.pos.short_avg);
                     warn!(exit_msg);
                     self.exit_msg = exit_msg;
@@ -1081,7 +1080,7 @@ impl Core {
         }
 
         // 定价异常风控
-        if self.ready == 1 && (self.strategy.ref_price - self.strategy.mp).abs() / self.strategy.mp > dec!(0.03) {
+        if self.ready == 1 && (self.strategy.ref_price - self.strategy.mp).abs() / self.strategy.mp > Decimal::from_str("0.03").unwrap() {
             let exit_msg = format!("{} 定价偏离过大,怀疑定价异常,退出。", self.params.account_name);
             warn!(exit_msg);
             warn!(?self.strategy.ref_price, ?self.strategy.mp);
@@ -1577,8 +1576,8 @@ pub fn on_timer(core_arc: Arc<Mutex<Core>>) -> JoinHandle<()> {
                 // 计算预估成交额
                 let total_trade_value = core.local_buy_value + core.local_sell_value;
                 let time_diff = Decimal::from(Utc::now().timestamp_millis() - core.start_time);
-                let trade_vol_24h = (total_trade_value / time_diff) * dec!(86400);
-                core.strategy.trade_vol_24h_w = trade_vol_24h / dec!(10000);
+                let trade_vol_24h = (total_trade_value / time_diff) * Decimal::from_str("86400").unwrap();
+                core.strategy.trade_vol_24h_w = trade_vol_24h / Decimal::from_str("10000").unwrap();
                 core.strategy.trade_vol_24h_w.rescale(2);
             }
         }

+ 4 - 8
src/core_libs.rs

@@ -12,7 +12,8 @@ use tracing::{error, info};
 use crate::cci::CentralControlInfo;
 use crate::params::Params;
 use crate::model::{Order, OrderInfo};
-use crate::{core, exchange_disguise};
+use crate::core;
+use crate::gate_usdt_swap::gate_swap_run;
 use crate::trace_stack::TraceStack;
 
 pub async fn init(params: Params,
@@ -41,13 +42,8 @@ pub async fn init(params: Params,
     let core_arc = Arc::new(Mutex::new(core_obj));
 
     // 交易交易所
-    exchange_disguise::run_transactional_exchange(ws_running.clone(),
-                                                  params.exchange,
-                                                  core_arc.clone(),
-                                                  trade_name,
-                                                  vec![params.pair.clone()],
-                                                  params.colo != 0i8,
-                                                  exchange_params.clone()).await;
+    gate_swap_run(ws_running.clone(), core_arc.clone(), trade_name, vec![params.pair.clone()], params.colo != 0i8, exchange_params.clone()).await;
+
     // 启动定期触发的系统逻辑
     core::on_timer(core_arc.clone());
     // 启动策略逻辑

+ 0 - 68
src/exchange.rs

@@ -1,68 +0,0 @@
-use std::collections::{BTreeMap};
-use std::io::Error;
-use tokio::sync::mpsc::Sender;
-use crate::gate_swap::GateSwap;
-use crate::model::Order;
-
-/// 交易所交易模式枚举
-/// - `BinanceSwap`: Binance交易所期货;
-/// - `BinanceSpot`: Binance交易所现货;
-/// - `GateSwap`: Gate交易所期货;
-/// - `GateSpot`: Gate交易所现货;
-/// - `KucoinSwap`: kucoin交易所期货;
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum ExchangeEnum {
-    GateSwapEnum
-}
-
-/// Exchange结构体
-///
-/// 方法:
-/// - 创建Exchange:
-///
-/// new(platform: [ExchangeEnum], symbol: `String`, is_colo: `bool`, params: `BTreeMap<String, String>`, order_sender: `Sender<Order>`, error_sender: `Sender<Error>`) -> `Box<dyn Platform + Send + Sync>`
-/// - `platform(`[ExchangeEnum]`)`: 交易所平台枚举
-/// - `symbol(String)`: 币对
-/// - `is_colo(bool)`: 是否开始告诉模式
-/// - `params(BTreeMap<String, String>)`: 登录所需参数
-/// - `order_sender(Sender<Order>)`: 订单消息发送者
-/// - `error_sender(Sender<Error>)`: 错误消息发送者
-///
-/// 示例参数值:
-///
-/// | 交易所枚举 | params参数示例 BTreeMap<String, String> |
-/// | --- | --- |
-/// | BinanceSwap | {"access_key":"your_access_key","secret_key":"your_secret_key"} |
-/// | BinanceSpot | {"access_key":"your_access_key","secret_key":"your_secret_key"} |
-/// | GateSwap | {"access_key":"your_access_key","secret_key":"your_secret_key"} |
-/// | GateSpot | {"access_key":"your_access_key","secret_key":"your_secret_key"} |
-/// | KucoinSwap | {"access_key":"your_access_key","secret_key":"your_secret_key","pass_key":"your_pass_key"} |
-///  ```rust
-/// use std::collections::BTreeMap;
-/// use std::io::Error;
-/// use tokio::sync::mpsc;
-/// use as_rust::exchange::{Exchange, ExchangeEnum};
-/// use standard::Order;
-///
-/// let mut params:BTreeMap<String,String> = BTreeMap::new();
-/// params.insert("access_key".to_string(), "your_access_key".to_string());
-/// params.insert("secret_key".to_string(), "your_secret_key".to_string());
-/// let (order_sender, _order_receiver): (mpsc::Sender<Order>, mpsc::Receiver<Order>) = mpsc::channel(1024);
-/// let (error_sender, _error_receiver): (mpsc::Sender<Error>, mpsc::Receiver<Error>) = mpsc::channel(1024);
-///
-/// let exchange = Exchange::new(ExchangeEnum::GateSwap, "BTC_USDT".to_string(), false, params, order_sender, error_sender);
-#[derive(Debug, Clone)]
-pub struct 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>) -> GateSwap {
-        match exchange {
-            ExchangeEnum::GateSwapEnum => {
-                GateSwap::new(symbol, is_colo, params, order_sender, error_sender).await
-            }
-        }
-    }
-}
-
-
-

+ 0 - 55
src/exchange_disguise.rs

@@ -1,55 +0,0 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use rust_decimal::Decimal;
-use tokio::sync::Mutex;
-use crate::core::Core;
-use crate::gate_usdt_swap::gate_swap_run;
-use crate::model::SpecialDepth;
-use crate::trace_stack::TraceStack;
-
-// 交易交易所启动
-pub async fn run_transactional_exchange(is_shutdown_arc :Arc<AtomicBool>,
-                                        exchange_name: String,
-                                        core_arc: Arc<Mutex<Core>>,
-                                        name: String,
-                                        symbols: Vec<String>,
-                                        is_colo: bool,
-                                        exchange_params: BTreeMap<String, String>) {
-    match exchange_name.as_str() {
-        "gate_usdt_swap" => {
-            gate_swap_run(is_shutdown_arc, core_arc, name, symbols, is_colo, exchange_params).await;
-        }
-        _ => {
-            let msg = format!("不支持的交易交易所:{}", exchange_name);
-            panic!("{}", msg);
-        }
-    }
-}
-
-pub async fn on_special_depth(core_arc: Arc<Mutex<Core>>,
-                              update_flag_u: &mut Decimal,
-                              label: &String,
-                              trace_stack: &mut TraceStack,
-                              special_depth: &SpecialDepth) {
-    if special_depth.t > *update_flag_u {
-        let mut core = core_arc.lock().await;
-        trace_stack.on_after_unlock_core();
-
-        core.tickers.insert(label.clone(), special_depth.ticker.clone());
-        core.depths.insert(label.clone(), special_depth.depth.clone());
-
-        // 触发depth更新
-        core.on_depth_update(&(special_depth.depth), &label, trace_stack).await;
-
-        core.local_depths.insert(special_depth.name.clone(), special_depth.depth.clone());
-
-        *update_flag_u = special_depth.t;
-    }
-}
-
-pub async fn on_order() {}
-
-pub async fn on_position() {}
-
-pub async fn on_account() {}

+ 0 - 7
src/gate_swap.rs

@@ -10,7 +10,6 @@ use serde_json::{json, Value};
 use tokio::spawn;
 use tokio::time::Instant;
 use tracing::{error, info};
-use crate::exchange::ExchangeEnum;
 use crate::gate_swap_rest::GateSwapRest;
 use crate::model::{Account, Market, Order, OrderCommand, Position, PositionModeEnum, Ticker};
 use crate::trace_stack::TraceStack;
@@ -18,7 +17,6 @@ use crate::trace_stack::TraceStack;
 #[allow(dead_code)]
 #[derive(Clone)]
 pub struct GateSwap {
-    exchange: ExchangeEnum,
     symbol: String,
     is_colo: bool,
     params: BTreeMap<String, String>,
@@ -32,7 +30,6 @@ impl GateSwap {
     pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> GateSwap {
         let market = Market::new();
         let mut gate_swap = GateSwap {
-            exchange: ExchangeEnum::GateSwapEnum,
             symbol: symbol.to_uppercase(),
             is_colo,
             params: params.clone(),
@@ -61,10 +58,6 @@ impl GateSwap {
 
     // 克隆方法
     pub fn clone_box(&self) -> GateSwap { self.clone() }
-    // 获取交易所模式
-    pub fn get_self_exchange(&self) -> ExchangeEnum {
-        ExchangeEnum::GateSwapEnum
-    }
     // 获取交易对
     pub fn get_self_symbol(&self) -> String { self.symbol.clone() }
     // 获取是否使用高速通道

+ 104 - 3
src/gate_swap_handle.rs

@@ -1,14 +1,23 @@
+use std::cmp::Ordering;
 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 crate::public_params;
 use crate::model::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};
 use crate::response_base::ResponseData;
 use crate::trace_stack::TraceStack;
 
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct DepthParam {
+    pub depth_asks: Vec<MarketOrder>,
+    pub depth_bids: Vec<MarketOrder>,
+    pub t: Decimal,
+    pub create_at: i64
+}
+
 // 处理账号信息
 pub fn handle_account_info(res_data: &ResponseData, symbol: &String) -> Account {
     let res_data_json = res_data.data.as_array().unwrap();
@@ -125,7 +134,7 @@ pub fn handle_book_ticker(res_data: &ResponseData) -> SpecialDepth {
     let bq = Decimal::from_f64((*res_data).data["B"].as_f64().unwrap()).unwrap();
     let ap = Decimal::from_str((*res_data).data["a"].as_str().unwrap_or("0")).unwrap_or(Decimal::ZERO);
     let aq = Decimal::from_f64((*res_data).data["A"].as_f64().unwrap()).unwrap();
-    let mp = (bp + ap) * dec!(0.5);
+    let mp = (bp + ap) * Decimal::from_str("0.5").unwrap();
     let t = Decimal::from_u64((*res_data).data["u"].as_u64().unwrap()).unwrap();
     let create_at = (*res_data).data["t"].as_i64().unwrap() * 1000;
 
@@ -150,5 +159,97 @@ pub fn format_depth_items(value: &Value) -> Vec<MarketOrder> {
             amount: Decimal::from_f64(value["s"].as_f64().unwrap()).unwrap(),
         })
     }
-    return depth_items;
+    depth_items
+}
+
+// 处理深度信息
+pub fn handle_special_depth(res_data: &ResponseData) -> SpecialDepth {
+    let label = res_data.label.clone();
+    // 格式化
+    let mut format_depth = format_depth(res_data);
+    // 运算、组装
+    make_special_depth(label, &mut format_depth.depth_asks, &mut format_depth.depth_bids, format_depth.t, format_depth.create_at)
+}
+
+pub fn format_depth(res_data: &ResponseData) -> DepthParam {
+
+    let depth_asks: Vec<MarketOrder> = format_depth_items(&res_data.data["asks"]);
+    let depth_bids: Vec<MarketOrder> = format_depth_items(&res_data.data["bids"]);
+    // todo! 有id可以取 保证与py一致
+    let t: Decimal = Decimal::from_str(&res_data.data["t"].to_string()).unwrap();
+    let create_at: i64 = res_data.data["t"].as_i64().unwrap() * 1000;
+
+
+    DepthParam {
+        depth_asks,
+        depth_bids,
+        t,
+        create_at
+    }
+}
+
+pub fn make_special_depth(label: String, depth_asks: &mut Vec<MarketOrder>, depth_bids: &mut Vec<MarketOrder>, t: Decimal, create_at: i64) -> SpecialDepth {
+    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));
+    // TODO 不排序的话,有4us可以省下来。
+    let mp = (depth_asks[0].price + depth_bids[0].price) * Decimal::from_str("0.5").unwrap();
+    // 每1权重需要多少价格距离,0.001代表0.1%,每0.1%代表1权重 0.001
+    let step = (Decimal::new(1, 3) * mp / Decimal::from_usize(public_params::LEVEL).unwrap()).round_dp(mp.scale());
+    let mut ap = Vec::new();
+    let mut bp = Vec::new();
+    let mut av: Vec<Decimal> = Vec::new();
+    let mut bv: Vec<Decimal> = Vec::new();
+    for i in 0..public_params::LEVEL {
+        let price = (depth_asks[0].price + step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_asks[0].price.scale());
+        ap.push(price);
+    }
+    for i in 0..public_params::LEVEL {
+        let price = (depth_bids[0].price - step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_bids[0].price.scale());
+        bp.push(price);
+    }
+    let mut ap_price_tag = depth_asks[0].price + step;
+    let mut ap_index = 0;
+    for item in depth_asks.iter() {
+        let price = item.price;
+        let amount = item.amount;
+        if av.get(ap_index).is_none() { av.push(Decimal::ZERO) };
+        if price < ap_price_tag {
+            av[ap_index] += amount;
+        } else {
+            ap_price_tag += step;
+            ap_index += 1;
+            if ap_index == public_params::LEVEL {
+                break;
+            }
+            av[ap_index] += amount
+        }
+    }
+
+    let mut bp_price_tag = depth_bids[0].price - step;
+    let mut bp_index = 0;
+    for item in depth_bids.iter() {
+        let price = item.price;
+        let amount = item.amount;
+        if bv.get(bp_index).is_none() { bv.push(Decimal::ZERO) };
+        if price > bp_price_tag {
+            bv[bp_index] += amount;
+        } else {
+            bp_price_tag -= step;
+            bp_index += 1;
+            if bp_index == public_params::LEVEL {
+                break;
+            }
+            bv[bp_index] += amount
+        }
+    }
+
+    let ticker_info = SpecialTicker { sell: depth_asks[0].price, buy: depth_bids[0].price, mid_price: mp, t, create_at };
+    let depth_info = bp.iter().cloned().chain(bv.iter().cloned()).chain(ap.iter().cloned()).chain(av.iter().cloned()).collect();
+    SpecialDepth {
+        name: label,
+        depth: depth_info,
+        ticker: ticker_info,
+        t,
+        create_at,
+    }
 }

+ 1 - 2
src/gate_swap_rest.rs

@@ -6,7 +6,6 @@ use hmac::{Hmac, Mac, NewMac};
 use reqwest::Client;
 use rust_decimal::Decimal;
 use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
 use serde_json::Value;
 use sha2::Sha512;
 use tracing::{error, info};
@@ -56,7 +55,7 @@ impl GateSwapRest {
             login_param,
             delays: vec![],
             max_delay: 0,
-            avg_delay: dec!(0.0),
+            avg_delay: Decimal::ZERO,
         }
     }
 

+ 27 - 9
src/gate_usdt_swap.rs

@@ -7,11 +7,9 @@ use tokio::spawn;
 use tokio::sync::Mutex;
 
 use crate::core::Core;
-use crate::exchange::ExchangeEnum::GateSwapEnum;
-use crate::exchange_disguise::on_special_depth;
 use crate::gate_swap_rest::GateSwapRest;
 use crate::gate_swap_ws::{GateSwapLogin, GateSwapSubscribeType, GateSwapWs, GateSwapWsType};
-use crate::model::OrderInfo;
+use crate::model::{OrderInfo, SpecialDepth};
 use crate::response_base::ResponseData;
 use crate::trace_stack::TraceStack;
 
@@ -90,7 +88,7 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
     match response.channel.as_str() {
         "futures.order_book" => {
             trace_stack.set_source("gate_usdt_swap.order_book".to_string());
-            let special_depth = crate::handle_info::HandleSwapInfo::handle_special_depth(GateSwapEnum, &response);
+            let special_depth = crate::gate_swap_handle::handle_special_depth(&response);
             trace_stack.on_after_format();
 
             on_special_depth(core_arc_clone, update_flag_u, &response.label, &mut trace_stack, &special_depth).await;
@@ -98,7 +96,7 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
         "futures.book_ticker" => {
             trace_stack.set_source("gate_usdt_swap.book_ticker".to_string());
             // 将ticker数据转换为模拟深度
-            let special_depth = crate::handle_info::HandleSwapInfo::handle_book_ticker(GateSwapEnum, &response).await;
+            let special_depth = crate::gate_swap_handle::handle_book_ticker(&response);
             trace_stack.on_after_format();
             // 没有买价或卖价,则不更新
             if special_depth.ticker.buy != Decimal::ZERO || special_depth.ticker.sell != Decimal::ZERO {
@@ -106,19 +104,18 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
             }
         }
         "futures.balances" => {
-            let account = crate::handle_info::HandleSwapInfo::handle_account_info(GateSwapEnum, &response, run_symbol);
+            let account= crate::gate_swap_handle::handle_account_info(&response, run_symbol);
             let mut core = core_arc_clone.lock().await;
             core.update_equity(account).await;
         }
         "futures.orders" => {
             trace_stack.set_source("gate_swap.orders".to_string());
-            let orders = crate::handle_info::HandleSwapInfo::handle_order(GateSwapEnum, response.clone(), multiplier.clone());
+            let orders = crate::gate_swap_handle::handle_order(response.clone(), multiplier.clone());
 
             let mut order_infos:Vec<OrderInfo> = Vec::new();
             for mut order in orders.order {
                 if order.status == "NULL" {
                     error!("gate_usdt_swap 未识别的订单状态:{:?}", response);
-
                     continue;
                 }
 
@@ -132,7 +129,7 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
             }
         }
         "futures.positions" => {
-            let positions = crate::handle_info::HandleSwapInfo::handle_position(GateSwapEnum, &response, multiplier);
+            let positions = crate::gate_swap_handle::handle_position(&response, multiplier);
             let mut core = core_arc_clone.lock().await;
             core.update_position(positions).await;
         }
@@ -168,3 +165,24 @@ fn parse_btree_map_to_gate_swap_login(exchange_params: BTreeMap<String, String>)
         secret: exchange_params.get("secret_key").unwrap().clone()
     }
 }
+
+pub async fn on_special_depth(core_arc: Arc<Mutex<Core>>,
+                              update_flag_u: &mut Decimal,
+                              label: &String,
+                              trace_stack: &mut TraceStack,
+                              special_depth: &SpecialDepth) {
+    if special_depth.t > *update_flag_u {
+        let mut core = core_arc.lock().await;
+        trace_stack.on_after_unlock_core();
+
+        core.tickers.insert(label.clone(), special_depth.ticker.clone());
+        core.depths.insert(label.clone(), special_depth.depth.clone());
+
+        // 触发depth更新
+        core.on_depth_update(&(special_depth.depth), &label, trace_stack).await;
+
+        core.local_depths.insert(special_depth.name.clone(), special_depth.depth.clone());
+
+        *update_flag_u = special_depth.t;
+    }
+}

+ 0 - 157
src/handle_info.rs

@@ -1,157 +0,0 @@
-use std::cmp::Ordering;
-use std::str::FromStr;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::FromPrimitive;
-use rust_decimal_macros::dec;
-use crate::public_params;
-use crate::exchange::ExchangeEnum;
-use crate::gate_swap_handle;
-use crate::model::{Account, MarketOrder, Position, SpecialDepth, SpecialOrder, SpecialTicker};
-use crate::response_base::ResponseData;
-
-#[allow(dead_code)]
-pub struct HandleSwapInfo;
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct DepthParam {
-    pub depth_asks: Vec<MarketOrder>,
-    pub depth_bids: Vec<MarketOrder>,
-    pub t: Decimal,
-    pub create_at: i64
-}
-
-#[allow(dead_code)]
-impl HandleSwapInfo {
-    // 处理账号信息
-    pub fn handle_account_info(exchange: ExchangeEnum, res_data: &ResponseData, symbol: &String) -> Account {
-        match exchange {
-            ExchangeEnum::GateSwapEnum => {
-                gate_swap_handle::handle_account_info(res_data, symbol)
-            }
-        }
-    }
-    // 处理特殊Ticket信息
-    pub async fn handle_book_ticker(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
-        match exchange {
-            ExchangeEnum::GateSwapEnum => {
-                gate_swap_handle::handle_book_ticker(res_data)
-            }
-        }
-    }
-    // 处理position信息
-    pub fn handle_position(exchange: ExchangeEnum, res_data: &ResponseData, ct_val: &Decimal) -> Vec<Position> {
-        match exchange {
-            ExchangeEnum::GateSwapEnum => {
-                gate_swap_handle::handle_position(res_data, ct_val)
-            }
-        }
-    }
-    // 处理订单信息
-    pub fn handle_order(exchange: ExchangeEnum, res_data: ResponseData, ct_val: Decimal) -> SpecialOrder {
-        match exchange {
-            ExchangeEnum::GateSwapEnum => {
-                gate_swap_handle::handle_order(res_data, ct_val)
-            }
-        }
-    }
-
-    // 处理深度信息
-    pub fn handle_special_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> SpecialDepth {
-        let label = res_data.label.clone();
-        // 格式化
-        let mut format_depth = format_depth(exchange, res_data);
-        // 运算、组装
-        make_special_depth(label, &mut format_depth.depth_asks, &mut format_depth.depth_bids, format_depth.t, format_depth.create_at)
-    }
-}
-
-
-pub fn make_special_depth(label: String, depth_asks: &mut Vec<MarketOrder>, depth_bids: &mut Vec<MarketOrder>, t: Decimal, create_at: i64) -> SpecialDepth {
-    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));
-    // TODO 不排序的话,有4us可以省下来。
-    let mp = (depth_asks[0].price + depth_bids[0].price) * dec!(0.5);
-    let step = (public_params::EFF_RANGE * mp / Decimal::from_usize(public_params::LEVEL).unwrap()).round_dp(mp.scale());
-    let mut ap = Vec::new();
-    let mut bp = Vec::new();
-    let mut av: Vec<Decimal> = Vec::new();
-    let mut bv: Vec<Decimal> = Vec::new();
-    for i in 0..public_params::LEVEL {
-        let price = (depth_asks[0].price + step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_asks[0].price.scale());
-        ap.push(price);
-    }
-    for i in 0..public_params::LEVEL {
-        let price = (depth_bids[0].price - step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_bids[0].price.scale());
-        bp.push(price);
-    }
-    let mut ap_price_tag = depth_asks[0].price + step;
-    let mut ap_index = 0;
-    for item in depth_asks.iter() {
-        let price = item.price;
-        let amount = item.amount;
-        if av.get(ap_index).is_none() { av.push(Decimal::ZERO) };
-        if price < ap_price_tag {
-            av[ap_index] += amount;
-        } else {
-            ap_price_tag += step;
-            ap_index += 1;
-            if ap_index == public_params::LEVEL {
-                break;
-            }
-            av[ap_index] += amount
-        }
-    }
-
-    let mut bp_price_tag = depth_bids[0].price - step;
-    let mut bp_index = 0;
-    for item in depth_bids.iter() {
-        let price = item.price;
-        let amount = item.amount;
-        if bv.get(bp_index).is_none() { bv.push(Decimal::ZERO) };
-        if price > bp_price_tag {
-            bv[bp_index] += amount;
-        } else {
-            bp_price_tag -= step;
-            bp_index += 1;
-            if bp_index == public_params::LEVEL {
-                break;
-            }
-            bv[bp_index] += amount
-        }
-    }
-
-    let ticker_info = SpecialTicker { sell: depth_asks[0].price, buy: depth_bids[0].price, mid_price: mp, t, create_at };
-    let depth_info = bp.iter().cloned().chain(bv.iter().cloned()).chain(ap.iter().cloned()).chain(av.iter().cloned()).collect();
-    SpecialDepth {
-        name: label,
-        depth: depth_info,
-        ticker: ticker_info,
-        t,
-        create_at,
-    }
-}
-
-pub fn format_depth(exchange: ExchangeEnum, res_data: &ResponseData) -> DepthParam {
-    let depth_asks: Vec<MarketOrder>;
-    let depth_bids: Vec<MarketOrder>;
-    let t: Decimal;
-    let create_at: i64;
-    match exchange {
-        ExchangeEnum::GateSwapEnum => {
-            depth_asks = gate_swap_handle::format_depth_items(&res_data.data["asks"]);
-            depth_bids = gate_swap_handle::format_depth_items(&res_data.data["bids"]);
-            // todo! 有id可以取 保证与py一致
-            t = Decimal::from_str(&res_data.data["t"].to_string()).unwrap();
-            create_at = res_data.data["t"].as_i64().unwrap() * 1000;
-        }
-    }
-
-    DepthParam {
-        depth_asks,
-        depth_bids,
-        t,
-        create_at
-    }
-}
-
-

+ 0 - 5
src/main.rs

@@ -6,7 +6,6 @@ pub mod core;
 pub mod model;
 mod strategy;
 mod utils;
-pub mod exchange_disguise;
 mod gate_usdt_swap;
 pub mod clear_core;
 pub mod proxy;
@@ -15,16 +14,12 @@ pub mod http_tool;
 pub mod gate_swap_ws;
 pub mod gate_swap_rest;
 pub mod socket_tool;
-// 引入exchange模块
-pub mod exchange;
-pub mod handle_info;
 // 引入gate模块
 mod gate_swap;
 pub mod gate_swap_handle;
 pub mod params;
 pub mod log_utils;
 pub mod clear_log_utils;
-pub mod account_info;
 pub mod clear_position_result;
 pub mod cci;
 pub mod public_params;

+ 4 - 5
src/model.rs

@@ -2,7 +2,6 @@ use std::collections::HashMap;
 use std::fmt;
 use std::fmt::Formatter;
 use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
 use serde_derive::{Deserialize, Serialize};
 use tokio::time::Instant;
 use crate::trace_stack::TraceStack;
@@ -29,10 +28,10 @@ pub struct LocalPosition {
 impl LocalPosition {
     pub fn new() -> LocalPosition {
         LocalPosition{
-            long_pos: dec!(0),
-            short_pos: dec!(0),
-            long_avg: dec!(0),
-            short_avg: dec!(0),
+            long_pos: Decimal::ZERO,
+            short_pos: Decimal::ZERO,
+            long_avg: Decimal::ZERO,
+            short_avg: Decimal::ZERO,
         }
     }
 }

+ 3 - 3
src/params.rs

@@ -1,7 +1,7 @@
 use std::fs::File;
 use std::io::Read;
+use std::str::FromStr;
 use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
 use toml::from_str;
 use serde_derive::Deserialize;
 use serde_json::Value;
@@ -96,8 +96,8 @@ impl Params {
             // 接下来是写死的参数
             interval: 100,
             broker_id: json_value["exchange"].as_str().unwrap().to_string().split("_").collect::<Vec<_>>()[0].to_string(),
-            used_pct: dec!(1),
-            gamma: dec!(0.999),
+            used_pct: Decimal::ONE,
+            gamma: Decimal::from_str("0.999").unwrap(),
             log_level: "info".to_string(),
             port: call_port,
             run_mode: 0,

+ 3 - 5
src/public_params.rs

@@ -1,5 +1,3 @@
-use rust_decimal::Decimal;
-use rust_decimal_macros::dec;
 
 // TODO 市场数据汇总(market_info)的下标集合
 pub const LEVEL: usize = 1;
@@ -12,9 +10,9 @@ pub const ASK_QUANTITY_INDEX: usize = LEVEL * 2 + 1;                        // 
 // 上面是市场数据汇总的下标相关
 pub const MARKET_DELAY_LIMIT: i64 = 10*60*1000;                             // 市场信息延迟限制(单位:毫秒)
 pub const GRID: i64 = 1;                                                    // 策略资金分成多少份
-pub const STOP_LOSS: Decimal = dec!(0.02);                                  // 风控止损比例,0.02代表2%,是原文的STOPLOSS
-pub const GAMMA: Decimal = dec!(0.999);                                     // gamma默认值
-pub const EFF_RANGE: Decimal = dec!(0.001);                                 // 每1权重需要多少价格距离,0.001代表0.1%,每0.1%代表1权重
+// pub const STOP_LOSS: Decimal = Decimal::new(2, 2);                                  // 风控止损比例,0.02代表2%,是原文的STOPLOSS  0.02
+// pub const GAMMA: Decimal = Decimal::new(999, 3);                                   // gamma默认值 0.999
+// pub const EFF_RANGE: Decimal = Decimal::new(1, 3);                                 // 每1权重需要多少价格距离,0.001代表0.1%,每0.1%代表1权重 0.001
 
 // 各交易所限频规则汇总
 pub const BASIC_LIMIT:i64 = 100;

+ 21 - 21
src/strategy.rs

@@ -1,10 +1,10 @@
 use std::cmp::{max, min};
 use std::collections::HashMap;
 use std::ops::{Div, Mul};
+use std::str::FromStr;
 use chrono::Utc;
 use rust_decimal::Decimal;
 use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
-use rust_decimal_macros::dec;
 use tracing::{error, info, warn};
 use tokio::time::Instant;
 use crate::params::Params;
@@ -162,8 +162,8 @@ impl Strategy {
             total_amount: Default::default(),
             is_ready: false,
             _is_print: is_print,
-            _min_amount_value: dec!(5.0),
-            _max_amount_value: dec!(10000.0),
+            _min_amount_value: Decimal::from_str("5.0").unwrap(),
+            _max_amount_value: Decimal::from_str("10000.0").unwrap(),
             mp_ema: Default::default(),
             mp: Default::default(),
             bp: Default::default(),
@@ -171,8 +171,8 @@ impl Strategy {
             ref_price: Default::default(),
             ref_bp: Default::default(),
             ref_ap: Default::default(),
-            step_size: dec!(1e-10),
-            tick_size: dec!(1e-10),
+            step_size: Decimal::new(1, 10),
+            tick_size: Decimal::new(1, 10),
             max_pos_rate: Default::default(),
             profit: Default::default(),
             daily_return: Default::default(),
@@ -227,7 +227,7 @@ impl Strategy {
         // 开仓下单间隔 均匀下单机会
         strategy.post_open_time = now.timestamp_millis();
         let post_open_interval_per_second = Decimal::ONE.div(Decimal::from_i64(get_limit_order_requests_num_per_second(params.exchange.clone())).unwrap());
-        strategy.post_open_interval = dec!(1000).mul(post_open_interval_per_second).to_i64().unwrap();
+        strategy.post_open_interval = Decimal::from_str("1000").unwrap().mul(post_open_interval_per_second).to_i64().unwrap();
         info!("策略模块初始化完成!");
 
         strategy
@@ -254,12 +254,12 @@ impl Strategy {
         // 价格值处理
         self.bp = agg_market[crate::public_params::BID_PRICE_INDEX];
         self.ap = agg_market[crate::public_params::ASK_PRICE_INDEX];
-        self.mp = (self.bp + self.ap) * dec!(0.5);
+        self.mp = (self.bp + self.ap) * Decimal::from_str("0.5").unwrap();
         // 中间价的ema值处理
         if self.mp_ema.eq(&Decimal::ZERO) {
             self.mp_ema = self.mp;
         } else {
-            self.mp_ema = self.mp_ema * dec!(0.999) + self.mp * dec!(0.001);
+            self.mp_ema = self.mp_ema * Decimal::from_str("0.999").unwrap() + self.mp * Decimal::from_str("0.001").unwrap();
         }
         // debug!(?self.bp, ?self.ap, ?self.mp, ?self.mp_ema);
 
@@ -267,7 +267,7 @@ impl Strategy {
         if self.mp > self.mp_ema {
             self.adjust_lever_rate = Decimal::ONE;
         } else {
-            self.adjust_lever_rate = dec!(0.8);
+            self.adjust_lever_rate = Decimal::from_str("0.8").unwrap();
         }
         // debug!(?self.adjust_lever_rate);
 
@@ -387,7 +387,7 @@ impl Strategy {
             Decimal::ZERO
         };
         let run_time = Utc::now().timestamp_millis() - self._start_time;
-        let run_time_day = Decimal::from(run_time) / (dec!(86400000));
+        let run_time_day = Decimal::from(run_time) / Decimal::from_str("86400000").unwrap();
         self.daily_return = self.profit / run_time_day;
         self.daily_return.rescale(2);
         self.short_pos_bias.rescale(2);
@@ -494,7 +494,7 @@ impl Strategy {
         }
         // 跟随做市模式
         else if self.maker_mode == "follow".to_string() {
-            mp = (ref_bp + ref_ap) * dec!(0.5);
+            mp = (ref_bp + ref_ap) * Decimal::from_str("0.5").unwrap();
             buy_start = mp;
             sell_start = mp;
         } else {
@@ -913,8 +913,8 @@ impl Strategy {
             // 平多价值大于最小交易价值,执行平多逻辑
             if self.pos.long_pos * self.mp > self._min_amount_value {
                 if pd_order_num == 0 {
-                    let mut price = (short_lower + short_upper) * dec!(0.5);
-                    price = clip(price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
+                    let mut price = (short_lower + short_upper) * Decimal::from_str("0.5").unwrap();
+                    price = clip(price, self.bp * Decimal::from_str("0.9995").unwrap(), self.ap * Decimal::from_str("1.03").unwrap());
                     price = fix_price(price, self.tick_size);
                     let mut amount = self.pos.long_pos;
                     amount = fix_amount(amount, self.step_size);
@@ -937,8 +937,8 @@ impl Strategy {
             // 平空价值大于最小交易价值,执行平空逻辑
             if self.pos.short_pos > self._min_amount_value {
                 if pk_order_num == 0 {
-                    let mut price = (long_upper + long_lower) * dec!(0.5);
-                    price = clip(price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
+                    let mut price = (long_upper + long_lower) * Decimal::from_str("0.5").unwrap();
+                    price = clip(price, self.bp * Decimal::from_str("0.97").unwrap(), self.ap * Decimal::from_str("1.0005").unwrap());
                     price = fix_price(price, self.tick_size);
                     let mut amount = self.pos.short_pos;
                     amount = fix_amount(amount, self.step_size);
@@ -960,7 +960,7 @@ impl Strategy {
         } else {
             if self.pos.long_pos > Decimal::ZERO {
                 if pd_order_num == 0 {
-                    let mut price = (short_lower + short_upper) * dec!(0.5);
+                    let mut price = (short_lower + short_upper) * Decimal::from_str("0.5").unwrap();
                     // 不限制大小
                     // price = clip(price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
                     price = fix_price(price, self.tick_size);
@@ -981,7 +981,7 @@ impl Strategy {
 
             if self.pos.short_pos > Decimal::ZERO {
                 if pk_order_num == 0 {
-                    let mut price = (long_upper + long_lower) * dec!(0.5);
+                    let mut price = (long_upper + long_lower) * Decimal::from_str("0.5").unwrap();
                     // 不限制大小
                     // price = clip(price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
                     price = fix_price(price, self.tick_size);
@@ -1135,15 +1135,15 @@ impl Strategy {
             short_free_value = min(coin_value, self.max_short_value) - sell_value;
         }
         // 一手开单价值计算
-        let one_hand_long_value = dec!(0.99) * (self.max_long_value / self.grid);
-        let one_hand_short_value = dec!(0.99) * (self.max_short_value / self.grid);
+        let one_hand_long_value = Decimal::from_str("0.99").unwrap() * (self.max_long_value / self.grid);
+        let one_hand_short_value = Decimal::from_str("0.99").unwrap() * (self.max_short_value / self.grid);
 
         // debug!(?self.post_side);
         // 挂多单
         if self.post_side >= 0 {
             // debug!(?buy_price_list);
             if buy_price_list.len() == 0 {
-                let mut target_buy_price = (long_upper + long_lower) * dec!(0.5);
+                let mut target_buy_price = (long_upper + long_lower) * Decimal::from_str("0.5").unwrap();
                 // 取消大小限制
                 target_buy_price = target_buy_price;
                 // target_buy_price = clip(target_buy_price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
@@ -1172,7 +1172,7 @@ impl Strategy {
         if self.post_side <= 0 {
             // debug!(?sell_price_list);
             if sell_price_list.len() == 0 {
-                let mut target_sell_price = (short_lower + short_upper) * dec!(0.5);
+                let mut target_sell_price = (short_lower + short_upper) * Decimal::from_str("0.5").unwrap();
                 // target_sell_price = clip(target_sell_price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
                 // 取消大小限制
                 target_sell_price = target_sell_price;