From 6d213ed49218afbf8b83e440eba41f642a4695f2 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Fri, 08 May 2026 10:30:23 +0800
Subject: [PATCH] feat(gateApi): 添加用户ID获取和WebSocket私有频道订阅功能

---
 src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 59 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 f15b8b2..f06e972 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -3,7 +3,9 @@
 import io.gate.gateapi.ApiClient;
 import io.gate.gateapi.ApiException;
 import io.gate.gateapi.GateApiException;
+import io.gate.gateapi.api.AccountApi;
 import io.gate.gateapi.api.FuturesApi;
+import io.gate.gateapi.models.AccountDetail;
 import io.gate.gateapi.models.FuturesAccount;
 import io.gate.gateapi.models.FuturesInitialOrder;
 import io.gate.gateapi.models.FuturesOrder;
@@ -72,6 +74,8 @@
     private volatile BigDecimal lastKlinePrice;
     /** 服务器返回的累计已实现盈亏 */
     private BigDecimal totalHistoryPnl = BigDecimal.ZERO;
+    /** 用户 ID,用于 WebSocket 私有频道订阅 */
+    private Long userId;
 
     /**
      * 构造函数,初始化 Gate 期货 API 客户端。
@@ -111,6 +115,14 @@
      */
     public void init() {
         try {
+            AccountApi accountApi = new AccountApi(apiClient);
+            AccountDetail accountDetail = accountApi.getAccountDetail();
+            this.userId = accountDetail.getUserId();
+            log.info("[GateGrid] 用户ID: {}", userId);
+
+            futuresApi.cancelPriceTriggeredOrderList(SETTLE, contract);
+            log.info("[GateGrid] 已取消所有既有止盈止损条件单");
+
             futuresApi.updateContractPositionLeverageCall(
                     SETTLE, contract, leverage, marginMode, positionMode, null);
             log.info("[GateGrid] 已设置杠杆: {}x, 保证金模式: {}", leverage, marginMode);
@@ -191,7 +203,7 @@
             return;
         }
 
-        boolean hasPosition = size.compareTo(BigDecimal.ZERO) > 0;
+        boolean hasPosition = size.abs().compareTo(BigDecimal.ZERO) > 0;
 
         if ("dual_long".equals(mode)) {
             if (longActive && !hasPosition) {
@@ -393,10 +405,52 @@
             TriggerOrderResponse response = futuresApi.createPriceTriggeredOrder(SETTLE, order);
             log.info("[GateGrid] 止盈条件单已创建, triggerPrice:{}, orderType:{}, autoSize:{}, id:{}",
                     triggerPrice, orderType, autoSize, response.getId());
+        } catch (GateApiException e) {
+            if ("AUTO_USER_EXIST_POSITION_ORDER".equals(e.getErrorLabel())) {
+                log.warn("[GateGrid] 止盈条件单已存在,取消旧单后重试, label:{}", e.getErrorLabel());
+                try {
+                    futuresApi.cancelPriceTriggeredOrderList(SETTLE, contract);
+                    TriggerOrderResponse response = futuresApi.createPriceTriggeredOrder(SETTLE, createPriceTriggeredOrderBean(triggerPrice, rule, orderType, autoSize));
+                    log.info("[GateGrid] 止盈条件单重试成功, triggerPrice:{}, orderType:{}, autoSize:{}, id:{}",
+                            triggerPrice, orderType, autoSize, response.getId());
+                } catch (Exception retryEx) {
+                    log.error("[GateGrid] 止盈条件单重试失败, triggerPrice:{}, orderType:{}, autoSize:{}",
+                            triggerPrice, orderType, autoSize, retryEx);
+                }
+            } else {
+                log.error("[GateGrid] 止盈条件单创建失败, triggerPrice:{}, orderType:{}, autoSize:{}",
+                        triggerPrice, orderType, autoSize, e);
+            }
         } catch (Exception e) {
             log.error("[GateGrid] 止盈条件单创建失败, triggerPrice:{}, orderType:{}, autoSize:{}",
                     triggerPrice, orderType, autoSize, e);
         }
+    }
+
+    private FuturesPriceTriggeredOrder createPriceTriggeredOrderBean(BigDecimal triggerPrice,
+                                                                      FuturesPriceTrigger.RuleEnum rule,
+                                                                      String orderType,
+                                                                      String autoSize) {
+        FuturesPriceTrigger trigger = new FuturesPriceTrigger();
+        trigger.setStrategyType(FuturesPriceTrigger.StrategyTypeEnum.NUMBER_0);
+        trigger.setPriceType(FuturesPriceTrigger.PriceTypeEnum.NUMBER_0);
+        trigger.setPrice(triggerPrice.toString());
+        trigger.setRule(rule);
+        trigger.setExpiration(0);
+
+        FuturesInitialOrder initial = new FuturesInitialOrder();
+        initial.setContract(contract);
+        initial.setSize(0L);
+        initial.setPrice("0");
+        initial.setTif(FuturesInitialOrder.TifEnum.IOC);
+        initial.setReduceOnly(true);
+        initial.setAutoSize(autoSize);
+
+        FuturesPriceTriggeredOrder order = new FuturesPriceTriggeredOrder();
+        order.setTrigger(trigger);
+        order.setInitial(initial);
+        order.setOrderType(orderType);
+        return order;
     }
 
     /**
@@ -447,4 +501,8 @@
     public BigDecimal getTotalHistoryPnl() {
         return totalHistoryPnl;
     }
+
+    public Long getUserId() {
+        return userId;
+    }
 }

--
Gitblit v1.9.1