Browse Source

觀察平均穿越時間。

skyfffire 1 year ago
parent
commit
e58d956eb8
1 changed files with 26 additions and 10 deletions
  1. 26 10
      strategy/src/avellaneda_stoikov.rs

+ 26 - 10
strategy/src/avellaneda_stoikov.rs

@@ -50,6 +50,7 @@ pub struct AvellanedaStoikov {
     pub prev_trade_time: i64,                                                   // 上次交易时间,也就是t
     pub cross_time: i64,                                                        // 上次穿過0軸的時間
     pub cross_time_diff: i64,                                                   // 穿越0軸的diff
+    pub cross_time_diff_avg: i64,                                               // 穿越0軸的diff的平均值
     pub t_diff: Decimal,                                                        // (T-t)
     pub prev_close_time: i64,                                                   // 上次平倉時間
     pub prev_prev_close_time: i64,                                              // 上上次平倉時間
@@ -100,6 +101,7 @@ impl AvellanedaStoikov {
             prev_trade_time: Utc::now().timestamp_micros(),
             cross_time: 0,
             cross_time_diff: 0,
+            cross_time_diff_avg: 0,
             t_diff: Default::default(),
             flow_ratio_long: Decimal::ONE,
             level: Default::default(),
@@ -244,12 +246,20 @@ impl AvellanedaStoikov {
             self.ask_delta += pos_edge;
         }
 
+        if self.flow_ratio_long.is_zero() || self.cross_time_diff < 30 {
+            self.ask_delta += self.base_delta;
+            self.bid_delta += self.base_delta;
+
+            return;
+        }
+
         if self.flow_ratio_long < Decimal::ZERO {
             if self.flow_ratio_short > Decimal::ZERO {
                 self.ask_delta -= self.base_delta * (self.flow_ratio_short.abs() * Decimal::PI);
                 self.bid_delta += self.base_delta;
             } else if self.flow_ratio_short < Decimal::ZERO && self.inventory < Decimal::ZERO {
                 self.ask_delta += self.base_delta;
+                // self.bid_delta -= self.base_delta * (self.flow_ratio_short.abs() + self.flow_ratio_long.abs());
                 self.bid_delta -= self.base_delta * (self.flow_ratio_short.abs() * dec!(1.5));
             } else {
                 self.ask_delta += self.base_delta;
@@ -257,6 +267,7 @@ impl AvellanedaStoikov {
             }
         } else if self.flow_ratio_long > Decimal::ZERO {
             if self.flow_ratio_short > Decimal::ZERO && self.inventory > Decimal::ZERO {
+                // self.ask_delta -= self.base_delta * (self.flow_ratio_short.abs() + self.flow_ratio_long.abs());
                 self.ask_delta -= self.base_delta * (self.flow_ratio_short.abs() * dec!(1.5));
                 self.bid_delta += self.base_delta;
             } else if self.flow_ratio_short < Decimal::ZERO {
@@ -266,13 +277,6 @@ impl AvellanedaStoikov {
                 self.ask_delta += self.base_delta;
                 self.bid_delta += self.base_delta;
             }
-        } else {
-            self.ask_delta += self.base_delta;
-            self.bid_delta += self.base_delta;
-        }
-
-        if self.init_delta_plus.is_zero() {
-            self.init_delta_plus = (self.bid_delta + self.ask_delta) / Decimal::TWO
         }
     }
 
@@ -379,13 +383,25 @@ impl AvellanedaStoikov {
     pub fn update_flow_ratio(&mut self) {
         let prev_flow_ratio_long = self.flow_ratio_long;
         self.flow_ratio_long = Self::calc_flow_ratio(&self.flow_ratio_long, &dec!(0), &mut self.trade_long_vec);
+        let time = Utc::now().timestamp_millis();
+        let mut is_cross = false;
         if (self.flow_ratio_long > Decimal::ZERO && prev_flow_ratio_long <= Decimal::ZERO)
             || (self.flow_ratio_long < Decimal::ZERO && prev_flow_ratio_long >= Decimal::ZERO) {
-            self.cross_time = Utc::now().timestamp_millis();
+            self.cross_time = time;
+            is_cross = true;
         }
 
         if self.cross_time != 0 {
-            self.cross_time_diff = (Utc::now().timestamp_millis() - self.cross_time) / 1000;
+            let prev_cross_time_diff = self.cross_time_diff;
+            self.cross_time_diff = (time - self.cross_time) / 1000;
+
+            if is_cross {
+                self.cross_time_diff_avg = if self.cross_time_diff_avg == 0 {
+                    prev_cross_time_diff
+                } else {
+                    (self.cross_time_diff_avg * 5 + prev_cross_time_diff * 5) / 10
+                };
+            }
         }
 
         self.flow_ratio_short = Self::calc_flow_ratio(&self.flow_ratio_short, &dec!(0), &mut self.trade_short_vec);
@@ -469,7 +485,7 @@ impl AvellanedaStoikov {
             inventory: self.inventory,
             sigma_square: self.flow_ratio_long,
             gamma: self.flow_ratio_short,
-            kappa: Decimal::from(self.cross_time_diff),
+            kappa: Decimal::from(self.cross_time_diff_avg),
 
             flow_ratio: self.flow_ratio_long,
             ref_price: self.ref_price,