Browse Source

v4.0.10: 信号连续性+平仓条件优化

skyffire 8 months ago
parent
commit
4220f9cc6a
1 changed files with 77 additions and 18 deletions
  1. 77 18
      strategy/src/predictor.rs

+ 77 - 18
strategy/src/predictor.rs

@@ -41,6 +41,10 @@ pub struct Predictor {
     pub balance: Decimal,                                                       // 初始余额
     pub prev_balance: Decimal,
 
+    pub prev_open_time: Decimal,
+    pub trade_condition: Decimal,                                                 // 过去1分钟以内,差价是否满足过扩大行为+行情有针
+    pub trade_condition_time: Decimal,                                            // 满足时的瞬时时间
+
     pub ask_delta: Decimal,                                                     // δa
     pub bid_delta: Decimal,                                                     // δb
 
@@ -89,15 +93,15 @@ impl Predictor {
 
             while let Some(value) = rx.next().await {
                 // 数据填充到对应位置
-                // 第一步:获取插入位置
-                let target_ts = value[0]; // 时间戳在values[0]
-                let insert_pos = debugs[0]
-                    .binary_search_by(|ts| {
-                        ts.as_ref() // 解包Option
-                            .expect("Timestamp cannot be None")
-                            .cmp(&target_ts)
-                    })
-                    .unwrap_or_else(|e| e);
+                // // 第一步:获取插入位置, 这里有bug,持仓推送并不连续,有时候会导致图表显示错误……
+                // let target_ts = value[0]; // 时间戳在values[0]
+                // let insert_pos = debugs[0]
+                //     .binary_search_by(|ts| {
+                //         ts.as_ref() // 解包Option
+                //             .expect("Timestamp cannot be None")
+                //             .cmp(&target_ts)
+                //     })
+                //     .unwrap_or_else(|e| e);
 
                 // 第二步:执行插入操作
                 for i in 0..debugs.len() {
@@ -108,7 +112,7 @@ impl Predictor {
                     } else {
                         Some(value)
                     };
-                    debugs[i].insert(insert_pos, elem);
+                    debugs[i].push_back(elem)
                 }
 
                 // 长度限制
@@ -170,6 +174,9 @@ impl Predictor {
             balance: Default::default(),
             prev_balance: Default::default(),
 
+            trade_condition: Default::default(),
+            trade_condition_time: Default::default(),
+
             last_update_time: Default::default(),
             last_index: Default::default(),
 
@@ -182,6 +189,7 @@ impl Predictor {
 
             debug_sender: tx,
             trend_rate: Default::default(),
+            prev_open_time: Default::default(),
         };
 
         predictor
@@ -294,6 +302,15 @@ impl Predictor {
         }
 
         if prev_pos_amount != self.pos_amount {
+            // 重置连续信号
+            self.trade_condition = Decimal::ZERO;
+            self.trade_condition_time = Decimal::ZERO;
+
+            // 开单
+            if prev_pos_amount.is_zero() {
+                self.prev_open_time = Decimal::from(Utc::now().timestamp_millis())
+            }
+
             self.processor(update_time, true).await;
         }
     }
@@ -364,34 +381,72 @@ impl Predictor {
         let prev_bid_delta = self.bid_delta;
         let prev_ask_delta = self.ask_delta;
 
-        let is_close_long = self.inventory > Decimal::ZERO && (self.fair_price < self.mid_price * (Decimal::ONE + self.params.close));
-        let is_close_short = self.inventory < Decimal::ZERO && (self.fair_price > self.mid_price * (Decimal::ONE - self.params.close));
+        let now = Decimal::from(Utc::now().timestamp_millis());
+        let is_holding_time_over = dec!(15) * dec!(60_000);
+
+        let is_close_long = self.inventory > Decimal::ZERO && (
+            // 反转平仓
+            (self.fair_price < self.mid_price * (Decimal::ONE - self.params.close) && self.trend_rate > self.params.open * dec!(5))
+            // 达到最大持仓时间平仓
+            || (now - self.prev_open_time > is_holding_time_over)
+        );
+        let is_close_short = self.inventory < Decimal::ZERO && (
+            // 反转平仓
+            (self.fair_price > self.mid_price * (Decimal::ONE + self.params.close) && self.trend_rate < self.params.open * dec!(-5))
+            // 达到最大持仓时间平仓
+            || (now - self.prev_open_time > is_holding_time_over)
+        );
+        let is_open_long = self.fair_price > self.mid_price * (Decimal::ONE + self.params.open) && self.trend_rate < self.params.open * dec!(-5);
+        let is_open_short = self.fair_price < self.mid_price * (Decimal::ONE - self.params.open) && self.trend_rate > self.params.open * dec!(5);
+
+        // 使信号有一定持续性
+        if is_close_long {
+            self.trade_condition = dec!(1);
+        }
+        if is_close_short {
+            self.trade_condition = dec!(2);
+        }
+        if is_open_long {
+            self.trade_condition = dec!(3);
+            self.trade_condition_time = now;
+        }
+        if is_open_short {
+            self.trade_condition = dec!(4);
+            self.trade_condition_time = now;
+        }
+
+        // 开仓信号要过期,只保留10秒
+        if (self.trade_condition == dec!(3) || self.trade_condition == dec!(4))
+            && now - self.trade_condition_time > dec!(10_000) {
+            self.trade_condition = Decimal::ZERO;
+        }
 
+        // 开单信号处理
         self.bid_delta = dec!(-2);
         self.ask_delta = dec!(-2);
         self.optimal_ask_price = Self::DONT_VIEW;
         self.optimal_bid_price = Self::DONT_VIEW;
 
-        if is_close_long {
+        if self.trade_condition == dec!(1) && self.inventory > Decimal::ZERO {
             self.ask_delta = dec!(0);
             self.bid_delta = dec!(-2);
 
             self.optimal_ask_price = min(self.mid_price, self.fair_price);
             self.optimal_bid_price = Self::DONT_VIEW;
-        } else if is_close_short {
+        } else if self.trade_condition == dec!(2) && self.inventory < Decimal::ZERO {
             self.bid_delta = dec!(0);
             self.ask_delta = dec!(-2);
 
             self.optimal_bid_price = max(self.mid_price, self.fair_price);
             self.optimal_ask_price = Self::DONT_VIEW;
         } else if self.inventory.is_zero() {
-            if self.fair_price > self.mid_price * (Decimal::ONE + self.params.open) && self.trend_rate < self.params.open * dec!(-5) {
+            if self.trade_condition == dec!(3) {
                 self.bid_delta = dec!(0);
                 self.ask_delta = dec!(-2);
 
                 self.optimal_bid_price = self.fair_price;
                 self.optimal_ask_price = Self::DONT_VIEW;
-            } else if self.fair_price < self.mid_price * (Decimal::ONE - self.params.open) && self.trend_rate > self.params.open * dec!(5) {
+            } else if self.trade_condition == dec!(4) {
                 self.ask_delta = dec!(0);
                 self.bid_delta = dec!(-2);
 
@@ -400,9 +455,11 @@ impl Predictor {
             }
         }
 
+        // 价格处理
         self.optimal_ask_price.rescale(self.mid_price.scale());
         self.optimal_bid_price.rescale(self.mid_price.scale());
 
+        // 返回方向是否改变过,有改变可以立即在图表上显示
         prev_ask_delta != self.ask_delta || prev_bid_delta != self.bid_delta
     }
 
@@ -495,12 +552,14 @@ impl Predictor {
         let now = data_time;
         let mid_price = self.mid_price;
         let ask_price = if self.params.ref_exchange.len() > 0 {
-            self.fair_price_std_vec[0]
+            // self.fair_price_std_vec[0]
+            Self::DONT_VIEW
         } else {
             Self::DONT_VIEW
         };
         let bid_price = if self.params.ref_exchange.len() > 1 {
-            self.fair_price_std_vec[1]
+            // self.fair_price_std_vec[1]
+            Self::DONT_VIEW
         } else {
             Self::DONT_VIEW
         };