From a986f3571c7e18ade4665fe5999b445b5762264d Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Mon, 11 May 2026 23:07:15 +0800
Subject: [PATCH] refactor(gateApi): 修改网格交易队列生成算法

---
 src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java |   69 ++++++++++++++++++----------------
 1 files changed, 36 insertions(+), 33 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 feb3fa0..d0ca8f5 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -479,32 +479,35 @@
 
     /**
      * 生成空仓价格队列。
-     * 以空头基底入场价 shortBaseEntryPrice 为基准,按 gridRate 递减生成 gridQueueSize 个价格元素:
-     * <pre>shortBaseEntryPrice × (1 − gridRate × i), i=1..gridQueueSize</pre>
+     * 以 shortBaseEntryPrice × gridRate 作为绝对步长 step,存到 config。
+     * 第1个元素 = shortBaseEntryPrice − step,后续依次递减 step,共 gridQueueSize 个。
      * 队列降序排列(大→小),方便 processShortGrid 中从头遍历。
      */
     private void generateShortQueue() {
         shortPriceQueue.clear();
-        BigDecimal step = config.getGridRate();
-        for (int i = 1; i <= config.getGridQueueSize(); i++) {
-            shortPriceQueue.add(shortBaseEntryPrice.multiply(BigDecimal.ONE.subtract(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP));
+        BigDecimal step = shortBaseEntryPrice.multiply(config.getGridRate()).setScale(1, RoundingMode.HALF_UP);
+        config.setStep(step);
+        BigDecimal elem = shortBaseEntryPrice.subtract(step).setScale(1, RoundingMode.HALF_UP);
+        for (int i = 0; i < config.getGridQueueSize(); i++) {
+            shortPriceQueue.add(elem);
+            elem = elem.subtract(step).setScale(1, RoundingMode.HALF_UP);
         }
         shortPriceQueue.sort((a, b) -> b.compareTo(a));
-        //输出队列:shortPriceQueue;
         log.info("[Gate] 空队列:{}", shortPriceQueue);
     }
 
     /**
      * 生成多仓价格队列。
-     * 以多头基底入场价 longBaseEntryPrice 为基准,按 gridRate 递增生成 gridQueueSize 个价格元素:
-     * <pre>longBaseEntryPrice × (1 + gridRate × i), i=1..gridQueueSize</pre>
+     * 以 shortBaseEntryPrice + step 为首元素,后续依次递增 step,共 gridQueueSize 个。
      * 队列升序排列(小→大),方便 processLongGrid 中从头遍历。
      */
     private void generateLongQueue() {
         longPriceQueue.clear();
-        BigDecimal step = config.getGridRate();
-        for (int i = 1; i <= config.getGridQueueSize(); i++) {
-            longPriceQueue.add(longBaseEntryPrice.multiply(BigDecimal.ONE.add(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP));
+        BigDecimal step = config.getStep();
+        BigDecimal elem = shortBaseEntryPrice.add(step).setScale(1, RoundingMode.HALF_UP);
+        for (int i = 0; i < config.getGridQueueSize(); i++) {
+            longPriceQueue.add(elem);
+            elem = elem.add(step).setScale(1, RoundingMode.HALF_UP);
         }
         longPriceQueue.sort(BigDecimal::compareTo);
         log.info("[Gate] 多队列:{}", longPriceQueue);
@@ -520,8 +523,8 @@
      * <h3>执行流程</h3>
      * <ol>
      *   <li>匹配队列元素 → 为空则直接返回</li>
-     *   <li>空仓队列:移除 matched 元素,尾部补充新元素(尾价 × (1 − gridRate) 循环递减)</li>
-     *   <li>多仓队列:以多仓队列首元素(最小价)为种子,生成 matched.size() 个递减元素加入</li>
+     *   <li>空仓队列:移除 matched 元素,尾部补充新元素(尾价 − step 循环递减)</li>
+     *   <li>多仓队列:以多仓队列首元素(最小价)为种子,递减 step 生成 matched.size() 个元素加入</li>
      *   <li>保证金检查 → 安全则开空一次</li>
      *   <li>额外反向开多:若多仓均价 > 空仓均价 且 当前价夹在中间且远离多仓均价</li>
      * </ol>
@@ -550,9 +553,9 @@
         synchronized (shortPriceQueue) {
             shortPriceQueue.removeAll(matched);
             BigDecimal min = shortPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : shortPriceQueue.get(shortPriceQueue.size() - 1);
-            BigDecimal step = config.getGridRate();
+            BigDecimal gridStep = config.getStep();
             for (int i = 0; i < matched.size(); i++) {
-                min = min.multiply(BigDecimal.ONE.subtract(step)).setScale(1, RoundingMode.HALF_UP);
+                min = min.subtract(gridStep).setScale(1, RoundingMode.HALF_UP);
                 shortPriceQueue.add(min);
                 log.info("[Gate] 空队列增加:{}", min);
             }
@@ -564,14 +567,14 @@
 
         synchronized (longPriceQueue) {
             BigDecimal first = longPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : longPriceQueue.get(0);
-            BigDecimal step = config.getGridRate();
+            BigDecimal gridStep = config.getStep();
             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
-                        && currentPrice.subtract(longEntryPrice).abs().compareTo(longEntryPrice.multiply(step)) < 0) {
-                    log.info("[Gate] 多队列跳过(price≈longEntry):{}", elem);
-                    continue;
-                }
+                BigDecimal elem = first.subtract(gridStep.multiply(BigDecimal.valueOf(i))).setScale(1, RoundingMode.HALF_UP);
+//                if (longEntryPrice.compareTo(BigDecimal.ZERO) > 0
+//                        && currentPrice.subtract(longEntryPrice).abs().compareTo(longEntryPrice.multiply(config.getGridRate())) < 0) {
+//                    log.info("[Gate] 多队列跳过(price≈longEntry):{}", elem);
+//                    continue;
+//                }
                 longPriceQueue.add(elem);
                 log.info("[Gate] 多队列增加:{}", elem);
             }
@@ -607,8 +610,8 @@
      * <h3>执行流程</h3>
      * <ol>
      *   <li>匹配队列元素 → 为空则直接返回</li>
-     *   <li>多仓队列:移除 matched 元素,尾部补充新元素(尾价 × (1 + gridRate) 循环递增)</li>
-     *   <li>空仓队列:以空仓队列首元素(最高价)为种子,生成 matched.size() 个递增元素加入</li>
+     *   <li>多仓队列:移除 matched 元素,尾部补充新元素(尾价 + step 循环递增)</li>
+     *   <li>空仓队列:以空仓队列首元素(最高价)为种子,递增 step 生成 matched.size() 个元素加入</li>
      *   <li>保证金检查 → 安全则开多一次</li>
      *   <li>额外反向开空:若多仓均价 > 空仓均价 且 当前价夹在中间且远离空仓均价</li>
      * </ol>
@@ -638,9 +641,9 @@
         synchronized (longPriceQueue) {
             longPriceQueue.removeAll(matched);
             BigDecimal max = longPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : longPriceQueue.get(longPriceQueue.size() - 1);
-            BigDecimal step = config.getGridRate();
+            BigDecimal gridStep = config.getStep();
             for (int i = 0; i < matched.size(); i++) {
-                max = max.multiply(BigDecimal.ONE.add(step)).setScale(1, RoundingMode.HALF_UP);
+                max = max.add(gridStep).setScale(1, RoundingMode.HALF_UP);
                 longPriceQueue.add(max);
 
                 log.info("[Gate] 多队列增加:{}", max);
@@ -652,14 +655,14 @@
 
         synchronized (shortPriceQueue) {
             BigDecimal first = shortPriceQueue.isEmpty() ? matched.get(0) : shortPriceQueue.get(0);
-            BigDecimal step = config.getGridRate();
+            BigDecimal gridStep = config.getStep();
             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
-                        && currentPrice.subtract(shortEntryPrice).abs().compareTo(shortEntryPrice.multiply(step)) < 0) {
-                    log.info("[Gate] 空队列跳过(price≈shortEntry):{}", elem);
-                    continue;
-                }
+                BigDecimal elem = first.add(gridStep.multiply(BigDecimal.valueOf(i))).setScale(1, RoundingMode.HALF_UP);
+//                if (shortEntryPrice.compareTo(BigDecimal.ZERO) > 0
+//                        && currentPrice.subtract(shortEntryPrice).abs().compareTo(shortEntryPrice.multiply(config.getGridRate())) < 0) {
+//                    log.info("[Gate] 空队列跳过(price≈shortEntry):{}", elem);
+//                    continue;
+//                }
                 shortPriceQueue.add(elem);
                 log.info("[Gate] 空队列增加:{}", elem);
             }

--
Gitblit v1.9.1