Pārlūkot izejas kodu

修好了平仓问题。

skyfffire 11 mēneši atpakaļ
vecāks
revīzija
0ab3e1dc3e
2 mainītis faili ar 125 papildinājumiem un 13 dzēšanām
  1. 1 1
      strategy/src/core.rs
  2. 124 12
      strategy/src/strategy.rs

+ 1 - 1
strategy/src/core.rs

@@ -1516,7 +1516,7 @@ impl Core {
             self.strategy.tick_size = self.strategy.tick_size.trunc();
         }
         // 获取最小下单价值
-        self.strategy.min_amount_value = self.market.min_notional * dec!(2);
+        self.strategy.min_amount_value = self.market.min_notional;
 
         if self.strategy.step_size.is_zero() || self.strategy.tick_size.is_zero() || self.strategy.min_amount_value.is_zero() {
             self.exit_msg = format!("交易精度未正常获取 step_size:{}, tick_size:{}, min_amount_value:{}", self.strategy.step_size, self.strategy.tick_size, self.strategy.min_amount_value);

+ 124 - 12
strategy/src/strategy.rs

@@ -91,6 +91,7 @@ pub struct Strategy {
     pub max_short_value: Decimal,                                   // 最大做空持仓
 
     pub open_dist: Vec<Decimal>,                                    // 开仓相关价格
+    pub close_dist: Vec<Decimal>,                                   // 平仓相关价格
 
     pub trade_close_dist: Decimal,                                  //
     pub trade_open_dist: Decimal,                                   //
@@ -183,6 +184,7 @@ impl Strategy {
             max_long_value: Default::default(),
             max_short_value: Default::default(),
             open_dist: vec![],
+            close_dist: vec![],
             trade_close_dist: params.close,
             trade_open_dist: params.open,
             ref_index: 0,
@@ -467,19 +469,27 @@ impl Strategy {
         predictor.optimal_ask_price = utils::fix_price(predictor.optimal_ask_price, self.tick_size);
         predictor.optimal_bid_price = utils::fix_price(predictor.optimal_bid_price, self.tick_size);
 
-        // let delta_ask = predictor.ask_delta.clone();
-        // let delta_bid = predictor.ask_delta.clone();
+        let open = self.trade_open_dist;
+        let close = self.trade_close_dist;
 
-        // 开仓相关
-        let avoid_ask = min(dec!(0.001), predictor.spread_max / predictor.ref_price);
-        let avoid_bid = min(dec!(0.001), predictor.spread_max / predictor.ref_price);
+        // 平仓相关
+        let close_avoid = min(dec!(0.0005), close * dec!(0.5));
+        self.close_dist = vec![
+            predictor.optimal_bid_price * (Decimal::ONE + close_avoid),                   // buy upper
+            predictor.optimal_bid_price * (Decimal::ONE - close_avoid),                   // buy lower
+            predictor.optimal_ask_price * (Decimal::ONE - close_avoid),                   // sell lower
+            predictor.optimal_ask_price * (Decimal::ONE + close_avoid),                   // sell upper
+        ];
+        // debug!(?mp, ?buy_start, ?sell_start, ?avoid, ?close_dist);
 
+        // 开仓相关
+        let open_avoid = min(dec!(0.001), open * dec!(0.1));
         // 用于判断价格是否出界
         self.open_dist = vec![
-            predictor.optimal_bid_price * (Decimal::ONE + avoid_bid),                   // buy upper
-            predictor.optimal_bid_price * (Decimal::ONE - avoid_bid),                   // buy lower
-            predictor.optimal_ask_price * (Decimal::ONE - avoid_ask),                   // sell lower
-            predictor.optimal_ask_price * (Decimal::ONE + avoid_ask),                   // sell upper
+            predictor.optimal_bid_price * (Decimal::ONE + open_avoid),                   // buy upper
+            predictor.optimal_bid_price * (Decimal::ONE - open_avoid),                   // buy lower
+            predictor.optimal_ask_price * (Decimal::ONE - open_avoid),                   // sell lower
+            predictor.optimal_ask_price * (Decimal::ONE + open_avoid),                   // sell upper
         ];
 
         // 修复价格范围
@@ -821,6 +831,107 @@ impl Strategy {
         return diff_time > 30 && diff_time < 3570;
     }
 
+    // 平仓订单处理命令
+    // #[instrument(skip(self, command), level="TRACE")]
+    pub fn _post_close(&self, command: &mut OrderCommand, local_orders: &HashMap<String, OrderInfo>, predictor: &mut AvellanedaStoikov) {
+        // debug!(?command);
+
+        let mut pd_amount = Decimal::ZERO;
+        let mut pd_order_num = 0;
+        let mut pk_amount = Decimal::ZERO;
+        let mut pk_order_num = 0;
+        // 各类价格
+        let long_upper = self.close_dist[0];
+        let long_lower = self.close_dist[1];
+        let short_lower = self.close_dist[2];
+        let short_upper = self.close_dist[3];
+
+        // 获取当前挂单,如果超过挂单范围则取消当前平仓单
+        for order_client_id in local_orders.keys() {
+            let order = local_orders.get(order_client_id).unwrap();
+            let key = format!("Cancel{}", *order_client_id);
+            let value = vec![order.client_id.clone(), order.order_id.clone()];
+
+            if order.side == "pk".to_string() {
+                if self.local_time - order.local_time > 500 || order.price > long_upper || order.price < long_lower {
+                    command.cancel.insert(key.clone(), value.clone());
+                }
+
+                pk_amount += order.amount;
+                pk_order_num += 1;
+            }
+
+            if order.side == "pd".to_string() {
+                if self.local_time - order.local_time > 500 || order.price < short_lower || order.price > short_upper {
+                    command.cancel.insert(key.clone(), value.clone());
+                }
+
+                pd_amount += order.amount;
+                pd_order_num += 1;
+            }
+        }
+        // debug!(?command);
+
+        // // 判断是否需要取消平仓订单
+        // let is_need_cancel_all_close =
+        //     (pd_amount - self.pos.long_pos).abs() * self.mp > self.min_amount_value
+        //     || (pk_amount - self.pos.short_pos).abs() * self.mp > self.min_amount_value;
+        // if is_need_cancel_all_close {
+        //     for order_client_id in local_orders.keys() {
+        //         let order = local_orders.get(order_client_id).unwrap();
+        //
+        //         if order.side == "pk".to_string() || order.side == "pd".to_string() {
+        //             let key = format!("Cancel{}", *order_client_id);
+        //             let value = vec![order.client_id.clone(), order.order_id.clone()];
+        //
+        //             command.cancel.insert(key, value);
+        //         }
+        //     }
+        // }
+        // // debug!(?command);
+
+        if predictor.inventory > Decimal::ZERO {
+            if pd_order_num == 0 {
+                let mut price = (short_lower + short_upper) * dec!(0.5);
+                // 不限制大小
+                // price = utils::clip(price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
+                price = utils::fix_price(price, self.tick_size);
+
+                let order_client_id = utils::generate_client_id(Some(self.broker_id.clone()));
+                let order = vec![
+                    predictor.pos_amount.abs().to_string(),
+                    "pd".to_string(),
+                    price.to_string(),
+                    order_client_id.clone()
+                ];
+
+                command.limits_close.insert(order_client_id, order);
+
+                // debug!(?command);
+            }
+        }
+        if predictor.inventory < Decimal::ZERO {
+            if pk_order_num == 0 {
+                let mut price = (long_upper + long_lower) * dec!(0.5);
+                // 不限制大小
+                // price = utils::clip(price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
+                price = utils::fix_price(price, self.tick_size);
+
+                let order_client_id = utils::generate_client_id(Some(self.broker_id.clone()));
+                let order = vec![
+                    predictor.pos_amount.abs().to_string(),
+                    "pk".to_string(),
+                    price.to_string(),
+                    order_client_id.clone()
+                ];
+
+                command.limits_close.insert(order_client_id, order);
+
+                // debug!(?command);
+            }
+        }
+    }
+
     // 生成取消订单的指令
     // #[instrument(skip(self, command), level="TRACE")]
     pub fn _cancel_open(&self, command: &mut OrderCommand, local_orders: &HashMap<String, OrderInfo>) {
@@ -951,7 +1062,7 @@ impl Strategy {
         // let one_hand_long_value = dec!(0.99) * (self.max_long_value / self.grid);
         // let one_hand_short_value = dec!(0.99) * (self.max_short_value / self.grid);
         // 挂多单
-        if self.post_side >= 0 && buy_value == Decimal::ZERO && predictor.inventory <= Decimal::ZERO {
+        if self.post_side >= 0 && buy_value == Decimal::ZERO && predictor.inventory.is_zero() {
             let mut target_buy_price = predictor.optimal_bid_price;
             // target_buy_price = utils::clip(target_buy_price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
             target_buy_price = utils::fix_price(target_buy_price, self.tick_size);
@@ -994,7 +1105,7 @@ impl Strategy {
             }
         }
         // 挂空单
-        if self.post_side <= 0 && sell_value == Decimal::ZERO && predictor.inventory >= Decimal::ZERO {
+        if self.post_side <= 0 && sell_value == Decimal::ZERO && predictor.inventory.is_zero() {
             let mut target_sell_price = predictor.optimal_ask_price;
             // target_sell_price = utils::clip(target_sell_price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
             // 取消大小限制
@@ -1116,6 +1227,7 @@ impl Strategy {
         self.fix_price(predictor);
 
         self._cancel_open(&mut command, local_orders);              // 撤单命令处理
+        self._post_close(&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
@@ -1123,6 +1235,6 @@ impl Strategy {
         self._refresh_request_limit();                              // 刷新频率限制
         self._update_request_num(&mut command);                     // 统计刷新频率
 
-        return command;
+        command
     }
 }