Quellcode durchsuchen

v4.1.2: 使用论文的方法实现的因子测试。

skyffire vor 8 Monaten
Ursprung
Commit
6bc02363ef
1 geänderte Dateien mit 85 neuen und 20 gelöschten Zeilen
  1. 85 20
      strategy/src/predictor.rs

+ 85 - 20
strategy/src/predictor.rs

@@ -27,6 +27,7 @@ pub struct Predictor {
     pub mu: Decimal,
     pub sigma: Decimal,
     pub phi: Decimal,
+    pub weights: VecDeque<Decimal>,
 
     pub prices: Vec<Vec<FixedTimeRangeDeque<Decimal>>>,                         // [[[做市所], [参考所0]], ...]
     pub ks: Vec<Decimal>,
@@ -167,6 +168,7 @@ impl Predictor {
             mu: Default::default(),
             sigma: Default::default(),
             phi: Default::default(),
+            weights: Self::calculate_weights(60),
 
             mid_price: Default::default(),
             ask_price: Default::default(),
@@ -284,6 +286,15 @@ impl Predictor {
                     self.log_return_vec.push_back(log_return);
                     self.mu = Self::calculate_mean(&self.log_return_vec);
                     self.sigma = Self::calculate_std(&self.log_return_vec);
+
+                    let r = if self.sigma.is_zero() {
+                        Decimal::ZERO
+                    } else {
+                        (log_return - self.mu) / self.sigma
+                    };
+                    self.r_vec.push_back(r);
+
+                    self.phi = Self::calculate_convolve(&self.r_vec, &self.weights);
                 }
             }
 
@@ -453,21 +464,14 @@ impl Predictor {
 
         let is_close_long = self.inventory > Decimal::ZERO && (
             // 硬止损,开单不久之后就在亏
-            (self.profit_high < dec!(0.001) && self.profit < dec!(-0.005))
-            // 浮动止损,如果profit_high较高产生了利润,但后续不给力
-            || (self.profit_high - self.profit > dec!(0.0075) && self.profit < Decimal::ZERO)
-            // 利润较大时,追踪止盈
-            || (self.profit > dec!(0.005) && self.profit < self.profit_high * dec!(0.75))
-        );
-        let is_close_short = self.inventory < Decimal::ZERO && (
-            // 硬止损
-            (self.profit < dec!(-0.01))
-            // 利润较大时,追踪止盈
-            || (self.profit > dec!(0.01) && self.profit < self.profit_high * dec!(0.75))
+            (self.profit_high < dec!(0.001) && self.profit < dec!(-0.01))
+            // 时间到了,追踪止盈
+            || (now - self.prev_open_time > dec!(100_000) && self.profit < self.profit_high * dec!(0.75))
         );
+        let is_close_short = self.inventory < Decimal::ZERO;
 
         let is_open_long = self.inventory.is_zero()
-            && self.fair_price > self.mid_price * dec!(1.0001)
+            && self.phi > Decimal::ONE
             && self.r_short < -self.params.open
         ;
 
@@ -611,6 +615,67 @@ impl Predictor {
         sum / Decimal::from(count) // 计算平均值
     }
 
+    fn calculate_weights(t: i32) -> VecDeque<Decimal> {
+        let max_n = 5 * t;
+        let mut raw_weights = VecDeque::with_capacity(max_n as usize);
+
+        // 计算 raw_weights
+        for n in 1..=max_n {
+            // 将 n 转换为 Decimal
+            let n_dec = Decimal::from(n);
+
+            // 计算 exp(-2 * n / T)
+            let exp_value = Decimal::from_f64((-2.0 * n as f64 / t as f64).exp())
+                .unwrap_or(dec!(0));
+
+            // 计算 n * exp(-2 * n / T)
+            let weight = n_dec * exp_value;
+            raw_weights.push_back(weight);
+        }
+
+        // 计算 M_T
+        let sum_squares: Decimal = raw_weights.iter()
+            .map(|&x| x * x)
+            .sum();
+        let m_t = dec!(1) / sum_squares.sqrt().unwrap_or(dec!(1));
+
+        // 计算最终权重并反转
+        let mut weights: VecDeque<Decimal> = raw_weights.iter()
+            .map(|&x| {
+                let rst = m_t * x;
+                rst.round_dp(8)
+            })
+            .collect();
+        weights.make_contiguous().reverse();
+
+        weights
+    }
+
+    fn calculate_convolve(signal: &VecDeque<Decimal>, kernel: &VecDeque<Decimal>) -> Decimal {
+        let signal_len = signal.len();
+        let kernel_len = kernel.len();
+        let result_len = signal_len + kernel_len - 1;
+
+        let mut result = Decimal::ZERO;
+
+        // 计算完整卷积
+        for i in 0..result_len {
+            let mut sum = Decimal::ZERO;
+
+            // 对于每个输出点,计算所有可能的乘积和
+            for j in 0..kernel_len {
+                let signal_idx = i as i32 - j as i32;
+                if signal_idx >= 0 && signal_idx < signal_len as i32 {
+                    sum += signal[signal_idx as usize] * kernel[j];
+                }
+            }
+
+            result = sum;
+        }
+
+        result
+    }
+
     // 最小二乘法拟合函数,支持VecDeque
     pub async fn linear_least_squares(&self, index: usize) -> Option<(Decimal, Decimal)> {
         let x = &self.prices[index][1];
@@ -685,19 +750,19 @@ impl Predictor {
         let last_price = Self::DONT_VIEW;
         let fair_price = self.fair_price;
 
-        let spread = Self::DONT_VIEW;
+        let spread = if self.r_vec.len() > 0 {
+            self.r_vec.iter().last().unwrap().clone()
+        } else {
+            Decimal::ZERO
+        };
         let spread_max = self.mu;
         let spread_min = self.sigma;
-        // let spread = self.price_times_avg;
-        // let spread_max = self.fair_price_vec[1] / self.fair_price_vec[0];
-        // let spread_min = self.fair_price / self.mid_price;
 
         let inventory = self.inventory;
 
-        let sigma_square = Decimal::from(Utc::now().timestamp_millis()) - data_time;
-        // let sigma_square = Self::DONT_VIEW;
-        let gamma = Self::DONT_VIEW;
-        let kappa = self.balance;
+        let sigma_square = self.phi;
+        let gamma = self.balance;
+        let kappa = Decimal::from(Utc::now().timestamp_millis()) - data_time;
 
         let flow_ratio = Decimal::ZERO;