From 80e9bd1f5a167a5c7c76b2d61919aa163664076d Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Sat, 09 May 2026 13:45:40 +0800
Subject: [PATCH] fix(trade): 修复止盈订单数量设置和日志记录问题
---
src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java | 59 ++++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 36 insertions(+), 23 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 dfb885a..7bc38fa 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -58,8 +58,6 @@
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";
@@ -124,6 +122,12 @@
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());
}
@@ -134,9 +138,9 @@
closeExistingPositions();
- futuresApi.updateContractPositionLeverageCall(
+ futuresApi.updateDualModePositionLeverageCall(
SETTLE, config.getContract(), config.getLeverage(),
- config.getMarginMode(), config.getPositionMode(), null);
+ config.getMarginMode(), null);
log.info("[Gate] 杠杆: {}x {}", config.getLeverage(), config.getMarginMode());
} catch (GateApiException e) {
log.error("[Gate] 初始化失败, label:{}, msg:{}", e.getErrorLabel(), e.getMessage());
@@ -227,14 +231,10 @@
state = StrategyState.OPENING;
log.info("[Gate] 首根K线到达,开基底仓位...");
executor.openLong(config.getQuantity(), () -> {
- baseLongOpened = true;
- longActive = true;
- log.info("[Gate] 基底多已开");
+ log.info("[Gate] 基底多单已提交");
}, null);
executor.openShort(negate(config.getQuantity()), () -> {
- baseShortOpened = true;
- shortActive = true;
- log.info("[Gate] 基底空已开");
+ log.info("[Gate] 基底空单已提交");
}, null);
return;
}
@@ -267,10 +267,10 @@
log.info("[Gate] 基底多成交价: {}", longBaseEntryPrice);
tryGenerateQueues();
} else {
- executor.placeTakeProfit(entryPrice.add(config.getGridRate()).setScale(1, RoundingMode.HALF_UP),
- FuturesPriceTrigger.RuleEnum.NUMBER_1, ORDER_TYPE_CLOSE_LONG, AUTO_SIZE_LONG);
- log.info("[Gate] 多单止盈已设, entry:{}, tp:{}", entryPrice,
- entryPrice.add(config.getGridRate()).setScale(1, RoundingMode.HALF_UP));
+ 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, negate(config.getQuantity()));
+ log.info("[Gate] 多单止盈已设, entry:{}, tp:{}, size:{}", entryPrice, tpPrice, negate(config.getQuantity()));
}
} else {
longActive = false;
@@ -287,10 +287,10 @@
log.info("[Gate] 基底空成交价: {}", shortBaseEntryPrice);
tryGenerateQueues();
} else {
- executor.placeTakeProfit(entryPrice.subtract(config.getGridRate()).setScale(1, RoundingMode.HALF_UP),
- FuturesPriceTrigger.RuleEnum.NUMBER_2, ORDER_TYPE_CLOSE_SHORT, AUTO_SIZE_SHORT);
- log.info("[Gate] 空单止盈已设, entry:{}, tp:{}", entryPrice,
- entryPrice.subtract(config.getGridRate()).setScale(1, RoundingMode.HALF_UP));
+ 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, config.getQuantity());
+ log.info("[Gate] 空单止盈已设, entry:{}, tp:{}, size:{}", entryPrice, tpPrice, config.getQuantity());
}
} else {
shortActive = false;
@@ -334,18 +334,21 @@
shortPriceQueue.clear();
BigDecimal step = config.getGridRate();
for (int i = 1; i <= config.getGridQueueSize(); i++) {
- shortPriceQueue.add(shortBaseEntryPrice.subtract(step.multiply(BigDecimal.valueOf(i))).setScale(1, RoundingMode.HALF_UP));
+ shortPriceQueue.add(shortBaseEntryPrice.multiply(BigDecimal.ONE.subtract(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP));
}
shortPriceQueue.sort((a, b) -> b.compareTo(a));
+ //输出队列:shortPriceQueue;
+ log.info("[Gate] 空队列:{}", shortPriceQueue);
}
private void generateLongQueue() {
longPriceQueue.clear();
BigDecimal step = config.getGridRate();
for (int i = 1; i <= config.getGridQueueSize(); i++) {
- longPriceQueue.add(longBaseEntryPrice.add(step.multiply(BigDecimal.valueOf(i))).setScale(1, RoundingMode.HALF_UP));
+ longPriceQueue.add(longBaseEntryPrice.multiply(BigDecimal.ONE.add(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP));
}
longPriceQueue.sort(BigDecimal::compareTo);
+ log.info("[Gate] 多队列:{}", longPriceQueue);
}
private void processShortGrid(BigDecimal currentPrice) {
@@ -375,10 +378,12 @@
BigDecimal min = shortPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : shortPriceQueue.get(shortPriceQueue.size() - 1);
BigDecimal step = config.getGridRate();
for (int i = 0; i < matched.size(); i++) {
- min = min.subtract(step).setScale(1, RoundingMode.HALF_UP);
+ 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) {
@@ -387,6 +392,8 @@
while (longPriceQueue.size() > config.getGridQueueSize()) {
longPriceQueue.remove(longPriceQueue.size() - 1);
}
+
+ log.info("[Gate] 多队列:{}", shortPriceQueue);
}
}
@@ -417,10 +424,12 @@
BigDecimal max = longPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : longPriceQueue.get(longPriceQueue.size() - 1);
BigDecimal step = config.getGridRate();
for (int i = 0; i < matched.size(); i++) {
- max = max.add(step).setScale(1, RoundingMode.HALF_UP);
+ max = max.multiply(BigDecimal.ONE.add(step)).setScale(1, RoundingMode.HALF_UP);
longPriceQueue.add(max);
}
longPriceQueue.sort(BigDecimal::compareTo);
+
+ log.info("[Gate] 多队列:{}", shortPriceQueue);
}
synchronized (shortPriceQueue) {
@@ -429,6 +438,8 @@
while (shortPriceQueue.size() > config.getGridQueueSize()) {
shortPriceQueue.remove(shortPriceQueue.size() - 1);
}
+
+ log.info("[Gate] 空队列:{}", shortPriceQueue);
}
}
@@ -478,6 +489,8 @@
shortPnl = shortPositionSize.multiply(multiplier).multiply(shortEntryPrice.subtract(price));
}
unrealizedPnl = longPnl.add(shortPnl);
+
+ log.info("[Gate] 未实现盈亏: {}", unrealizedPnl);
}
/**
--
Gitblit v1.9.1