Ver Fonte

gate 更新市价止损

JiahengHe há 1 ano atrás
pai
commit
c47e1976db
3 ficheiros alterados com 69 adições e 41 exclusões
  1. 19 0
      config_htx.json
  2. 0 27
      src/core_libs.rs
  3. 50 14
      strategy/src/core.rs

+ 19 - 0
config_htx.json

@@ -0,0 +1,19 @@
+{
+  "lever_rate": 1,
+  "colo": 0,
+  "stop_loss": 0.01,
+  "grid": 1,
+  "ref_exchange": "htx_usdt_swap",
+  "exchange": "htx_usdt_swap",
+  "open": 0.0038,
+  "close": 0.00008,
+  "pair": "pepe_usdt",
+  "ref_pair": "pepe_usdt",
+  "account": {
+    "secretKey": "6baacfd0-ebeb0de5-9aeb40ed-d2dbd",
+    "accessKey": "984b0506-a251aad4-e16133ec-ed2htwf5tf",
+    "pass": "",
+    "name": "htx_local_test"
+  },
+  "hold_coin": 0
+}

+ 0 - 27
src/core_libs.rs

@@ -7,7 +7,6 @@ use std::sync::Arc;
 use std::sync::atomic::{AtomicBool};
 use std::time::Duration;
 use chrono::Utc;
-use rust_decimal::Decimal;
 use tokio::sync::{mpsc, Mutex};
 use tokio::time::Instant;
 use tracing::{error, info};
@@ -106,32 +105,6 @@ pub async fn init(params: Params,
             }
         }
     });
-    // 市价数据更新(市价风控)
-    let markt_price_core_arc = core_arc.clone();
-    tokio::spawn(async move {
-        info!("市价风控数据更新启动...");
-        loop {
-            tokio::time::sleep(Duration::from_millis(100)).await;
-
-            let mut core = markt_price_core_arc.lock().await;
-            // 有仓位时检测
-            if core.local_position.long_pos > Decimal::ZERO || core.local_position.short_pos > Decimal::ZERO{
-                let positions = core.platform_rest.get_position().await;
-                match positions {
-                    Ok(pos) => {
-                        let total_price: Decimal = pos.iter()
-                            .map(|p| &p.profit)
-                            .sum();
-                        core.update_equity_profit_including_unrealized(total_price).await;
-                    },
-                    Err(err) => {
-                        error!("市价风控数据获取异常 {}", err);
-                    }
-                }
-            }
-        }
-    });
-
 
     let _error_handler_core_arc = core_arc.clone();
     tokio::spawn(async move {

+ 50 - 14
strategy/src/core.rs

@@ -642,6 +642,10 @@ impl Core {
             if self.mode_signal == 0 && self.ready == 1 {
                 self.on_agg_market();
             }
+            // 市价计算浮盈、亏
+            let mid_price = (depth[BID_PRICE_INDEX] + depth[ASK_PRICE_INDEX]) / Decimal::from_str("2").unwrap();
+            self.update_equity_profit_including_unrealized(mid_price).await;
+
         } else if *name_ref == self.ref_name[0] { // 判断是否为当前跟踪的盘口
             // 判断是否需要触发ontick 对行情进行过滤
             // 过滤条件 价格变化很大 时间间隔很长
@@ -952,17 +956,26 @@ impl Core {
         }
     }
     // 更新本地值(市场价)
-    pub async fn update_equity_profit_including_unrealized(&mut self, profit:Decimal){
-        self.local_cash_including_unrealized = self.local_cash + profit;
-        if self.local_cash_including_unrealized > self.max_local_cash_including_unrealized{
-            self.max_local_cash_including_unrealized = self.local_cash_including_unrealized.clone();
+    pub async fn update_equity_profit_including_unrealized(&mut self, mid_price:Decimal){
+        let mut profit = Decimal::ZERO;
+        if self.local_position.long_pos > Decimal::ZERO {
+            let long_profit = self.local_position.long_pos * self.local_position.long_avg - self.local_position.long_pos * mid_price;
+            profit += long_profit;
+        }
+        if self.local_position.short_pos > Decimal::ZERO{
+            let short_profit = self.local_position.short_pos * self.local_position.short_avg - self.local_position.short_pos * mid_price;
+            profit += short_profit;
+        }
+        if profit != Decimal::ZERO {
+            info!("更新浮盈亏 profit {}", profit);
+            self.local_cash_including_unrealized = self.local_cash + profit;
+            info!("含浮盈亏净值: local_cash_including_unrealized {}", self.local_cash_including_unrealized);
+            if self.local_cash_including_unrealized > self.max_local_cash_including_unrealized{
+                self.max_local_cash_including_unrealized = self.local_cash_including_unrealized.clone();
+            }
         }
     }
 
-    pub async fn check_market_price_risk(&mut self){
-
-    }
-
     // #[instrument(skip(self), level="TRACE")]
     pub async fn check_risk(&mut self) {
         // 参数检查的风控
@@ -1195,7 +1208,7 @@ impl Core {
     }
 
     // #[instrument(skip(self, target_hold_coin), level="TRACE")]
-    pub async fn check_position(&mut self, target_hold_coin: Decimal) -> bool {
+    pub async fn check_position(&mut self, target_hold_coin: Decimal, is_first_clear: bool) -> bool {
         info!("------------------------------------------------------------------------------------------------------------");
         info!("步骤一:检查挂单:");
         let mut is_order_clear = false;
@@ -1229,6 +1242,11 @@ impl Core {
         info!("挂单检查完毕。");
         info!("");
 
+        // 如果不是第一次检查,留500ms给交易所撮合
+        if !is_first_clear {
+            sleep(Duration::from_millis(500)).await;
+        }
+
         info!("步骤二:检查仓位:");
         let is_position_clear;
         if self.exchange.contains("spot") { // 现货
@@ -1575,7 +1593,7 @@ impl Core {
         let short_one_hand_value: Decimal;
         let long_one_hand_amount: Decimal = (long_one_hand_value / mp / &self.strategy.step_size).floor() * self.strategy.step_size;
         let short_one_hand_amount: Decimal;
-        info!("mp {}", mp);
+
         if self.exchange.contains("spot") {
             short_one_hand_value = start_coin * mp * self.params.lever_rate / grid;
             short_one_hand_amount = (short_one_hand_value / mp / self.strategy.step_size).floor() * self.strategy.step_size;
@@ -1619,18 +1637,36 @@ impl Core {
 
     pub async fn clear_position_and_orders(&mut self, target_hold_coin: Decimal) {
         let mut clear_count = 1;
-        while !self.check_position(target_hold_coin).await {
-            sleep(Duration::from_secs(1)).await;
+        let mut total_clear_count = 1;
 
-            if clear_count >= 3600 {
-                info!("清理次数达到上限:{}次,不再执行清理。", clear_count);
+        loop {
+            let is_clear = self.check_position(target_hold_coin, clear_count <= 1).await;
+            // 如果5次中间有一次没清理干净,则重新清理
+            if !is_clear {
+                clear_count = 1
+            }
+
+            // 如果连续5次都检查到清理干净,则表明大概率是清理干净了的
+            if clear_count >= 5 {
+                info!("连续{}次清理完成。", clear_count);
+                info!("");
+                break
+            }
+
+            // 最大次数判定
+            if total_clear_count >= 500 {
+                info!("清理次数达到上限:{}次,不再执行清理。", total_clear_count);
                 info!("");
                 break
             }
 
             clear_count += 1;
+            total_clear_count += 1;
             info!("清理指令发送完毕,启动第{}次检查。", clear_count);
             info!("");
+
+            // 每次清理间隔1s
+            sleep(Duration::from_secs(1)).await;
         }
     }
 }