From dac84cb80a0dfe39d87ec88abbc4ad3bac8ec309 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Mon, 15 Jun 2026 14:14:55 +0800
Subject: [PATCH] refactor(gateApi): 优化网格交易服务中的止损逻辑和订单处理

---
 src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java |  173 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 137 insertions(+), 36 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 6e79f5e..dec4977 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -606,9 +606,8 @@
         GridElement shortGridElement = GridElement.findByShortOrderId(orderId);
         if (shortGridElement != null) {
             if (shortGridElement.isHasShortOrder() && StrUtil.isNotEmpty(tradeId) && !tradeId.equals("0") ){
+                int filledQty = Integer.parseInt(shortGridElement.getShortTraderParam().getQuantity());
                 shortEntryTraderIdParam(shortGridElement, null, false);
-
-                int filledQty = shortGridElement.getId();
                 extendShortStopLoss(filledQty);
                 log.info("[Gate] 空单成交 gridId:{}", filledQty);
             }
@@ -616,9 +615,9 @@
         GridElement longGridElement = GridElement.findByLongOrderId(orderId);
         if (longGridElement != null) {
             if (longGridElement.isHasLongOrder() && StrUtil.isNotEmpty(tradeId) && !tradeId.equals("0")){
-                longEntryTraderIdParam(longGridElement, null, false);
 
-                int filledQty = longGridElement.getId();
+                int filledQty = Integer.parseInt(longGridElement.getLongTraderParam().getQuantity());
+                longEntryTraderIdParam(longGridElement, null, false);
                 extendLongStopLoss(filledQty);
                 log.info("[Gate] 多单成交 gridId:{}", filledQty);
             }
@@ -653,39 +652,84 @@
             baseGridElement.setShortOrderId(baseShortTraderParam.getEntryOrderId());
             baseGridElement.setHasShortOrder(true);
 
-            int shortTime = 2;
-            GridElement elemShort = GridElement.findById(shortTime);
-            if (elemShort != null) {
-                BigDecimal triggerPrice = elemShort.getGridPrice();
-                String size = config.getBaseQuantity();
+//            int shortTime = 2;
+//            GridElement elemShort = GridElement.findById(shortTime);
+//            if (elemShort != null) {
+//                BigDecimal triggerPrice = elemShort.getGridPrice();
+//                String size = config.getBaseQuantity();
+//                executor.placeTakeProfit(
+//                        triggerPrice,
+//                        FuturesPriceTrigger.RuleEnum.NUMBER_1,
+//                        ORDER_TYPE_CLOSE_SHORT,
+//                        size,
+//                        profitId -> {
+//                            elemShort.setShortStopLossOrderId(profitId);
+//                            GridElement.refreshIndices();
+//                            log.info("[Gate] 空仓止损已挂, gridId:{}, 触发价:{}, stopLossId:{}", shortTime, triggerPrice, profitId);
+//                        }
+//                );
+//            }
+//
+//
+//            int longTime = -2;
+//            GridElement elemLong = GridElement.findById(longTime);
+//            if (elemLong != null) {
+//                BigDecimal triggerPrice = elemLong.getGridPrice();
+//                String size = config.getBaseQuantity();
+//                executor.placeTakeProfit(
+//                        triggerPrice,
+//                        FuturesPriceTrigger.RuleEnum.NUMBER_2,
+//                        ORDER_TYPE_CLOSE_LONG,
+//                        negate(size),
+//                        profitId -> {
+//                            elemLong.setLongStopLossOrderId(profitId);
+//                            GridElement.refreshIndices();
+//                            log.info("[Gate] 多仓止损已挂, gridId:{}, 触发价:{}, stopLossId:{}", longTime, triggerPrice, profitId);
+//                        }
+//                );
+//            }
+
+            int shortTime = Integer.parseInt(config.getBaseQuantity()) + 1;
+            for (int id = 2; id <= shortTime; id++) {
+                GridElement elem = GridElement.findById(id);
+                if (elem == null) {
+                    continue;
+                }
+                BigDecimal triggerPrice = elem.getGridPrice();
+                String size = config.getQuantity();
+                int finalId = id;
                 executor.placeTakeProfit(
                         triggerPrice,
                         FuturesPriceTrigger.RuleEnum.NUMBER_1,
                         ORDER_TYPE_CLOSE_SHORT,
                         size,
                         profitId -> {
-                            elemShort.setShortStopLossOrderId(profitId);
+                            elem.setShortStopLossOrderId(profitId);
                             GridElement.refreshIndices();
-                            log.info("[Gate] 空仓止损已挂, gridId:{}, 触发价:{}, stopLossId:{}", shortTime, triggerPrice, profitId);
+                            log.info("[Gate] 空仓止损已挂, gridId:{}, 触发价:{}, stopLossId:{}", finalId, triggerPrice, profitId);
                         }
                 );
             }
 
 
-            int longTime = -2;
-            GridElement elemLong = GridElement.findById(longTime);
-            if (elemLong != null) {
-                BigDecimal triggerPrice = elemLong.getGridPrice();
-                String size = config.getBaseQuantity();
+            int longTime = Integer.parseInt(config.getBaseQuantity()) + 1;
+            for (int id = -2; id >= -longTime; id--) {
+                GridElement elem = GridElement.findById(id);
+                if (elem == null) {
+                    continue;
+                }
+                BigDecimal triggerPrice = elem.getGridPrice();
+                String size = config.getQuantity();
+                int finalId = id;
                 executor.placeTakeProfit(
                         triggerPrice,
                         FuturesPriceTrigger.RuleEnum.NUMBER_2,
                         ORDER_TYPE_CLOSE_LONG,
                         negate(size),
                         profitId -> {
-                            elemLong.setLongStopLossOrderId(profitId);
+                            elem.setLongStopLossOrderId(profitId);
                             GridElement.refreshIndices();
-                            log.info("[Gate] 多仓止损已挂, gridId:{}, 触发价:{}, stopLossId:{}", longTime, triggerPrice, profitId);
+                            log.info("[Gate] 多仓止损已挂, gridId:{}, 触发价:{}, stopLossId:{}", finalId, triggerPrice, profitId);
                         }
                 );
             }
@@ -811,7 +855,8 @@
         //根据精度转换成小数
         int prec = config.getPriceScale();
         BigDecimal step = config.getStep();
-        String qty = config.getBaseQuantity();
+//        String qty = config.getBaseQuantity();
+        String qty = config.getQuantity();
 
         // 空仓队列:id 从 -1 自减, shortPriceQueue[i] → id=-(i+1)
         for (int i = 0; i < shortSize; i++) {
@@ -1012,11 +1057,29 @@
         }
 
         BigDecimal triggerPrice = newEntryGrid.getGridPrice();
-        String size = config.getBaseQuantity();
-        log.info("[Gate] 多仓止损触发 gridId:{}, 在gridId:{}挂{}基础张多单=",
+
+        BigDecimal baseQuantity = new BigDecimal(config.getBaseQuantity());
+        BigDecimal subtract = baseQuantity.subtract(longPositionSize);
+        String size = new BigDecimal(config.getQuantity()).add(new BigDecimal("1")).toString();
+        if (subtract.compareTo(BigDecimal.ZERO) >=0){
+            size = subtract.add(new BigDecimal("1")).toString();
+        }
+        log.info("[Gate] 多仓止损触发 gridId:{}, 在gridId:{}挂{}基础张多单",
                 gridId, newEntryGridId, size);
+
+        newEntryGrid.getLongTraderParam().setQuantity(size);
         placeEntryOrderWithPreFlag(newEntryGrid, true, triggerPrice,
                 FuturesPriceTrigger.RuleEnum.NUMBER_1, size);
+
+
+        int cancelGridId = gridId + 2;
+        GridElement cancelGrid = GridElement.findById(cancelGridId);
+        if (cancelGrid != null && cancelGrid.isHasLongOrder()) {
+            executor.cancelConditionalOrder(cancelGrid.getLongOrderId(), oid -> {
+                longEntryTraderIdParam(cancelGrid, null, false);
+                log.info("[Gate] 多仓止损触发, 取消gridId:{}的多单", cancelGridId);
+            });
+        }
     }
 
     private void handleShortStopLossTriggered(GridElement gridElement) {
@@ -1034,27 +1097,54 @@
         }
 
         BigDecimal triggerPrice = newEntryGrid.getGridPrice();
-        String size =config.getBaseQuantity();
+
+        BigDecimal baseQuantity = new BigDecimal(config.getBaseQuantity());
+        BigDecimal subtract = baseQuantity.subtract(longPositionSize);
+        String size = new BigDecimal(config.getQuantity()).add(new BigDecimal("1")).toString();
+        if (subtract.compareTo(BigDecimal.ZERO) >=0){
+            size = subtract.add(new BigDecimal("1")).toString();
+        }
         log.info("[Gate] 空仓止损触发 gridId:{}, 在gridId:{}挂{}基础张空单",
                 gridId, newEntryGridId, size);
         newEntryGrid.getShortTraderParam().setQuantity(size);
         placeEntryOrderWithPreFlag(newEntryGrid, false, triggerPrice,
                 FuturesPriceTrigger.RuleEnum.NUMBER_2, negate(size));
+
+
+        int cancelGridId = gridId - 2;
+        GridElement cancelGrid = GridElement.findById(cancelGridId);
+        if (cancelGrid != null && cancelGrid.isHasShortOrder()) {
+            executor.cancelConditionalOrder(cancelGrid.getShortOrderId(), oid -> {
+                shortEntryTraderIdParam(cancelGrid, null, false);
+                log.info("[Gate] 空仓止损触发, 取消gridId:{}的空单", cancelGridId);
+            });
+        }
     }
 
     private void extendLongStopLoss(int filledQty) {
-        int furthestSlId = filledQty - 2;
-        log.info("[Gate] 多仓追挂止损, 当前最远止损gridId:{}", furthestSlId);
-        GridElement elem = GridElement.findById(furthestSlId);
-        if (elem != null) {
+        int furthestSlId = 0;
+        for (GridElement e : config.getGridElements()) {
+            if (e.getLongStopLossOrderId() != null && e.getId() < furthestSlId) {
+                furthestSlId = e.getId();
+            }
+        }
+        if (furthestSlId == 0) {
+            furthestSlId = -11;
+        }
+        log.info("[Gate] 多仓追挂止损, 当前最远止损gridId:{}, 追加{}张", furthestSlId, filledQty);
+        for (int i = 0; i < filledQty; i++) {
+            int newSlId = furthestSlId - i - 1;
+            GridElement elem = GridElement.findById(newSlId);
+            if (elem == null) {
+                continue;
+            }
             BigDecimal triggerPrice = elem.getGridPrice();
-            int finalSlId = elem.getId();
-            String size = config.getBaseQuantity();
+            int finalSlId = newSlId;
             executor.placeTakeProfit(
                     triggerPrice,
                     FuturesPriceTrigger.RuleEnum.NUMBER_2,
                     ORDER_TYPE_CLOSE_LONG,
-                    negate(size),
+                    negate(config.getQuantity()),
                     profitId -> {
                         elem.setLongStopLossOrderId(profitId);
                         GridElement.refreshIndices();
@@ -1065,18 +1155,29 @@
     }
 
     private void extendShortStopLoss(int filledQty) {
-        int furthestSlId = filledQty + 2;
-        log.info("[Gate] 空仓追挂止损, 当前最远止损gridId:{}", furthestSlId);
-        GridElement elem = GridElement.findById(furthestSlId);
-        if (elem != null) {
+        int furthestSlId = 0;
+        for (GridElement e : config.getGridElements()) {
+            if (e.getShortStopLossOrderId() != null && e.getId() > furthestSlId) {
+                furthestSlId = e.getId();
+            }
+        }
+        if (furthestSlId == 0) {
+            furthestSlId = 11;
+        }
+        log.info("[Gate] 空仓追挂止损, 当前最远止损gridId:{}, 追加{}张", furthestSlId, filledQty);
+        for (int i = 0; i < filledQty; i++) {
+            int newSlId = furthestSlId + i + 1;
+            GridElement elem = GridElement.findById(newSlId);
+            if (elem == null) {
+                continue;
+            }
             BigDecimal triggerPrice = elem.getGridPrice();
-            int finalSlId = elem.getId();
-            String size = config.getBaseQuantity();
+            int finalSlId = newSlId;
             executor.placeTakeProfit(
                     triggerPrice,
                     FuturesPriceTrigger.RuleEnum.NUMBER_1,
                     ORDER_TYPE_CLOSE_SHORT,
-                    size,
+                    config.getQuantity(),
                     profitId -> {
                         elem.setShortStopLossOrderId(profitId);
                         GridElement.refreshIndices();

--
Gitblit v1.9.1