From 6e4499000b79c1848824a217af84ee51cba36274 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Mon, 18 May 2026 17:15:43 +0800
Subject: [PATCH] 第二个版本

---
 src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java |   35 ++++++++++++++++++++---------------
 src/main/java/com/xcong/excoin/modules/gateApi/GateConfig.java           |    5 +++++
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/GateConfig.java b/src/main/java/com/xcong/excoin/modules/gateApi/GateConfig.java
index 7153f7a..a7ccf86 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateConfig.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateConfig.java
@@ -90,6 +90,8 @@
     private final BigDecimal marginRatioLimit;
     /** 合约乘数(单张合约代表的基础资产数量,如 BTC_USDT=0.001, ETH_USDT=0.01) */
     private final BigDecimal contractMultiplier;
+    /** 价格精度(根据合约乘数自动计算的小数位数,如 0.001 → 3,0.01 → 2) */
+    private final int pricePrecision;
     /** 未实现盈亏计价模式:最新价 / 标记价格 */
     private final PnLPriceMode unrealizedPnlPriceMode;
     /** 网格绝对步长(shortBaseEntryPrice × gridRate),运行时由队列生成逻辑设置 */
@@ -117,6 +119,7 @@
         this.gridQueueSize = builder.gridQueueSize;
         this.marginRatioLimit = builder.marginRatioLimit;
         this.contractMultiplier = builder.contractMultiplier;
+        this.pricePrecision = builder.contractMultiplier.stripTrailingZeros().scale();
         this.unrealizedPnlPriceMode = builder.unrealizedPnlPriceMode;
     }
 
@@ -193,6 +196,8 @@
 
     /** @return 合约乘数(单张合约代表的基础资产数量,如 ETH_USDT=0.01) */
     public BigDecimal getContractMultiplier() { return contractMultiplier; }
+    /** @return 价格精度(根据合约乘数自动计算的小数位数,如 0.001→3,0.01→2),用于价格四舍五入 */
+    public int getPricePrecision() { return pricePrecision; }
     /** @return 未实现盈亏计价模式:LAST_PRICE(最新成交价)/ MARK_PRICE(标记价格) */
     public PnLPriceMode getUnrealizedPnlPriceMode() { return unrealizedPnlPriceMode; }
 
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 9c720ec..f85a5f6 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -740,12 +740,13 @@
      */
     private void generateShortQueue() {
         shortPriceQueue.clear();
-        BigDecimal step = shortBaseEntryPrice.multiply(config.getGridRate()).setScale(1, RoundingMode.HALF_UP);
+        int prec = config.getPricePrecision();
+        BigDecimal step = shortBaseEntryPrice.multiply(config.getGridRate()).setScale(prec, RoundingMode.HALF_UP);
         config.setStep(step);
-        BigDecimal elem = shortBaseEntryPrice.subtract(step).setScale(1, RoundingMode.HALF_UP);
+        BigDecimal elem = shortBaseEntryPrice.subtract(step).setScale(prec, RoundingMode.HALF_UP);
             for (int i = 0; i < config.getGridQueueSize(); i++) {
                 shortPriceQueue.add(elem);
-                elem = elem.subtract(step).setScale(1, RoundingMode.HALF_UP);
+                elem = elem.subtract(step).setScale(prec, RoundingMode.HALF_UP);
                 if (elem.compareTo(BigDecimal.ZERO) <= 0) {
                     break;
                 }
@@ -761,11 +762,12 @@
      */
     private void generateLongQueue() {
         longPriceQueue.clear();
+        int prec = config.getPricePrecision();
         BigDecimal step = config.getStep();
-        BigDecimal elem = shortBaseEntryPrice.add(step).setScale(1, RoundingMode.HALF_UP);
+        BigDecimal elem = shortBaseEntryPrice.add(step).setScale(prec, RoundingMode.HALF_UP);
         for (int i = 0; i < config.getGridQueueSize(); i++) {
             longPriceQueue.add(elem);
-            elem = elem.add(step).setScale(1, RoundingMode.HALF_UP);
+            elem = elem.add(step).setScale(prec, RoundingMode.HALF_UP);
         }
         longPriceQueue.sort(BigDecimal::compareTo);
         log.info("[Gate] 多队列:{}", longPriceQueue);
@@ -791,6 +793,7 @@
         int longSize = longPriceQueue.size();
         BigDecimal step = config.getStep().subtract(config.getContractMultiplier());
         String qty = config.getQuantity();
+        int prec = config.getPricePrecision();
 
         // 空仓队列:id 从 -1 自减, shortPriceQueue[i] → id=-(i+1)
         for (int i = 0; i < shortSize; i++) {
@@ -801,13 +804,13 @@
             TraderParam longParam = TraderParam.builder()
                     .direction(TraderParam.Direction.LONG)
                     .entryPrice(price)
-                    .takeProfitPrice(price.add(step).setScale(1, RoundingMode.HALF_UP))
+                    .takeProfitPrice(price.add(step).setScale(prec, RoundingMode.HALF_UP))
                     .quantity(qty)
                     .build();
             TraderParam shortParam = TraderParam.builder()
                     .direction(TraderParam.Direction.SHORT)
                     .entryPrice(price)
-                    .takeProfitPrice(price.subtract(step).setScale(1, RoundingMode.HALF_UP))
+                    .takeProfitPrice(price.subtract(step).setScale(prec, RoundingMode.HALF_UP))
                     .quantity(qty)
                     .build();
             elements.add(GridElement.builder()
@@ -826,13 +829,13 @@
             TraderParam longParam = TraderParam.builder()
                     .direction(TraderParam.Direction.LONG)
                     .entryPrice(price)
-                    .takeProfitPrice(price.add(step).setScale(1, RoundingMode.HALF_UP))
+                    .takeProfitPrice(price.add(step).setScale(prec, RoundingMode.HALF_UP))
                     .quantity(qty)
                     .build();
             TraderParam shortParam = TraderParam.builder()
                     .direction(TraderParam.Direction.SHORT)
                     .entryPrice(price)
-                    .takeProfitPrice(price.subtract(step).setScale(1, RoundingMode.HALF_UP))
+                    .takeProfitPrice(price.subtract(step).setScale(prec, RoundingMode.HALF_UP))
                     .quantity(qty)
                     .build();
             elements.add(GridElement.builder()
@@ -854,13 +857,13 @@
             TraderParam longParam = TraderParam.builder()
                     .direction(TraderParam.Direction.LONG)
                     .entryPrice(price)
-                    .takeProfitPrice(price.add(step).setScale(1, RoundingMode.HALF_UP))
+                    .takeProfitPrice(price.add(step).setScale(prec, RoundingMode.HALF_UP))
                     .quantity(qty)
                     .build();
             TraderParam shortParam = TraderParam.builder()
                     .direction(TraderParam.Direction.SHORT)
                     .entryPrice(price)
-                    .takeProfitPrice(price.subtract(step).setScale(1, RoundingMode.HALF_UP))
+                    .takeProfitPrice(price.subtract(step).setScale(prec, RoundingMode.HALF_UP))
                     .quantity(qty)
                     .build();
             elements.add(GridElement.builder()
@@ -902,6 +905,7 @@
      * @param currentPrice 当前 K 线收盘价(最新成交价)
      */
     private void processShortGrid(BigDecimal currentPrice) {
+        int prec = config.getPricePrecision();
         List<BigDecimal> matched = new ArrayList<>();
         synchronized (shortPriceQueue) {
             for (BigDecimal p : shortPriceQueue) {
@@ -922,7 +926,7 @@
             BigDecimal min = shortPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : shortPriceQueue.get(shortPriceQueue.size() - 1);
             BigDecimal gridStep = config.getStep();
             for (int i = 0; i < matched.size(); i++) {
-                min = min.subtract(gridStep).setScale(1, RoundingMode.HALF_UP);
+                min = min.subtract(gridStep).setScale(prec, RoundingMode.HALF_UP);
                 shortPriceQueue.add(min);
             }
             shortPriceQueue.sort((a, b) -> b.compareTo(a));
@@ -932,7 +936,7 @@
             BigDecimal first = longPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : longPriceQueue.get(0);
             BigDecimal gridStep = config.getStep();
             for (int i = 1; i <= matched.size(); i++) {
-                BigDecimal elem = first.subtract(gridStep.multiply(BigDecimal.valueOf(i))).setScale(1, RoundingMode.HALF_UP);
+                BigDecimal elem = first.subtract(gridStep.multiply(BigDecimal.valueOf(i))).setScale(prec, RoundingMode.HALF_UP);
                 longPriceQueue.add(elem);
             }
             longPriceQueue.sort(BigDecimal::compareTo);
@@ -1058,6 +1062,7 @@
      * @param currentPrice 当前 K 线收盘价(最新成交价)
      */
     private void processLongGrid(BigDecimal currentPrice) {
+        int prec = config.getPricePrecision();
         List<BigDecimal> matched = new ArrayList<>();
         synchronized (longPriceQueue) {
             for (BigDecimal p : longPriceQueue) {
@@ -1084,7 +1089,7 @@
             BigDecimal max = longPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : longPriceQueue.get(longPriceQueue.size() - 1);
             BigDecimal gridStep = config.getStep();
             for (int i = 0; i < matched.size(); i++) {
-                max = max.add(gridStep).setScale(1, RoundingMode.HALF_UP);
+                max = max.add(gridStep).setScale(prec, RoundingMode.HALF_UP);
                 longPriceQueue.add(max);
             }
             longPriceQueue.sort(BigDecimal::compareTo);
@@ -1093,7 +1098,7 @@
             BigDecimal first = shortPriceQueue.isEmpty() ? matched.get(0) : shortPriceQueue.get(0);
             BigDecimal gridStep = config.getStep();
             for (int i = 1; i <= matched.size(); i++) {
-                BigDecimal elem = first.add(gridStep.multiply(BigDecimal.valueOf(i))).setScale(1, RoundingMode.HALF_UP);
+                BigDecimal elem = first.add(gridStep.multiply(BigDecimal.valueOf(i))).setScale(prec, RoundingMode.HALF_UP);
                 shortPriceQueue.add(elem);
             }
             shortPriceQueue.sort((a, b) -> b.compareTo(a));

--
Gitblit v1.9.1