Ver código fonte

MFI第一版,仅view

skyffire 1 ano atrás
pai
commit
df15d7738b
1 arquivos alterados com 34 adições e 9 exclusões
  1. 34 9
      strategy/src/avellaneda_stoikov.rs

+ 34 - 9
strategy/src/avellaneda_stoikov.rs

@@ -37,13 +37,13 @@ pub struct AvellanedaStoikov {
 
     pub flow_ratio_long: Decimal,                                               // 资金流比例
     pub flow_ratio_short: Decimal,                                              // 资金流比例
+    pub money_flow_index: Decimal,                                              // MFI
 
     pub ask_delta: Decimal,                                                     // δa
     pub bid_delta: Decimal,                                                     // δb
     pub base_delta: Decimal,                                                    // 基础挂单距离
     pub ratio_edge: Decimal,                                                    // 资金流修正的挂单距离
     pub ref_price: Decimal,                                                     // 预定价格
-    pub init_delta_plus: Decimal,                                               // 最初的delta之和
 
     pub cci_arc: Arc<Mutex<CentralControlInfo>>,                                // 中控信息
 
@@ -87,7 +87,6 @@ impl AvellanedaStoikov {
             ask_delta: Default::default(),
             bid_delta: Default::default(),
             base_delta: Default::default(),
-            init_delta_plus: Default::default(),
 
             ratio_edge: Default::default(),
             kappa: Default::default(),
@@ -98,9 +97,10 @@ impl AvellanedaStoikov {
             is_ready: false,
             prev_trade_time: Utc::now().timestamp_micros(),
             t_diff: Default::default(),
-            flow_ratio_long: Decimal::ONE,
             level: Default::default(),
+            flow_ratio_long: Default::default(),
             flow_ratio_short: Default::default(),
+            money_flow_index: Default::default(),
         };
 
         avellaneda_stoikov
@@ -189,6 +189,35 @@ impl AvellanedaStoikov {
                 self.record_vec.push_back(record.clone());
             }
         }
+
+        // 如果蜡烛数量足够,则更新mfi
+        if self.record_vec.len() >= 3 {
+            self.update_mfi();
+        }
+    }
+
+    pub fn update_mfi(&mut self) {
+        let mut money_flow_in = Decimal::ZERO;
+        let mut money_flow_out = Decimal::ZERO;
+        let _3 = dec!(3);
+
+        for record in self.record_vec.deque.iter() {
+            let typical_price = (record.high + record.low + record.close) / _3;
+            let money_flow = typical_price * record.volume;
+            if record.close > record.open {
+                money_flow_in += money_flow;
+            } else if record.close < record.open {
+                money_flow_out += money_flow;
+            }
+        }
+
+        self.money_flow_index = if money_flow_out.is_zero() {
+            Decimal::ONE_HUNDRED
+        } else {
+            let money_flow_ratio = money_flow_in / money_flow_out;
+
+            Decimal::ONE_HUNDRED - Decimal::ONE_HUNDRED / (Decimal::ONE + money_flow_ratio)
+        };
     }
 
     pub async fn update_inventory(&mut self, inventory: &Decimal, min_amount_value: &Decimal) {
@@ -264,10 +293,6 @@ impl AvellanedaStoikov {
                 self.ask_delta = self.ask_delta + self.ratio_edge.abs() * dec!(16);
                 self.bid_delta = self.bid_delta - self.ratio_edge.abs() * (Decimal::TWO - self.t_diff);
             }
-
-            if self.init_delta_plus.is_zero() {
-                self.init_delta_plus = (self.bid_delta + self.ask_delta) / Decimal::TWO
-            }
         }
     }
 
@@ -487,8 +512,8 @@ impl AvellanedaStoikov {
             optimal_bid_price: self.optimal_bid_price,
 
             inventory: self.inventory,
-            sigma_square: self.flow_ratio_long,
-            gamma: self.flow_ratio_short,
+            sigma_square: self.money_flow_index,
+            gamma: self.flow_ratio_long,
             kappa: self.t_diff,
 
             flow_ratio: self.flow_ratio_long,