Эх сурвалжийг харах

新版方案,使用改變值就行開倉平倉。

skyfffire 1 жил өмнө
parent
commit
bb924a6c06

+ 42 - 31
strategy/src/avellaneda_stoikov.rs

@@ -16,7 +16,8 @@ pub struct AvellanedaStoikov {
     pub depth_vec: FixedTimeRangeDeque<Depth>,                                  // 深度队列
     pub trade_vec: FixedTimeRangeDeque<Trade>,                                  // 交易队列
     pub spread_vec: FixedTimeRangeDeque<Decimal>,
-    pub flow_ratio_vec: FixedTimeRangeDeque<Decimal>,                           // 資金流歷史記錄
+    pub flow_ratio_short_vec: FixedTimeRangeDeque<Decimal>,                     // 資金流歷史記錄
+    pub flow_ratio_long_vec: FixedTimeRangeDeque<Decimal>,                      // 資金流歷史記錄
 
     pub mid_price: Decimal,                                                     // 中间价
     pub ask_price: Decimal,                                                     // 卖一价
@@ -37,7 +38,8 @@ pub struct AvellanedaStoikov {
     pub flow_in_value: Decimal,
     pub flow_out_value: Decimal,
     pub flow_ratio: Decimal,                                                    // 资金流比例
-    pub flow_ratio_change: Decimal,                                             // 最近的資金流變化情況
+    pub flow_ratio_change_short: Decimal,                                       // 最近的資金流變化情況
+    pub flow_ratio_change_long: Decimal,                                       // 最近的資金流變化情況
 
     pub ask_delta: Decimal,                                                     // δa
     pub bid_delta: Decimal,                                                     // δb
@@ -70,7 +72,8 @@ impl AvellanedaStoikov {
             depth_vec: FixedTimeRangeDeque::new(Self::MAX_TIME_RANGE_MICROS),
             spread_vec: FixedTimeRangeDeque::new(Self::MAX_TIME_RANGE_MICROS),
             trade_vec: FixedTimeRangeDeque::new(Self::TRADE_RANGE_MICROS),
-            flow_ratio_vec: FixedTimeRangeDeque::new(Self::FLOW_RATIO_RANGE_MICROS),
+            flow_ratio_long_vec: FixedTimeRangeDeque::new(3 * Self::FLOW_RATIO_RANGE_MICROS),
+            flow_ratio_short_vec: FixedTimeRangeDeque::new(Self::FLOW_RATIO_RANGE_MICROS),
 
             mid_price: Default::default(),
             ask_price: Default::default(),
@@ -100,7 +103,8 @@ impl AvellanedaStoikov {
             prev_trade_time: Utc::now().timestamp_micros(),
             t_diff: Default::default(),
             flow_ratio: Decimal::ONE,
-            flow_ratio_change: Default::default(),
+            flow_ratio_change_short: Default::default(),
+            flow_ratio_change_long: Default::default(),
             flow_in_value: Default::default(),
             flow_out_value: Default::default(),
             level: Default::default(),
@@ -281,27 +285,27 @@ impl AvellanedaStoikov {
                 self.ask_delta += pos_edge;
             }
 
-            if self.flow_ratio < Decimal::ZERO {
-                if self.flow_ratio_change > dec!(0.01) || self.inventory > Decimal::ZERO {
-                    self.ask_delta -= self.base_delta * dec!(2);
-                    self.bid_delta += self.base_delta * dec!(2);
-                } else if self.flow_ratio_change < dec!(-0.01) && self.inventory < Decimal::ZERO {
-                    self.ask_delta += self.base_delta * dec!(2);
-                    self.bid_delta -= self.base_delta * dec!(2);
+            if self.flow_ratio_change_long < Decimal::ZERO {
+                if self.flow_ratio_change_short > dec!(0.05) {
+                    self.ask_delta -= self.base_delta;
+                    self.bid_delta += self.base_delta * dec!(3);
+                } else if self.flow_ratio_change_short < dec!(-0.15) && self.inventory < Decimal::ZERO {
+                    self.ask_delta += self.base_delta * dec!(3);
+                    self.bid_delta -= self.base_delta;
                 } else {
-                    self.ask_delta += self.base_delta * dec!(2);
-                    self.bid_delta += self.base_delta * dec!(2);
+                    self.ask_delta += self.base_delta * dec!(3);
+                    self.bid_delta += self.base_delta * dec!(3);
                 }
-            } else if self.flow_ratio > Decimal::ZERO {
-                if self.flow_ratio_change > dec!(0.01) && self.inventory > Decimal::ZERO {
-                    self.ask_delta -= self.base_delta * dec!(2);
-                    self.bid_delta += self.base_delta * dec!(2);
-                } else if self.flow_ratio_change < dec!(-0.01) || self.inventory < Decimal::ZERO {
-                    self.ask_delta += self.base_delta * dec!(2);
-                    self.bid_delta -= self.base_delta * dec!(2);
+            } else if self.flow_ratio_change_long > Decimal::ZERO {
+                if self.flow_ratio_change_short > dec!(0.15) && self.inventory > Decimal::ZERO {
+                    self.ask_delta -= self.base_delta;
+                    self.bid_delta += self.base_delta * dec!(3);
+                } else if self.flow_ratio_change_short < dec!(-0.05) {
+                    self.ask_delta += self.base_delta * dec!(3);
+                    self.bid_delta -= self.base_delta;
                 } else {
-                    self.ask_delta += self.base_delta * dec!(2);
-                    self.bid_delta += self.base_delta * dec!(2);
+                    self.ask_delta += self.base_delta * dec!(3);
+                    self.bid_delta += self.base_delta * dec!(3);
                 }
             }
 
@@ -326,19 +330,26 @@ impl AvellanedaStoikov {
     }
 
     pub fn update_flow_ratio(&mut self) {
-        if self.flow_out_value + self.flow_in_value > dec!(100_000) {
+        if self.flow_out_value + self.flow_in_value > dec!(300_000) {
             // 使用EMA來更新資金流,確保平滑性
             let a = Decimal::TWO / dec!(50);
             let now = (self.flow_in_value - self.flow_out_value) / (self.flow_out_value + self.flow_in_value);
             self.flow_ratio = a * now + (Decimal::ONE - a) * self.flow_ratio;
-            self.flow_ratio_vec.push_back(self.flow_ratio);
+            self.flow_ratio_long_vec.push_back(self.flow_ratio);
+            self.flow_ratio_short_vec.push_back(self.flow_ratio);
 
             // 更新最後的變化
-            if self.flow_ratio_vec.len() > 10 {
-                let last = self.flow_ratio_vec.deque.iter().last().unwrap().clone();
-                let first = self.flow_ratio_vec.deque[0];
+            if self.flow_ratio_short_vec.len() > 2 {
+                let last = self.flow_ratio_short_vec.deque.iter().last().unwrap().clone();
+                let first = self.flow_ratio_short_vec.deque[0];
 
-                self.flow_ratio_change = last - first;
+                self.flow_ratio_change_short = last - first;
+            }
+            if self.flow_ratio_long_vec.len() > 2 {
+                let last = self.flow_ratio_long_vec.deque.iter().last().unwrap().clone();
+                let first = self.flow_ratio_long_vec.deque[0];
+
+                self.flow_ratio_change_long = last - first;
             }
         } else {
             self.flow_ratio = Decimal::ZERO;
@@ -421,9 +432,9 @@ impl AvellanedaStoikov {
             optimal_bid_price: self.optimal_bid_price,
 
             inventory: self.inventory,
-            sigma_square: self.flow_ratio,
-            gamma: self.flow_ratio_change,
-            kappa: self.t_diff,
+            sigma_square: self.flow_ratio_change_long,
+            gamma: self.flow_ratio_change_short,
+            kappa: self.flow_ratio,
 
             flow_ratio: self.flow_ratio,
             ref_price: self.ref_price,