Browse Source

spread_best

skyfffire 1 year ago
parent
commit
a49ffde18e
1 changed files with 38 additions and 13 deletions
  1. 38 13
      strategy/src/avellaneda_stoikov.rs

+ 38 - 13
strategy/src/avellaneda_stoikov.rs

@@ -1,5 +1,5 @@
 use std::cmp::{max, min};
-use std::collections::{BTreeMap, VecDeque};
+use std::collections::{BTreeMap, HashMap, VecDeque};
 use std::sync::Arc;
 use chrono::Utc;
 use rust_decimal::prelude::*;
@@ -17,7 +17,8 @@ pub struct AvellanedaStoikov {
     pub fair_price_vec: Vec<Decimal>,                                           // 深度队列
     pub trade_long_vec: FixedTimeRangeDeque<Trade>,                             // 交易队列
     pub trade_short_vec: FixedTimeRangeDeque<Trade>,                            // 交易队列
-    pub spread_vec: FixedTimeRangeDeque<Decimal>,
+    pub spread_vec: Vec<Decimal>,                                               // 市场冲击队列
+    pub spread_count_map: HashMap<Decimal, usize>,                              // 市场次数的字典
     pub record_vec: VecDeque<Record>,                                           // 蜡烛队列
 
     pub mid_price: Decimal,                                                     // 中间价
@@ -26,7 +27,7 @@ pub struct AvellanedaStoikov {
     pub last_price: Decimal,                                                    // 最后成交价
     pub spread: Decimal,                                                        // 市场冲击
     pub spread_max: Decimal,                                                    // 最大市场冲击
-    pub spread_min: Decimal,                                                    // 最小市场冲击
+    pub spread_best: Decimal,                                                   // 最佳市场冲击
     pub optimal_ask_price: Decimal,                                             // 卖出挂单价
     pub optimal_bid_price: Decimal,                                             // 买入挂单价
 
@@ -53,7 +54,7 @@ impl AvellanedaStoikov {
     // 时间窗口大小(微秒)
     const MAX_TIME_RANGE_MICROS: i64 = 3 * 60_000_000;
     const TRADE_LONG_RANGE_MICROS: i64 = 3 * 60_000_000;
-    const SPREAD_RANGE_MICROS: i64 = 15 * 60_000_000;
+    // const SPREAD_RANGE_MICROS: i64 = 15 * 60_000_000;
     const TRADE_SHORT_RANGE_MICROS: i64 = 60_000_000;
     // const ONE_MILLION: Decimal = dec!(1_000_000);
     // const TWENTY_THOUSAND: Decimal = dec!(20_000);
@@ -66,7 +67,8 @@ impl AvellanedaStoikov {
             fair_price_vec: vec![Decimal::ZERO; 10],
 
             // 老的队列
-            spread_vec: FixedTimeRangeDeque::new(Self::SPREAD_RANGE_MICROS),
+            spread_vec: vec![],
+            spread_count_map: Default::default(),
             trade_long_vec: FixedTimeRangeDeque::new(Self::TRADE_LONG_RANGE_MICROS),
             trade_short_vec: FixedTimeRangeDeque::new(Self::TRADE_SHORT_RANGE_MICROS),
             record_vec: VecDeque::new(),
@@ -77,7 +79,7 @@ impl AvellanedaStoikov {
             last_price: Default::default(),
             spread: Default::default(),
             spread_max: Default::default(),
-            spread_min: Default::default(),
+            spread_best: Default::default(),
             optimal_ask_price: Default::default(),
             optimal_bid_price: Default::default(),
 
@@ -105,13 +107,28 @@ impl AvellanedaStoikov {
 
     // 更新最大市场冲击
     pub fn update_spread_max(&mut self) {
-        self.spread_max = if let Some(&max_value) = self.spread_vec.deque.iter().max() {
+        self.spread_max = if let Some(&max_value) = self.spread_vec.iter().max() {
             max_value
         } else {
             Decimal::NEGATIVE_ONE
         };
     }
 
+    // 更新最佳市场冲击
+    pub fn update_spread_best(&mut self) {
+        self.spread_best = self.spread_max;
+        let mut max_count = 0usize;
+
+        for (spread, count) in self.spread_count_map.iter() {
+            if *count < max_count {
+                continue
+            }
+
+            self.spread_best = *spread;
+            max_count = *count;
+        }
+    }
+
     pub fn update_spread(&mut self) {
         let prev_depth_0 = &self.depth_vec[0];
         if prev_depth_0.time.is_zero() {
@@ -122,8 +139,16 @@ impl AvellanedaStoikov {
         let now_spread = (prev_mid_price - self.mid_price).abs();
         if !now_spread.is_zero() {
             self.spread = now_spread;
-            self.spread_vec.push_back(self.spread);
+            self.spread_vec.push(self.spread);
+            self.spread_count_map.insert(self.spread, self.spread_count_map.get(&self.spread).unwrap_or(&0) + 1);
+
+            if self.spread_vec.len() > 100_000 {
+                let pop_value = self.spread_vec.remove(0);
+                self.spread_count_map.insert(pop_value, self.spread_count_map.get(&pop_value).unwrap() - 1);
+            }
+
             self.update_spread_max();
+            self.update_spread_best();
         }
     }
 
@@ -208,7 +233,7 @@ impl AvellanedaStoikov {
     }
 
     pub fn update_sigma_square(&mut self) {
-        self.sigma_square = self.spread_max * dec!(0.2);
+        self.sigma_square = self.spread_best;
         self.sigma_square.rescale(10);
     }
 
@@ -240,10 +265,10 @@ impl AvellanedaStoikov {
             self.ask_delta = self.base_delta;
 
             if self.inventory > Decimal::ZERO {
-                self.ask_delta = self.base_delta * dec!(0.7);
+                self.ask_delta = self.base_delta;
                 // self.ask_delta = Decimal::NEGATIVE_ONE;
             } else if self.inventory < Decimal::ZERO {
-                self.bid_delta = self.base_delta * dec!(0.7);
+                self.bid_delta = self.base_delta;
                 // self.bid_delta = Decimal::NEGATIVE_ONE;
             }
         }
@@ -364,12 +389,12 @@ impl AvellanedaStoikov {
             optimal_bid_price: self.optimal_bid_price,
 
             inventory: self.inventory,
-            sigma_square: self.spread_max,
+            sigma_square: self.sigma_square,
             gamma: self.spread,
             kappa: self.kappa,
 
             flow_ratio: Decimal::ZERO,
-            ref_price: self.ref_price,
+            ref_price: self.fair_price_vec[0],
         });
     }