From 7491d19c0412712080f23c389eb2f1bfa2924e09 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 19 May 2026 11:37:10 +0800
Subject: [PATCH] ``` fix(gate): 修复网格交易中订单状态更新处理逻辑

---
 src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java |  125 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 124 insertions(+), 1 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
index 4705633..a1ecfc3 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -600,6 +600,125 @@
         }
     }
 
+    /**
+     * 用户私有成交回调。由 {@link com.xcong.excoin.modules.gateApi.wsHandler.handler.UserTradesChannelHandler}
+     * 在收到 {@code futures.usertrades} 推送时调用。
+     *
+     * @param contract 合约名称
+     * @param orderId  订单 ID
+     * @param price    成交价格
+     * @param size     成交数量
+     * @param role     用户角色(maker / taker)
+     * @param fee      手续费
+     */
+    public void onUserTrade(String contract, String orderId, BigDecimal price, String size, String role, BigDecimal fee) {
+        if (state == StrategyState.STOPPED) {
+            return;
+        }
+        log.info("[Gate] 成交明细, 合约:{}, 订单ID:{}, 价格:{}, 数量:{}, 角色:{}, 手续费:{}",
+                contract, orderId, price, size, role, fee);
+    }
+
+    /**
+     * 自动订单(条件单)状态变更回调。
+     * 由 {@link com.xcong.excoin.modules.gateApi.wsHandler.handler.AutoOrdersChannelHandler}
+     * 在收到 {@code futures.autoorders} 推送时调用。
+     *
+     * @param orderId   条件单 ID
+     * @param status    订单状态(open / finished / cancelled)
+     * @param reason    变更原因
+     * @param orderType 订单类型(plan-close-long-position 等)
+     */
+    public void onAutoOrder(String orderId, String status, String reason, String orderType) {
+        if (state == StrategyState.STOPPED) {
+            return;
+        }
+        log.info("[Gate] 条件单状态变更, id:{}, status:{}, reason:{}, order_type:{}",
+                orderId, status, reason, orderType);
+        if (!"finished".equals(status)) {
+            return;
+        }
+
+        /**
+         * 匹配止盈单止盈
+         */
+        GridElement byLongTakeProfitOrderId = GridElement.findByLongTakeProfitOrderId(orderId);
+        if (byLongTakeProfitOrderId != null){
+            longTakeProfitTraderIdParam(
+                    byLongTakeProfitOrderId,
+                    null,
+                    false
+            );
+            longEntryTraderIdParam(
+                    byLongTakeProfitOrderId,
+                    null,
+                    false
+            );
+        }
+        GridElement byShortTakeProfitOrderId = GridElement.findByShortTakeProfitOrderId(orderId);
+        if (byShortTakeProfitOrderId != null){
+            shortTakeProfitTraderIdParam(
+                    byShortTakeProfitOrderId,
+                    null,
+                    false
+            );
+            shortEntryTraderIdParam(
+                    byShortTakeProfitOrderId,
+                    null,
+                    false
+            );
+        }
+
+        /**
+         * 匹配挂单
+         */
+        GridElement longGridElement = GridElement.findByLongOrderId(orderId);
+        if (longGridElement != null) {
+            if (longGridElement.isHasLongOrder()){
+                if (longGridElement.getLongTakeProfitOrderId() == null){
+                    BigDecimal longTp = longGridElement.getLongTraderParam().getTakeProfitPrice();
+                    if (longTp != null) {
+                        executor.placeTakeProfit(longTp,
+                                FuturesPriceTrigger.RuleEnum.NUMBER_1,
+                                ORDER_TYPE_CLOSE_LONG,
+                                negate(config.getQuantity()),
+                                (profitId) -> {
+                                    longTakeProfitTraderIdParam(
+                                            longGridElement,
+                                            profitId,
+                                            true
+                                    );
+                                });
+                        log.info("[Gate] 多单成交匹配止盈, orderId:{}, 止盈价:{}, size:{}", orderId, longTp, negate(config.getQuantity()));
+                        return;
+                    }
+                }
+            }
+        }
+        GridElement shortGridElement = GridElement.findByShortOrderId(orderId);
+        if (shortGridElement != null) {
+            if (shortGridElement.isHasShortOrder()){
+                if (shortGridElement.getShortTakeProfitOrderId() == null){
+                    BigDecimal shortTp = shortGridElement.getShortTraderParam().getTakeProfitPrice();
+                    if (shortTp != null) {
+                        executor.placeTakeProfit(shortTp,
+                                FuturesPriceTrigger.RuleEnum.NUMBER_2,
+                                ORDER_TYPE_CLOSE_SHORT,
+                                config.getQuantity(),
+                                (profitId) -> {
+                                    shortTakeProfitTraderIdParam(
+                                            shortGridElement,
+                                            profitId,
+                                            true
+                                    );
+                                });
+                        log.info("[Gate] 空单成交匹配止盈, orderId:{}, 止盈价:{}, size:{}", orderId, shortTp, config.getQuantity());
+                    }
+                }
+            }
+        }
+    }
+
     // ---- 网格队列处理 ----
 
     /**
@@ -631,6 +750,7 @@
             GridElement baseGridElement = GridElement.findById(0);
             TraderParam baseLongTraderParam = config.getBaseLongTraderParam();
             baseGridElement.setLongOrderId(baseLongTraderParam.getEntryOrderId());
+            baseGridElement.setHasLongOrder(true);
             //0位置的网格的多单止盈
             BigDecimal upTakeProfitPrice = baseGridElement.getLongTraderParam().getTakeProfitPrice();
             executor.placeTakeProfit(
@@ -649,6 +769,7 @@
             //0位置的网格的空单止盈
             TraderParam baseShortTraderParam = config.getBaseShortTraderParam();
             baseGridElement.setShortOrderId(baseShortTraderParam.getEntryOrderId());
+            baseGridElement.setHasShortOrder(true);
             BigDecimal downTakeProfitPrice = baseGridElement.getShortTraderParam().getTakeProfitPrice();
             executor.placeTakeProfit(
                     downTakeProfitPrice,
@@ -1008,7 +1129,7 @@
             if (downGridElement != null){
 
                 TraderParam downLongTraderParam = downGridElement.getLongTraderParam();
-                if (!downGridElement.isHasShortOrder()){
+                if (!downGridElement.isHasLongOrder()){
                     executor.placeConditionalEntryOrder(
                             downLongTraderParam.getEntryPrice(),
                             FuturesPriceTrigger.RuleEnum.NUMBER_1,
@@ -1029,6 +1150,7 @@
                 BigDecimal downGridPrice = downGridElement.getGridPrice();
                 if (
                         !downGridElement.isHasShortOrder() &&
+                                downGridPrice.compareTo(currentPrice) < 0 &&
                                 downGridPrice.compareTo(longEntryPrice) <= 0 &&
                                 downGridPrice.compareTo(shortEntryPrice) >= 0
                 ){
@@ -1190,6 +1312,7 @@
                 BigDecimal downGridPrice = downGridElement.getGridPrice();
                 if (
                         !downGridElement.isHasLongOrder() &&
+                                downGridPrice.compareTo(currentPrice) > 0 &&
                                 downGridPrice.compareTo(longEntryPrice) <= 0 &&
                                 downGridPrice.compareTo(shortEntryPrice) >= 0
                 ){

--
Gitblit v1.9.1