From 1819eaee93e47888dad4e1be4e3c611576426581 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Sat, 09 May 2026 16:59:12 +0800
Subject: [PATCH] refactor(gateApi): 优化网格交易价格队列添加逻辑

---
 src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java |   59 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 47 insertions(+), 12 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 2bccbd2..eae5b3b 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -58,10 +58,8 @@
         WAITING_KLINE, OPENING, ACTIVE, STOPPED
     }
 
-    private static final String AUTO_SIZE_LONG = "close_long";
-    private static final String AUTO_SIZE_SHORT = "close_short";
-    private static final String ORDER_TYPE_CLOSE_LONG = "close-long-position";
-    private static final String ORDER_TYPE_CLOSE_SHORT = "close-short-position";
+    private static final String ORDER_TYPE_CLOSE_LONG = "plan-close-long-position";
+    private static final String ORDER_TYPE_CLOSE_SHORT = "plan-close-short-position";
 
     private final GateConfig config;
     private final GateTradeExecutor executor;
@@ -123,6 +121,12 @@
             FuturesAccount account = futuresApi.listFuturesAccounts(SETTLE);
             this.initialPrincipal = new BigDecimal(account.getTotal());
             log.info("[Gate] 初始本金: {} USDT", initialPrincipal);
+
+            //设置持仓模式为双向持仓
+            Boolean inDualMode = account.getInDualMode();
+            if (!inDualMode) {
+                futuresApi.setDualModeCall(SETTLE,true,null);
+            }
 
             if (!config.getPositionMode().equals(account.getPositionMode())) {
                 futuresApi.setPositionMode(SETTLE, config.getPositionMode());
@@ -265,8 +269,8 @@
                 } else {
                     BigDecimal tpPrice = entryPrice.multiply(BigDecimal.ONE.add(config.getGridRate())).setScale(1, RoundingMode.HALF_UP);
                     executor.placeTakeProfit(tpPrice,
-                            FuturesPriceTrigger.RuleEnum.NUMBER_1, ORDER_TYPE_CLOSE_LONG, AUTO_SIZE_LONG);
-                    log.info("[Gate] 多单止盈已设, entry:{}, tp:{}", entryPrice, tpPrice);
+                            FuturesPriceTrigger.RuleEnum.NUMBER_1, ORDER_TYPE_CLOSE_LONG, negate(config.getQuantity()));
+                    log.info("[Gate] 多单止盈已设, entry:{}, tp:{}, size:{}", entryPrice, tpPrice, negate(config.getQuantity()));
                 }
             } else {
                 longActive = false;
@@ -285,8 +289,8 @@
                 } else {
                     BigDecimal tpPrice = entryPrice.multiply(BigDecimal.ONE.subtract(config.getGridRate())).setScale(1, RoundingMode.HALF_UP);
                     executor.placeTakeProfit(tpPrice,
-                            FuturesPriceTrigger.RuleEnum.NUMBER_2, ORDER_TYPE_CLOSE_SHORT, AUTO_SIZE_SHORT);
-                    log.info("[Gate] 空单止盈已设, entry:{}, tp:{}", entryPrice, tpPrice);
+                            FuturesPriceTrigger.RuleEnum.NUMBER_2, ORDER_TYPE_CLOSE_SHORT, config.getQuantity());
+                    log.info("[Gate] 空单止盈已设, entry:{}, tp:{}, size:{}", entryPrice, tpPrice, config.getQuantity());
                 }
             } else {
                 shortActive = false;
@@ -358,10 +362,11 @@
                 }
             }
         }
+        log.info("[Gate] 原空队列:{}", shortPriceQueue);
         if (matched.isEmpty()) {
+            log.info("[Gate] 空仓队列未触发, 当前价:{}", currentPrice);
             return;
         }
-
         log.info("[Gate] 空仓队列触发, 匹配{}个元素, 当前价:{}", matched.size(), currentPrice);
         if (!isMarginSafe()) {
             log.warn("[Gate] 保证金超限,跳过空单开仓");
@@ -377,15 +382,29 @@
                 min = min.multiply(BigDecimal.ONE.subtract(step)).setScale(1, RoundingMode.HALF_UP);
                 shortPriceQueue.add(min);
             }
-            shortPriceQueue.sort((a, b) -> b.compareTo(a));
+            shortPriceQueue.sort(BigDecimal::compareTo);
+
+            log.info("[Gate] 现空队列:{}", shortPriceQueue);
         }
 
         synchronized (longPriceQueue) {
-            longPriceQueue.addAll(matched);
+            BigDecimal first = longPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : longPriceQueue.get(0);
+            BigDecimal step = config.getGridRate();
+            int added = 0;
+            for (int i = 1; i <= matched.size(); i++) {
+                BigDecimal elem = first.multiply(BigDecimal.ONE.subtract(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP);
+                if (longEntryPrice.compareTo(BigDecimal.ZERO) > 0
+                        && elem.subtract(longEntryPrice).abs().compareTo(longEntryPrice.multiply(step)) < 0) {
+                    continue;
+                }
+                longPriceQueue.add(elem);
+                added++;
+            }
             longPriceQueue.sort(BigDecimal::compareTo);
             while (longPriceQueue.size() > config.getGridQueueSize()) {
                 longPriceQueue.remove(longPriceQueue.size() - 1);
             }
+            log.info("[Gate] 现多队列:{}, 跳过{}个(贴近多仓均价)", longPriceQueue, matched.size() - added);
         }
     }
 
@@ -400,7 +419,9 @@
                 }
             }
         }
+        log.info("[Gate] 原多队列:{}", longPriceQueue);
         if (matched.isEmpty()) {
+            log.info("[Gate] 多仓队列未触发,  当前价:{}", currentPrice);
             return;
         }
 
@@ -420,14 +441,28 @@
                 longPriceQueue.add(max);
             }
             longPriceQueue.sort(BigDecimal::compareTo);
+
+            log.info("[Gate] 现多队列:{}", longPriceQueue);
         }
 
         synchronized (shortPriceQueue) {
-            shortPriceQueue.addAll(matched);
+            BigDecimal first = shortPriceQueue.isEmpty() ? matched.get(0) : shortPriceQueue.get(0);
+            BigDecimal step = config.getGridRate();
+            int added = 0;
+            for (int i = 1; i <= matched.size(); i++) {
+                BigDecimal elem = first.multiply(BigDecimal.ONE.add(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP);
+                if (shortEntryPrice.compareTo(BigDecimal.ZERO) > 0
+                        && elem.subtract(shortEntryPrice).abs().compareTo(shortEntryPrice.multiply(step)) < 0) {
+                    continue;
+                }
+                shortPriceQueue.add(elem);
+                added++;
+            }
             shortPriceQueue.sort((a, b) -> b.compareTo(a));
             while (shortPriceQueue.size() > config.getGridQueueSize()) {
                 shortPriceQueue.remove(shortPriceQueue.size() - 1);
             }
+            log.info("[Gate] 现空队列:{}, 跳过{}个(贴近空仓均价)", shortPriceQueue, matched.size() - added);
         }
     }
 

--
Gitblit v1.9.1