浏览代码

这个分支专门做负相关。

skyffire 1 年之前
父节点
当前提交
57b3375c23
共有 5 个文件被更改,包括 265 次插入166 次删除
  1. 242 158
      strategy/src/avellaneda_stoikov.rs
  2. 9 5
      strategy/src/bybit_usdt_swap.rs
  3. 4 0
      strategy/src/core.rs
  4. 8 1
      strategy/src/exchange_disguise.rs
  5. 2 2
      strategy/src/strategy.rs

+ 242 - 158
strategy/src/avellaneda_stoikov.rs

@@ -16,7 +16,10 @@ pub struct AvellanedaStoikov {
     pub depth_vec: FixedTimeRangeDeque<Depth>,                                  // 深度队列
     pub trade_long_vec: FixedTimeRangeDeque<Trade>,                             // 交易队列
     pub trade_short_vec: FixedTimeRangeDeque<Trade>,                            // 交易队列
+    pub open_interest_vec: FixedTimeRangeDeque<Decimal>,                        // OpenInterest队列
+    pub ticker_vec: FixedTimeRangeDeque<Ticker>,                                // Ticker队列
     pub spread_vec: FixedTimeRangeDeque<Decimal>,
+    pub money_flow_vec: FixedTimeRangeDeque<Decimal>,                           // MoneyFlow队列
 
     pub mid_price: Decimal,                                                     // 中间价
     pub ask_price: Decimal,                                                     // 卖一价
@@ -34,15 +37,19 @@ pub struct AvellanedaStoikov {
     pub gamma: Decimal,                                                         // γ,库存风险厌恶参数
     pub kappa: Decimal,                                                         // κ 订单簿 流动性 参数
 
-    pub flow_ratio_long: Decimal,                                               // 资金流比例
-    pub flow_ratio_short: Decimal,                                              // 资金流比例
+    pub open_interest: Decimal,                                                 // 最后持仓量
+    pub open_interest_ema: Decimal,                                             // 持仓量的ema
+    pub open_interest_diff: Decimal,                                            // 持仓量与ema的diff
+    pub money_flow: Decimal,                                                    // 资金流
+    pub money_flow_ema: Decimal,                                                // 资金流ema
+    pub money_flow_diff: Decimal,                                               // 资金流差值
+    pub money_flow_prev_cross: Decimal,                                         // 资金量上次穿越0轴时的价格
+    pub total_cross_diff: Decimal,                                              // 总共的穿越和(理论利润)
 
     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>>,                                // 中控信息
 
@@ -55,7 +62,7 @@ impl AvellanedaStoikov {
     // 时间窗口大小(微秒)
     const MAX_TIME_RANGE_MICROS: i64 = 3 * 60_000_000;
     const TRADE_LONG_RANGE_MICROS: i64 = 3 * 60_000_000;
-    const TRADE_SHORT_RANGE_MICROS: i64 = 20_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);
     const IRA: Decimal = dec!(1);
@@ -66,7 +73,10 @@ impl AvellanedaStoikov {
             depth_vec: FixedTimeRangeDeque::new(Self::MAX_TIME_RANGE_MICROS),
             spread_vec: FixedTimeRangeDeque::new(Self::MAX_TIME_RANGE_MICROS),
             trade_long_vec: FixedTimeRangeDeque::new(Self::TRADE_LONG_RANGE_MICROS),
+            ticker_vec: FixedTimeRangeDeque::new(Self::TRADE_LONG_RANGE_MICROS),
             trade_short_vec: FixedTimeRangeDeque::new(Self::TRADE_SHORT_RANGE_MICROS),
+            open_interest_vec: FixedTimeRangeDeque::new(Self::TRADE_SHORT_RANGE_MICROS),
+            money_flow_vec: FixedTimeRangeDeque::new(Self::TRADE_LONG_RANGE_MICROS),
 
             mid_price: Default::default(),
             ask_price: Default::default(),
@@ -84,20 +94,25 @@ 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(),
             ref_price: Default::default(),
 
             cci_arc,
 
+            money_flow: Default::default(),
+            money_flow_ema: Default::default(),
+            money_flow_diff: Default::default(),
+            money_flow_prev_cross: Default::default(),
+            open_interest: Default::default(),
+            open_interest_ema: Default::default(),
+            open_interest_diff: Default::default(),
+
             is_ready: false,
             prev_trade_time: Utc::now().timestamp_micros(),
             t_diff: Default::default(),
-            flow_ratio_long: Decimal::ONE,
             level: Default::default(),
-            flow_ratio_short: Default::default(),
+            total_cross_diff: Default::default(),
         };
 
         avellaneda_stoikov
@@ -157,12 +172,219 @@ impl AvellanedaStoikov {
         self.processor().await;
     }
 
+    // fn calc_flow_ratio(_prev_flow_ratio: &Decimal, min_volume: &Decimal, trades: &mut FixedTimeRangeDeque<Trade>) -> Decimal {
+    //     let mut flow_in_value = Decimal::ZERO;
+    //     let mut flow_out_value = Decimal::ZERO;
+    //     for trade_iter in trades.deque.iter() {
+    //         if trade_iter.size > Decimal::ZERO {
+    //             flow_in_value += trade_iter.value;
+    //         } else {
+    //             flow_out_value += trade_iter.value;
+    //         }
+    //     }
+    //
+    //     // 使用EMA來更新資金流,確保平滑性
+    //     // let a = Decimal::TWO / dec!(50);
+    //     if flow_out_value + flow_in_value > *min_volume {
+    //         // let now = (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value);
+    //         // a * now + (Decimal::ONE - a) * prev_flow_ratio
+    //         (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value)
+    //     } else {
+    //         Decimal::ZERO
+    //     }
+    // }
+    //
+    // fn calc_flow_ratio_2(_prev_flow_ratio: &Decimal, min_volume: &Decimal, trades: &mut FixedTimeRangeDeque<Trade>) -> Decimal {
+    //     let mut flow_in_value = Decimal::ZERO;
+    //     let mut flow_out_value = Decimal::ZERO;
+    //     for (index, trade_iter) in trades.deque.iter().enumerate() {
+    //         if index == 0 {
+    //             continue
+    //         }
+    //
+    //         let prev_trade_iter = trades.deque.get(index - 1).unwrap();
+    //         let trade = trade_iter;
+    //         if trade.price > prev_trade_iter.price {
+    //             flow_in_value += trade.value;
+    //             // flow_in_value += Decimal::ONE;
+    //         } else if trade.price < prev_trade_iter.price {
+    //             flow_out_value += trade.value;
+    //             // flow_out_value += Decimal::ONE;
+    //         } else {
+    //             if trade.size > Decimal::ZERO {
+    //                 flow_in_value += trade.value;
+    //             } else {
+    //                 flow_out_value += trade.value;
+    //             }
+    //         }
+    //     }
+    //
+    //     // 使用EMA來更新資金流,確保平滑性
+    //     // let a = Decimal::TWO / dec!(50);
+    //     if flow_out_value + flow_in_value > *min_volume {
+    //         // let now = (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value);
+    //         // a * now + (Decimal::ONE - a) * prev_flow_ratio
+    //         (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value)
+    //     } else {
+    //         Decimal::ZERO
+    //     }
+    // }
+
+    // pub fn update_flow_ratio(&mut self) {
+    //     self.flow_ratio_long = Self::calc_flow_ratio_2(&self.flow_ratio_long, &dec!(0), &mut self.trade_long_vec);
+    //     self.flow_ratio_short = Self::calc_flow_ratio(&self.flow_ratio_short, &dec!(0), &mut self.trade_long_vec);
+    // }
+
     pub async fn on_trade(&mut self, trade: &Trade) {
         self.trade_long_vec.push_back(trade.clone());
         self.trade_short_vec.push_back(trade.clone());
 
         self.last_price = trade.price;
         self.update_spread();
+        // self.update_flow_ratio();
+        self.processor().await;
+    }
+
+    pub fn update_money_flow(&mut self) {
+        // ====================== 求最大值,最小值。方便后面进行0-1标准化 =======================
+        let mut max_price_diff = Decimal::MIN;
+        let mut min_price_diff = Decimal::MAX;
+
+        let mut max_open_interest_diff = Decimal::MIN;
+        let mut min_open_interest_diff = Decimal::MAX;
+        for (index, ticker) in self.ticker_vec.deque.iter().enumerate() {
+            if index == 0 {
+                continue
+            }
+
+            let prev_ticker = self.ticker_vec.deque.get(index -  1).unwrap();
+            let price_diff = (ticker.last - prev_ticker.last).abs();
+            let open_interest_diff = (ticker.open_interest - prev_ticker.open_interest).abs();
+
+            max_price_diff = max(max_price_diff, price_diff);
+            min_price_diff = min(min_price_diff, price_diff);
+
+            max_open_interest_diff = max(max_open_interest_diff, open_interest_diff);
+            min_open_interest_diff = min(min_open_interest_diff, open_interest_diff);
+        }
+
+        // ====================== 求资金流 =======================
+        // self.money_flow = Decimal::ZERO;
+        let epsilon = dec!(1e-10);
+        // for (index, ticker) in self.ticker_vec.deque.iter().enumerate() {
+        if self.ticker_vec.len() < 2 {
+            return;
+        }
+
+        // 当前的diff(abs)
+        let ticker = self.ticker_vec.deque.get(self.ticker_vec.len() - 1).unwrap();
+        let prev_ticker = self.ticker_vec.deque.get( self.ticker_vec.len() - 2).unwrap();
+        let price_diff = ticker.last - prev_ticker.last;
+        let price_diff_abs = price_diff.abs();
+        let open_interest_diff = ticker.open_interest - prev_ticker.open_interest;
+        let open_interest_diff_abs = open_interest_diff.abs();
+        let volume_diff = max(ticker.volume - prev_ticker.volume, Decimal::ZERO);
+
+        // 0-1标准化
+        let price_std = if max_price_diff == min_price_diff {
+            Decimal::ZERO
+        } else {
+            (price_diff_abs - min_price_diff) / (max_price_diff - min_price_diff)
+        };
+        let open_interest_std = if max_open_interest_diff == min_open_interest_diff {
+            Decimal::ZERO
+        } else {
+            (open_interest_diff_abs - min_open_interest_diff) / (max_open_interest_diff - min_open_interest_diff)
+        };
+
+        // alpha与beta
+        // 当α>β时,表明价格变动对资金流向的影响更大,此时市场可能处于较强的买入状态,反映出资金流入的趋势。
+        // 当α<β时,持仓量的变动对资金流向影响更大,可能暗示资金的卖出或清算过程。
+        let alpha = (price_std + epsilon) / (price_std + open_interest_std + epsilon + epsilon);
+        let beta =  (open_interest_std + epsilon) / (price_std + open_interest_std + epsilon + epsilon);
+
+        // 求x,为sgn(x)做准备
+        let x = if !price_diff_abs.is_zero() && !open_interest_diff_abs.is_zero() {
+            alpha * price_diff / price_diff_abs + beta * open_interest_diff / open_interest_diff_abs
+        } else if price_diff_abs.is_zero() && open_interest_diff_abs.is_zero() {
+            Decimal::ZERO
+        } else if price_diff_abs.is_zero() && !open_interest_diff_abs.is_zero() {
+            beta * open_interest_diff / open_interest_diff_abs
+        } else {
+            alpha * price_diff / price_diff_abs
+        };
+
+        // 求xgn(x)
+        let sgn_x = if x > Decimal::ZERO {
+            Decimal::ONE
+        } else if x < Decimal::ZERO {
+            Decimal::NEGATIVE_ONE
+        } else {
+            Decimal::ZERO
+        };
+
+        // 当前index的money_flow
+        let money_flow_index = volume_diff * ticker.last * sgn_x;
+        self.money_flow += money_flow_index;
+        self.money_flow_vec.push_back(self.money_flow);
+        if !money_flow_index.is_zero() {
+            self.money_flow_ema = if self.money_flow_ema.is_zero() {
+                self.money_flow
+            } else {
+                dec!(0.01) * self.money_flow + dec!(0.99) * self.money_flow_ema
+            };
+
+            let prev_money_flow_diff = self.money_flow_diff;
+            self.money_flow_diff = self.money_flow - self.money_flow_ema;
+
+            let _0 = Decimal::ZERO;
+            let is_cross = (prev_money_flow_diff > _0 && self.money_flow_diff < _0) || (prev_money_flow_diff < _0 && self.money_flow_diff > _0);
+            if is_cross {
+                if !self.money_flow_prev_cross.is_zero() {
+                    if prev_money_flow_diff > _0 {
+                        self.total_cross_diff += self.mid_price - self.money_flow_prev_cross;
+                    } else {
+                        self.total_cross_diff += self.money_flow_prev_cross - self.mid_price;
+                    }
+                }
+
+                self.money_flow_prev_cross = self.mid_price;
+            }
+        }
+    }
+
+    pub async fn on_ticker(&mut self, ticker: &Ticker) {
+        if self.open_interest_vec.len() > 0 {
+            let diff = ticker.open_interest - self.open_interest_vec.get(0).unwrap();
+            self.open_interest_diff = if diff.is_zero() {
+                self.open_interest_diff
+            } else {
+                if diff > Decimal::ZERO {
+                    Decimal::ONE
+                } else {
+                    Decimal::NEGATIVE_ONE
+                }
+            };
+        }
+        self.open_interest_vec.push_back(ticker.open_interest.clone());
+        self.ticker_vec.push_back(ticker.clone());
+
+        self.last_price = ticker.last;
+        self.ask_price = ticker.sell;
+        self.bid_price = ticker.buy;
+        self.mid_price = (self.ask_price + self.bid_price) / Decimal::TWO;
+        // 持仓量的处理
+        if self.open_interest != ticker.open_interest {
+            self.open_interest = ticker.open_interest;
+            self.open_interest_ema = if self.open_interest_ema.is_zero() {
+                self.open_interest
+            } else {
+                dec!(0.5) * self.open_interest + dec!(0.5) * self.open_interest_ema
+            };
+        }
+        self.open_interest_diff = self.open_interest - self.open_interest_ema;
+
+        self.update_money_flow();
         self.processor().await;
     }
 
@@ -183,7 +405,7 @@ impl AvellanedaStoikov {
     }
 
     pub fn update_sigma_square(&mut self) {
-        self.sigma_square = self.spread_max * dec!(0.5);
+        self.sigma_square = self.spread_max;
         self.sigma_square.rescale(10);
     }
 
@@ -223,15 +445,9 @@ impl AvellanedaStoikov {
 
     pub fn update_delta(&mut self) {
         if self.gamma != Decimal::ZERO {
-            // let pos_edge = if self.inventory.abs() < dec!(5) {
-            //     self.gamma * self.sigma_square * self.inventory.abs().powd(Decimal::TWO) * self.t_diff
-            // } else {
-            //     Decimal::PI * self.gamma * self.sigma_square * self.inventory.abs().powd(Decimal::TWO) * self.t_diff
-            // };
             let pos_edge = self.gamma * self.sigma_square * self.inventory.abs().powd(dec!(2)) * self.t_diff;
 
             self.base_delta = self.gamma * self.sigma_square * self.t_diff / Decimal::TWO + (Decimal::ONE / self.gamma) * (Decimal::ONE + self.gamma / self.kappa).ln();
-            self.ratio_edge = self.flow_ratio_long * self.sigma_square;
 
             self.bid_delta = self.base_delta;
             self.ask_delta = self.base_delta;
@@ -242,16 +458,12 @@ impl AvellanedaStoikov {
                 self.ask_delta += pos_edge;
             }
 
-            if self.ratio_edge > Decimal::ZERO {
-                self.ask_delta = self.ask_delta - self.ratio_edge.abs() * (Decimal::TWO - self.t_diff);
-                self.bid_delta = self.bid_delta + self.ratio_edge.abs() * dec!(16);
-            } else if self.ratio_edge < Decimal::ZERO {
-                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
+            if self.money_flow_diff > Decimal::ZERO {
+                self.ask_delta -= self.base_delta * (Decimal::TWO - self.t_diff);
+                self.bid_delta += self.base_delta;
+            } else if self.money_flow_diff < Decimal::ZERO {
+                self.ask_delta += self.base_delta;
+                self.bid_delta -= self.base_delta * (Decimal::TWO - self.t_diff);
             }
         }
     }
@@ -270,132 +482,6 @@ impl AvellanedaStoikov {
         }
     }
 
-    fn calc_flow_ratio(_prev_flow_ratio: &Decimal, min_volume: &Decimal, trades: &mut FixedTimeRangeDeque<Trade>) -> Decimal {
-        // let mut flow_in_value = Decimal::ZERO;
-        // let mut flow_out_value = Decimal::ZERO;
-        // for (index, trade_iter) in trades.deque.iter().enumerate() {
-        //     if index == 0 {
-        //         continue
-        //     }
-        //
-        //     let prev_trade_iter = trades.deque.get(index - 1).unwrap();
-        //     let trade = trade_iter;
-        //     if trade.price > prev_trade_iter.price {
-        //         flow_in_value += trade.value * (prev_trade_iter.price - trade.price).abs();
-        //         // flow_in_value += Decimal::ONE;
-        //     } else if trade.price < prev_trade_iter.price {
-        //         flow_out_value += trade.value * (prev_trade_iter.price - trade.price).abs();
-        //         // flow_out_value += Decimal::ONE;
-        //     } else {
-        //         // if trade.size > Decimal::ZERO {
-        //         //     flow_in_value += trade.value;
-        //         // } else {
-        //         //     flow_out_value += trade.value;
-        //         // }
-        //     }
-        //
-        //     // if trade_iter.size > Decimal::ZERO {
-        //     //     flow_in_value += trade_iter.value;
-        //     // } else {
-        //     //     flow_out_value += trade_iter.value;
-        //     // }
-        // }
-
-        // if self.trade_vec.deque.len() > 1 {
-        //     let prev_trade_iter = self.trade_vec.deque.get(self.trade_vec.deque.len() - 2).unwrap();
-        //     if trade.price > prev_trade_iter.price {
-        //         self.flow_in_value += trade.value;
-        //     } else if trade.price < prev_trade_iter.price {
-        //         self.flow_out_value += trade.value;
-        //     } else {
-        //         // if trade.size > Decimal::ZERO {
-        //         //     self.flow_in_value += trade.value;
-        //         // } else {
-        //         //     self.flow_out_value += trade.value;
-        //         // }
-        //     }
-        //
-        //     // if trade.size > Decimal::ZERO {
-        //     //     self.flow_in_value += trade.value;
-        //     // } else {
-        //     //     self.flow_out_value += trade.value;
-        //     // }
-        //
-        //     if self.flow_out_value + self.flow_in_value > dec!(2_000_000) {
-        //         self.flow_out_value = self.flow_out_value * dec!(0.618);
-        //         self.flow_in_value = self.flow_in_value * dec!(0.618);
-        //     }
-        // }
-        // else {
-        //     if trade.size > Decimal::ZERO {
-        //         self.flow_in_value += trade.value;
-        //     } else {
-        //         self.flow_out_value += trade.value;
-        //     }
-        // }
-
-        let mut flow_in_value = Decimal::ZERO;
-        let mut flow_out_value = Decimal::ZERO;
-        for trade_iter in trades.deque.iter() {
-            if trade_iter.size > Decimal::ZERO {
-                flow_in_value += trade_iter.value;
-            } else {
-                flow_out_value += trade_iter.value;
-            }
-        }
-
-        // 使用EMA來更新資金流,確保平滑性
-        // let a = Decimal::TWO / dec!(50);
-        if flow_out_value + flow_in_value > *min_volume {
-            // let now = (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value);
-            // a * now + (Decimal::ONE - a) * prev_flow_ratio
-            (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value)
-        } else {
-            Decimal::ZERO
-        }
-    }
-
-    fn calc_flow_ratio_2(_prev_flow_ratio: &Decimal, min_volume: &Decimal, trades: &mut FixedTimeRangeDeque<Trade>) -> Decimal {
-        let mut flow_in_value = Decimal::ZERO;
-        let mut flow_out_value = Decimal::ZERO;
-        for (index, trade_iter) in trades.deque.iter().enumerate() {
-            if index == 0 {
-                continue
-            }
-
-            let prev_trade_iter = trades.deque.get(index - 1).unwrap();
-            let trade = trade_iter;
-            if trade.price > prev_trade_iter.price {
-                flow_in_value += trade.value;
-                // flow_in_value += Decimal::ONE;
-            } else if trade.price < prev_trade_iter.price {
-                flow_out_value += trade.value;
-                // flow_out_value += Decimal::ONE;
-            } else {
-                if trade.size > Decimal::ZERO {
-                    flow_in_value += trade.value;
-                } else {
-                    flow_out_value += trade.value;
-                }
-            }
-        }
-
-        // 使用EMA來更新資金流,確保平滑性
-        // let a = Decimal::TWO / dec!(50);
-        if flow_out_value + flow_in_value > *min_volume {
-            // let now = (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value);
-            // a * now + (Decimal::ONE - a) * prev_flow_ratio
-            (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value)
-        } else {
-            Decimal::ZERO
-        }
-    }
-
-    pub fn update_flow_ratio(&mut self) {
-        self.flow_ratio_long = Self::calc_flow_ratio_2(&self.flow_ratio_long, &dec!(0), &mut self.trade_long_vec);
-        self.flow_ratio_short = Self::calc_flow_ratio(&self.flow_ratio_short, &dec!(0), &mut self.trade_long_vec);
-    }
-
     pub fn check_ready(&mut self) {
         if self.is_ready {
             return;
@@ -437,8 +523,6 @@ impl AvellanedaStoikov {
     async fn processor(&mut self) {
         self.update_t_diff();
         // info!(?self.t_diff);
-        self.update_flow_ratio();
-        // info!(?self.flow_ratio_long);
         self.update_sigma_square();
         // info!(?self.sigma_square);
         self.update_gamma();
@@ -472,11 +556,11 @@ impl AvellanedaStoikov {
             optimal_bid_price: self.optimal_bid_price,
 
             inventory: self.inventory,
-            sigma_square: self.flow_ratio_long,
-            gamma: self.flow_ratio_short,
-            kappa: self.t_diff,
+            sigma_square: self.open_interest,
+            gamma: self.money_flow_diff,
+            kappa: self.total_cross_diff,
 
-            flow_ratio: self.flow_ratio_long,
+            flow_ratio: self.money_flow,
             ref_price: self.ref_price,
         });
     }

+ 9 - 5
strategy/src/bybit_usdt_swap.rs

@@ -13,7 +13,7 @@ use standard::exchange::ExchangeEnum::BybitSwap;
 use standard::exchange_struct_handler::ExchangeStructHandler;
 use standard::{Depth, OrderBook};
 use crate::core::Core;
-use crate::exchange_disguise::{on_depth, on_trade};
+use crate::exchange_disguise::{on_depth, on_ticker, on_trade};
 use crate::model::OrderInfo;
 
 // 参考 Bybit 合约 启动
@@ -29,12 +29,13 @@ pub(crate) async fn reference_bybit_swap_run(is_shutdown_arc: Arc<AtomicBool>,
         ws.set_subscribe(vec![
             BybitSwapSubscribeType::PuOrderBook1,
             BybitSwapSubscribeType::PuTrade,
-            // BybitSwapSubscribeType::PuTickers
+            BybitSwapSubscribeType::PuTickers
         ]);
 
         // 读取数据
         let core_arc_clone = Arc::clone(&core_arc);
-        let multiplier = core_arc_clone.lock().await.platform_rest.get_self_market().multiplier;
+        let rest = core_arc_clone.lock().await.platform_rest.clone_box();
+        let multiplier = rest.get_self_market().multiplier;
         let depth_asks = Arc::new(Mutex::new(Vec::new()));
         let depth_bids = Arc::new(Mutex::new(Vec::new()));
 
@@ -160,8 +161,11 @@ async fn on_public_data(core_arc: Arc<Mutex<Core>>, mul: &Decimal, response: &Re
             }
         }
         "tickers" => {
-            // let ticker = ExchangeStructHandler::ticker_handle(BybitSwap, response).await;
-            // info!(?ticker)
+            trace_stack.set_source("bybit_usdt_swap.tickers".to_string());
+            let ticker = ExchangeStructHandler::ticker_handle(BybitSwap, response).await;
+            trace_stack.on_after_format();
+
+            on_ticker(core_arc, &mut trace_stack, &ticker).await;
         }
         _ => {
             error!("未知推送类型");

+ 4 - 0
strategy/src/core.rs

@@ -612,6 +612,10 @@ impl Core {
         self.avellaneda_stoikov.on_trade(trade).await;
     }
 
+    pub async fn on_ticker(&mut self, ticker: &Ticker, _trace_stack: &mut TraceStack) {
+        self.avellaneda_stoikov.on_ticker(ticker).await;
+    }
+
     // #[instrument(skip(self, depth, name_ref, trace_stack), level="TRACE")]
     pub async fn on_depth(&mut self, depth: &Depth, name_ref: &String, trace_stack: &mut TraceStack) {
         // ================================ 刷新更新间隔 =========================================

+ 8 - 1
strategy/src/exchange_disguise.rs

@@ -3,7 +3,7 @@ use std::sync::Arc;
 use std::sync::atomic::AtomicBool;
 use tokio::sync::Mutex;
 use global::trace_stack::TraceStack;
-use standard::{Depth, Trade};
+use standard::{Depth, Ticker, Trade};
 use crate::binance_usdt_swap::{binance_swap_run, reference_binance_swap_run};
 use crate::bybit_usdt_swap::{bybit_swap_run, reference_bybit_swap_run};
 use crate::coinex_usdt_swap::coinex_swap_run;
@@ -137,6 +137,13 @@ pub async fn on_trade(core_arc: Arc<Mutex<Core>>, label: &String, trace_stack: &
     core.on_trade(trade, &label, trace_stack).await;
 }
 
+pub async fn on_ticker(core_arc: Arc<Mutex<Core>>, trace_stack: &mut TraceStack, ticker: &Ticker) {
+    let mut core = core_arc.lock().await;
+    trace_stack.on_after_unlock_core();
+
+    core.on_ticker(ticker, trace_stack).await;
+}
+
 pub async fn on_order() {}
 
 pub async fn on_position() {}

+ 2 - 2
strategy/src/strategy.rs

@@ -1053,7 +1053,7 @@ impl Strategy {
         info!("预热中");
     }
 
-    // 在满足条件后,返回非空command,否则返回一个空的command
+    // 在满足条件后,返回非空command,否则返回一个空的command
     pub fn on_tick(&mut self,
                    _local_orders: &HashMap<String, OrderInfo>,
                    local_position: &LocalPosition,
@@ -1110,7 +1110,7 @@ impl Strategy {
         }
 
         self._cancel_open(&mut command, local_orders);              // 撤单命令处理
-        self._post_open(&mut command, local_orders, predictor);     // 限价单命令处理
+        // self._post_open(&mut command, local_orders, predictor);     // 限价单命令处理
         self._check_local_orders(&mut command, local_orders);       // 固定时间检查超时订单
         self._update_in_cancel(&mut command, local_orders);         // 更新撤单队列,是一个filter
         self._check_request_limit(&mut command);                    // 限制频率,移除不合规则之订单,是一个filter