From 3bcc6918c362a7837f792ef91018a1fe043096ef Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 12 May 2026 17:27:21 +0800
Subject: [PATCH] refactor(gateApi): 将条件单ID管理从单值改为集合支持批量操作
---
src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java | 108 +++++++++++++++++++++++++++++++++---------------------
1 files changed, 66 insertions(+), 42 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 e791e63..a2ec807 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -15,6 +15,10 @@
import java.util.Collections;
import java.util.List;
+import com.xcong.excoin.modules.gateApi.wsHandler.handler.CandlestickChannelHandler;
+import com.xcong.excoin.modules.gateApi.wsHandler.handler.PositionClosesChannelHandler;
+import com.xcong.excoin.modules.gateApi.wsHandler.handler.PositionsChannelHandler;
+
/**
* Gate 网格交易服务 — 策略核心。
*
@@ -108,10 +112,10 @@
/** 空仓止盈队列,降序排列(大→小),仓位推送时消费 */
private final List<BigDecimal> shortTakeProfitQueue = Collections.synchronizedList(new ArrayList<>());
- /** 当前多仓限价单 ID,用于取消旧单 */
- private volatile String currentLongOrderId;
- /** 当前空仓限价单 ID,用于取消旧单 */
- private volatile String currentShortOrderId;
+ /** 当前多仓条件单 ID 集合,用于取消旧单 */
+ private final List<String> currentLongOrderIds = Collections.synchronizedList(new ArrayList<>());
+ /** 当前空仓条件单 ID 集合,用于取消旧单 */
+ private final List<String> currentShortOrderIds = Collections.synchronizedList(new ArrayList<>());
/** 基底空头入场价 */
private BigDecimal shortBaseEntryPrice;
@@ -296,8 +300,8 @@
longPriceQueue.clear();
longTakeProfitQueue.clear();
shortTakeProfitQueue.clear();
- currentLongOrderId = null;
- currentShortOrderId = null;
+ currentLongOrderIds.clear();
+ currentShortOrderIds.clear();
log.info("[Gate] 网格策略已启动");
}
@@ -513,11 +517,13 @@
log.info("[Gate] 多止盈队列:{}", longTakeProfitQueue);
log.info("[Gate] 空止盈队列:{}", shortTakeProfitQueue);
- executor.placeGridLimitOrder(longPriceQueue.get(0), config.getQuantity(),
- orderId -> { currentLongOrderId = orderId; log.info("[Gate] 初始限价多单已挂, id:{}", orderId); },
+ executor.placeConditionalEntryOrder(longPriceQueue.get(0),
+ FuturesPriceTrigger.RuleEnum.NUMBER_1, config.getQuantity(),
+ orderId -> { currentLongOrderIds.add(orderId); log.info("[Gate] 初始条件多单已挂, id:{}, trigger:{}", orderId, longPriceQueue.get(0)); },
null);
- executor.placeGridLimitOrder(shortPriceQueue.get(0), negate(config.getQuantity()),
- orderId -> { currentShortOrderId = orderId; log.info("[Gate] 初始限价空单已挂, id:{}", orderId); },
+ executor.placeConditionalEntryOrder(shortPriceQueue.get(0),
+ FuturesPriceTrigger.RuleEnum.NUMBER_2, negate(config.getQuantity()),
+ orderId -> { currentShortOrderIds.add(orderId); log.info("[Gate] 初始条件空单已挂, id:{}, trigger:{}", orderId, shortPriceQueue.get(0)); },
null);
state = StrategyState.ACTIVE;
@@ -638,27 +644,36 @@
log.info("[Gate] 空止盈队列增加:{}, 现止盈队列:{}", stpElem, shortTakeProfitQueue);
if (!isMarginSafe()) {
- log.warn("[Gate] 保证金超限,跳过挂限价单");
+ log.warn("[Gate] 保证金超限,跳过挂条件单");
} else {
- String oldLongId = currentLongOrderId;
- executor.cancelOrder(oldLongId);
- executor.placeGridLimitOrder(newShortFirst, negate(config.getQuantity()),
- orderId -> { currentShortOrderId = orderId; log.info("[Gate] 新限价空单, id:{}, price:{}", orderId, newShortFirst); },
+ synchronized (currentLongOrderIds) {
+ for (String id : currentLongOrderIds) {
+ executor.cancelConditionalOrder(id);
+ }
+ currentLongOrderIds.clear();
+ }
+ executor.placeConditionalEntryOrder(newShortFirst,
+ FuturesPriceTrigger.RuleEnum.NUMBER_2, negate(config.getQuantity()),
+ orderId -> { currentShortOrderIds.add(orderId); log.info("[Gate] 新条件空单, id:{}, trigger:{}", orderId, newShortFirst); },
null);
- executor.placeGridLimitOrder(newLongFirst, config.getQuantity(),
- orderId -> { currentLongOrderId = orderId; log.info("[Gate] 新限价多单, id:{}, price:{}", orderId, newLongFirst); },
+ executor.placeConditionalEntryOrder(newLongFirst,
+ FuturesPriceTrigger.RuleEnum.NUMBER_1, config.getQuantity(),
+ orderId -> { currentLongOrderIds.add(orderId); log.info("[Gate] 新条件多单, id:{}, trigger:{}", orderId, newLongFirst); },
null);
+
+ if (newShortFirst.compareTo(shortEntryPrice) > 0
+ && newShortFirst.compareTo(longEntryPrice) < 0) {
+ BigDecimal reverseLongTp = newShortFirst.add(step).setScale(1, RoundingMode.HALF_UP);
+ longTakeProfitQueue.add(reverseLongTp);
+ longTakeProfitQueue.sort(BigDecimal::compareTo);
+ executor.placeConditionalEntryOrder(newShortFirst,
+ FuturesPriceTrigger.RuleEnum.NUMBER_1, config.getQuantity(),
+ orderId -> { currentLongOrderIds.add(orderId); },
+ null);
+ log.info("[Gate] 反向条件多单已挂, trigger:{}, size:{}, 止盈:{}", newShortFirst, config.getQuantity(), reverseLongTp);
+ }
}
- if (isMarginSafe()
- && shortEntryPrice.compareTo(BigDecimal.ZERO) > 0
- && longEntryPrice.compareTo(BigDecimal.ZERO) > 0
- && longEntryPrice.compareTo(shortEntryPrice) > 0
- && currentPrice.compareTo(shortEntryPrice) > 0
- && currentPrice.compareTo(longEntryPrice) < 0) {
- executor.openLong(config.getQuantity(), null, null);
- log.info("[Gate] 额外反向开多, 当前价:{} 在[{},{}]之间", currentPrice, shortEntryPrice, longEntryPrice);
- }
}
/**
@@ -736,27 +751,36 @@
log.info("[Gate] 多止盈队列增加:{}, 现止盈队列:{}", ltpElem, longTakeProfitQueue);
if (!isMarginSafe()) {
- log.warn("[Gate] 保证金超限,跳过挂限价单");
+ log.warn("[Gate] 保证金超限,跳过挂条件单");
} else {
- String oldShortId = currentShortOrderId;
- executor.cancelOrder(oldShortId);
- executor.placeGridLimitOrder(newLongFirst, config.getQuantity(),
- orderId -> { currentLongOrderId = orderId; log.info("[Gate] 新限价多单, id:{}, price:{}", orderId, newLongFirst); },
+ synchronized (currentShortOrderIds) {
+ for (String id : currentShortOrderIds) {
+ executor.cancelConditionalOrder(id);
+ }
+ currentShortOrderIds.clear();
+ }
+ executor.placeConditionalEntryOrder(newLongFirst,
+ FuturesPriceTrigger.RuleEnum.NUMBER_1, config.getQuantity(),
+ orderId -> { currentLongOrderIds.add(orderId); log.info("[Gate] 新条件多单, id:{}, trigger:{}", orderId, newLongFirst); },
null);
- executor.placeGridLimitOrder(newShortFirst, negate(config.getQuantity()),
- orderId -> { currentShortOrderId = orderId; log.info("[Gate] 新限价空单, id:{}, price:{}", orderId, newShortFirst); },
+ executor.placeConditionalEntryOrder(newShortFirst,
+ FuturesPriceTrigger.RuleEnum.NUMBER_2, negate(config.getQuantity()),
+ orderId -> { currentShortOrderIds.add(orderId); log.info("[Gate] 新条件空单, id:{}, trigger:{}", orderId, newShortFirst); },
null);
+
+ if (newLongFirst.compareTo(shortEntryPrice) > 0
+ && newLongFirst.compareTo(longEntryPrice) < 0) {
+ BigDecimal reverseShortTp = newLongFirst.subtract(step).setScale(1, RoundingMode.HALF_UP);
+ shortTakeProfitQueue.add(reverseShortTp);
+ shortTakeProfitQueue.sort((a, b) -> b.compareTo(a));
+ executor.placeConditionalEntryOrder(newLongFirst,
+ FuturesPriceTrigger.RuleEnum.NUMBER_2, negate(config.getQuantity()),
+ orderId -> { currentShortOrderIds.add(orderId); },
+ null);
+ log.info("[Gate] 反向条件空单已挂, trigger:{}, size:{}, 止盈:{}", newLongFirst, negate(config.getQuantity()), reverseShortTp);
+ }
}
- if (isMarginSafe()
- && shortEntryPrice.compareTo(BigDecimal.ZERO) > 0
- && longEntryPrice.compareTo(BigDecimal.ZERO) > 0
- && longEntryPrice.compareTo(shortEntryPrice) > 0
- && currentPrice.compareTo(shortEntryPrice) > 0
- && currentPrice.compareTo(longEntryPrice) < 0) {
- executor.openShort(negate(config.getQuantity()), null, null);
- log.info("[Gate] 额外反向开空, 当前价:{} 在[{},{}]之间", currentPrice, shortEntryPrice, longEntryPrice);
- }
}
// ---- 保证金安全阀 ----
--
Gitblit v1.9.1