Selaa lähdekoodia

coinex 虚拟仓位计算

JiahengHe 1 vuosi sitten
vanhempi
commit
56afceb939
4 muutettua tiedostoa jossa 123 lisäystä ja 55 poistoa
  1. 2 0
      standard/src/coinex_swap.rs
  2. 116 50
      strategy/src/coinex_usdt_swap.rs
  3. 3 3
      strategy/src/core.rs
  4. 2 2
      strategy/src/strategy.rs

+ 2 - 0
standard/src/coinex_swap.rs

@@ -607,10 +607,12 @@ impl Platform for CoinexSwap {
                         // self_clone.order_sender.send(order).await.unwrap();
                     }
                     Err(error) => {
+                        // info!("撤单失败:{:?}", error.to_string());
                         // 取消失败去查订单。
                         let query_rst = self_clone.get_order_detail(&order_id, &custom_id).await;
                         match query_rst {
                             Ok(order) => {
+                                // info!("查单 订单详情:{:?}", order);
                                 self_clone.order_sender.send(order).await.unwrap();
                             }
                             Err(err) => {

+ 116 - 50
strategy/src/coinex_usdt_swap.rs

@@ -13,6 +13,7 @@ use standard::{Position, PositionModeEnum};
 use crate::model::{OrderInfo};
 use crate::core::Core;
 use crate::exchange_disguise::on_special_depth;
+use crate::utils::generate_client_id;
 
 // 1交易、0参考 coinex 合约 启动
 pub async fn coinex_swap_run(is_shutdown_arc: Arc<AtomicBool>,
@@ -99,7 +100,7 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
         }
         "order.update" => {
             trace_stack.set_source("coinex_swap.orders".to_string());
-            // info!("coinex_usdt_swap 订单推送:{:?}", response);
+            info!("coinex_usdt_swap 订单推送:{:?}", response);
             let orders = standard::handle_info::HandleSwapInfo::handle_order(CoinexSwap, response.clone(), multiplier.clone());
             let mut order_infos:Vec<OrderInfo> = Vec::new();
             for mut order in orders.order {
@@ -112,61 +113,126 @@ async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
                 order_infos.push(order_info);
             }
 
-            if !order_infos.is_empty(){
-                let mut core = core_arc_clone.lock().await;
-                core.update_order(order_infos, trace_stack).await;
+            if order_infos.is_empty() {
+                return
             }
-        }
-        "position.update" => {
-            info!("coinex_usdt_swap 仓位推送:{:?}", response.data);
-            let positions = standard::handle_info::HandleSwapInfo::handle_position(CoinexSwap, &response, multiplier);
+            let mut new_order = order_infos[0].clone();
             let mut core = core_arc_clone.lock().await;
+            // 本地订单缓存判断
+            if !core.local_orders_backup.contains_key(&new_order.client_id) {
+                return
+            }
+
+            // 获取订单目的
+            let mut rst = vec![];
+            let side = core.local_orders_backup.get(&new_order.client_id).unwrap().side.as_str();
             let local_position_by_orders = &core.local_position_by_orders;
-            let position = positions[0].clone();
-            let mut result_position = vec![];
-            info!("本地仓位推算:{:?}", local_position_by_orders);
-            let position_num = (local_position_by_orders.long_pos - local_position_by_orders.short_pos).abs();
-            let mut long_pos = Position::new();
-            let mut short_pos = Position::new();
-            if position_num == position.amount {
-                long_pos.amount = local_position_by_orders.long_pos;
-                long_pos.price = position.price;
-                long_pos.position_mode = PositionModeEnum::Long;
-                short_pos.amount = local_position_by_orders.short_pos;
-                short_pos.price = local_position_by_orders.short_avg;
-                short_pos.position_mode = PositionModeEnum::Short;
-            } else {
-                match position.position_mode {
-                    PositionModeEnum::Long => {
-                        long_pos.amount = position.amount + local_position_by_orders.short_pos;
-                        long_pos.price = position.price;
-                        long_pos.position_mode = PositionModeEnum::Long;
-                        short_pos.amount = local_position_by_orders.short_pos;
-                        short_pos.price = local_position_by_orders.short_avg;
-                        short_pos.position_mode = PositionModeEnum::Short;
-                    },
-                    PositionModeEnum::Short => {
-                        short_pos.amount = position.amount + local_position_by_orders.long_pos;
-                        short_pos.price = position.price;
-                        short_pos.position_mode = PositionModeEnum::Short;
-                        long_pos.amount = local_position_by_orders.long_pos;
-                        long_pos.price = local_position_by_orders.long_avg;
-                        long_pos.position_mode = PositionModeEnum::Long;
-                    },
-                    _ => {
-                        error!("coinex_usdt_swap 仓位推送错误:{:?}", response.data);
-                        short_pos.amount = Decimal::ZERO;
-                        short_pos.price = Decimal::ZERO;
-                        short_pos.position_mode = PositionModeEnum::Short;
-                        long_pos.amount = Decimal::ZERO;
-                        long_pos.price = Decimal::ZERO;
-                        long_pos.position_mode = PositionModeEnum::Long;
+            let long_pos = local_position_by_orders.long_pos;
+            let short_pos = local_position_by_orders.short_pos;
+
+            // 部分成交和新订单的处理,不用走下面的逻辑
+            if new_order.status != "REMOVE" || new_order.filled == Decimal::ZERO {
+                core.update_order(order_infos, trace_stack).await;
+                return
+            }
+
+            // 单向持仓的处理
+            match side {
+                "kd" => {
+                    if short_pos != Decimal::ZERO {
+                        let mut vir_order_filled = Decimal::ZERO;
+                        if short_pos >= new_order.amount {
+                            vir_order_filled = new_order.amount;
+                        } else {
+                            vir_order_filled = short_pos
+                        }
+                        // 构造虚拟订单
+                        let vir_client_id = format!("{}vir", new_order.client_id.clone());
+                        let vir_order = OrderInfo {
+                            symbol: "".to_string(),
+                            amount: vir_order_filled,
+                            side: "pk".to_string(),
+                            price: new_order.price,
+                            client_id: vir_client_id.clone(),
+                            filled_price: new_order.price,
+                            filled: vir_order_filled,
+                            order_id: "".to_string(),
+                            local_time: 0,
+                            create_time: 0,
+                            status: new_order.status.clone(),
+                            fee: Default::default(),
+                            trace_stack: trace_stack.clone(),
+                        };
+                        core.local_orders_backup.insert(vir_client_id.clone(), vir_order.clone());
+
+                        // 原始订单处理
+                        new_order.amount -= vir_order_filled;
+                        new_order.filled -= vir_order_filled;
+
+                        rst.push(vir_order.clone());
+                        if new_order.amount > Decimal::ZERO {
+                            rst.push(new_order.clone());
+                        } else {
+                            core.local_cancel_log.remove(&new_order.client_id);
+                            core.local_orders_backup.remove(&new_order.client_id);
+                        }
+                    } else {
+                        rst.push(new_order.clone());
+                    }
+                }
+                "kk" => {
+                    if long_pos != Decimal::ZERO {
+                        let mut vir_order_filled = Decimal::ZERO;
+                        if long_pos >= new_order.amount {
+                            vir_order_filled = new_order.amount;
+                        } else {
+                            vir_order_filled = long_pos
+                        }
+                        // 构造虚拟订单
+                        let vir_client_id = format!("{}vir", new_order.client_id.clone());
+                        let vir_order = OrderInfo {
+                            symbol: "".to_string(),
+                            amount: vir_order_filled,
+                            side: "pd".to_string(),
+                            price: new_order.price,
+                            client_id: vir_client_id.clone(),
+                            filled_price: new_order.price,
+                            filled: vir_order_filled,
+                            order_id: "".to_string(),
+                            local_time: 0,
+                            create_time: 0,
+                            status: new_order.status.clone(),
+                            fee: Default::default(),
+                            trace_stack: trace_stack.clone(),
+                        };
+                        core.local_orders_backup.insert(vir_client_id.clone(), vir_order.clone());
+
+                        // 原始订单处理
+                        new_order.amount -= vir_order_filled;
+                        new_order.filled -= vir_order_filled;
+
+                        rst.push(vir_order.clone());
+                        if new_order.amount > Decimal::ZERO {
+                            rst.push(new_order.clone());
+                        } else {
+                            core.local_cancel_log.remove(&new_order.client_id);
+                            core.local_orders_backup.remove(&new_order.client_id);
+                        }
+                    } else {
+                        rst.push(new_order.clone());
                     }
                 }
+                &_ => {}
             }
-            result_position.push(long_pos);
-            result_position.push(short_pos);
-            core.update_position(result_position).await;
+
+            core.update_order(rst, trace_stack).await;
+        }
+        "position.update" => {
+            // info!("coinex_usdt_swap 仓位推送:{:?}", response.data);
+            let positions = standard::handle_info::HandleSwapInfo::handle_position(CoinexSwap, &response, multiplier);
+            let mut core = core_arc_clone.lock().await;
+
+            core.update_position(positions).await;
         }
         "deals.update" => {
             // let mut core = core_arc_clone.lock().await;

+ 3 - 3
strategy/src/core.rs

@@ -1052,11 +1052,11 @@ impl Core {
             }
         }
 
-        // 持仓均价异常风控
+        // 持仓均价异常风控(浮盈风控)
         if self.strategy.long_pos_bias != Decimal::ZERO {
             if self.strategy.long_hold_value > Decimal::TWO * self.strategy._min_amount_value {
                 if self.strategy.long_pos_bias > dec!(4) || self.strategy.long_pos_bias < -Decimal::TWO {
-                    let exit_msg = format!("{} long_pos_bias: {},持仓均价异常,退出。", self.params.account_name, self.strategy.long_pos_bias);
+                    let exit_msg = format!("{} long_pos_bias: {},持仓均价异常(mp: {}, avg: {}),退出。", self.params.account_name, self.strategy.long_pos_bias, self.strategy.mp, self.strategy.pos.long_avg);
                     warn!(exit_msg);
                     self.exit_msg = exit_msg;
                     self.stop().await;
@@ -1066,7 +1066,7 @@ impl Core {
         if self.strategy.short_pos_bias != Decimal::ZERO {
             if self.strategy.short_hold_value > Decimal::TWO * self.strategy._min_amount_value {
                 if self.strategy.short_pos_bias > dec!(4) || self.strategy.short_pos_bias < -Decimal::TWO {
-                    let exit_msg = format!("{} short_pos_bias: {},持仓均价异常,退出。", self.params.account_name, self.strategy.short_pos_bias);
+                    let exit_msg = format!("{} short_pos_bias: {},持仓均价异常(mp: {}, avg: {}),退出。", self.params.account_name, self.strategy.short_pos_bias, self.strategy.mp, self.strategy.pos.short_avg);
                     warn!(exit_msg);
                     self.exit_msg = exit_msg;
                     self.stop().await;

+ 2 - 2
strategy/src/strategy.rs

@@ -85,8 +85,8 @@ pub struct Strategy {
     pub adjust_lever_rate: Decimal,                                 // 原文的adjust_leverrate
     pub lever_rate: Decimal,                                        // 原文的leverrate
 
-    pub long_pos_bias: Decimal,                                     //
-    pub short_pos_bias: Decimal,                                    //
+    pub long_pos_bias: Decimal,                                     // 做多浮盈
+    pub short_pos_bias: Decimal,                                    // 做空浮盈
     pub long_hold_rate: Decimal,                                    //
     pub short_hold_rate: Decimal,                                   //
     pub max_long_value: Decimal,                                    // 最大做多持仓