|
|
@@ -89,6 +89,12 @@ pub struct Predictor {
|
|
|
|
|
|
pub spread: Decimal, // 当前价差
|
|
|
pub spread_ema: Decimal, // 价差的sma,默认是sma5000
|
|
|
+
|
|
|
+ pub orderbook_imbalance: Decimal,
|
|
|
+ pub orderbook_imbalance_ema: Decimal,
|
|
|
+
|
|
|
+ pub volume_series_vec: VecDeque<Decimal>, // 成交量数组
|
|
|
+ pub volume_decay: Decimal, // 成交量衰减
|
|
|
}
|
|
|
|
|
|
impl Predictor {
|
|
|
@@ -223,6 +229,12 @@ impl Predictor {
|
|
|
|
|
|
spread: Default::default(),
|
|
|
spread_ema: Default::default(),
|
|
|
+
|
|
|
+ orderbook_imbalance: Default::default(),
|
|
|
+ orderbook_imbalance_ema: Default::default(),
|
|
|
+
|
|
|
+ volume_series_vec: VecDeque::new(),
|
|
|
+ volume_decay: Default::default(),
|
|
|
};
|
|
|
|
|
|
predictor
|
|
|
@@ -252,9 +264,56 @@ impl Predictor {
|
|
|
self.processor(false).await;
|
|
|
}
|
|
|
|
|
|
- pub async fn on_trade(&mut self, trade: &Trade, _index: usize) {
|
|
|
+ fn calculate_mean_from_iter(iter: impl Iterator<Item = Decimal>) -> Decimal {
|
|
|
+ let (sum, count) = iter.fold((Decimal::ZERO, 0), |(acc_sum, acc_count), val| {
|
|
|
+ (acc_sum + val, acc_count + 1)
|
|
|
+ });
|
|
|
+ if count == 0 {
|
|
|
+ Decimal::ZERO
|
|
|
+ } else {
|
|
|
+ sum / Decimal::from(count)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub async fn on_trade(&mut self, trade: &Trade, index: usize) {
|
|
|
self.last_price = trade.price;
|
|
|
|
|
|
+ // 主要看参考所的
|
|
|
+ if index == 1 {
|
|
|
+ self.volume_series_vec.push_back(trade.value);
|
|
|
+
|
|
|
+ if self.volume_series_vec.len() < 100 {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保 window 不超过队列长度
|
|
|
+ let window = self.volume_series_vec.len() / 2;
|
|
|
+
|
|
|
+ // 计算 current(后一半的均值)
|
|
|
+ let current_iter = self.volume_series_vec.range(self.volume_series_vec.len() - window / 2..).cloned();
|
|
|
+ let current = Self::calculate_mean_from_iter(current_iter);
|
|
|
+
|
|
|
+ // 计算 previous(前一半的均值)
|
|
|
+ let previous_iter = self.volume_series_vec
|
|
|
+ .range(self.volume_series_vec.len() - window..self.volume_series_vec.len() - window / 2)
|
|
|
+ .cloned();
|
|
|
+ let previous = Self::calculate_mean_from_iter(previous_iter);
|
|
|
+
|
|
|
+ self.volume_decay = if current > previous {
|
|
|
+ Decimal::ZERO
|
|
|
+ } else {
|
|
|
+ if self.volume_decay.is_zero() {
|
|
|
+ (previous - current) / previous
|
|
|
+ } else {
|
|
|
+ self.volume_decay * dec!(0.999) + (previous - current) / previous * dec!(0.001)
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ if self.volume_series_vec.len() > 1000 {
|
|
|
+ self.volume_series_vec.pop_front();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// self.processor().await;
|
|
|
}
|
|
|
|
|
|
@@ -449,6 +508,16 @@ impl Predictor {
|
|
|
self.spread_ema * dec!(0.995) + self.spread * dec!(0.005)
|
|
|
};
|
|
|
self.spread_ema.rescale(8);
|
|
|
+
|
|
|
+ // 计算订单簿不平衡
|
|
|
+ let ask_vol: Decimal = depth.asks.iter().map(|order| order.value).sum();
|
|
|
+ let bid_vol: Decimal = depth.bids.iter().map(|order| order.value).sum();
|
|
|
+ self.orderbook_imbalance = (bid_vol - ask_vol) / (bid_vol + ask_vol);
|
|
|
+ self.orderbook_imbalance_ema = if self.orderbook_imbalance_ema.is_zero() {
|
|
|
+ self.orderbook_imbalance
|
|
|
+ } else {
|
|
|
+ self.orderbook_imbalance_ema * dec!(0.9995) + self.orderbook_imbalance * dec!(0.0005)
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
pub async fn update_delta(&mut self) {
|
|
|
@@ -588,9 +657,9 @@ impl Predictor {
|
|
|
let last_price = self.last_price;
|
|
|
let fair_price = Self::DONT_VIEW;
|
|
|
|
|
|
- let spread = self.spread;
|
|
|
- let spread_max = self.spread_ema;
|
|
|
- let spread_min = Self::DONT_VIEW;
|
|
|
+ let spread = self.spread_ema;
|
|
|
+ let spread_max = self.orderbook_imbalance_ema;
|
|
|
+ let spread_min = self.volume_decay;
|
|
|
|
|
|
let optimal_ask_price = self.optimal_ask_price;
|
|
|
let optimal_bid_price = self.optimal_bid_price;
|