Administrator
2026-09-30 709e30c0b296a7ad63b05dd8718c933bb2f6eded
src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -836,8 +836,9 @@
                lastShortStopLossGridId = Integer.MAX_VALUE;
                // [Gate-需求2] 加仓后先撤空仓所有止盈+止损,再查交易所持仓后重挂
                cancelAllShortTakeProfitsAndStopLosses();
                // REST 查询可能因交易所延迟返回旧值,与 WS 本地缓存取最大值兜底
                int posSize = Math.max(queryPositionSize(Position.ModeEnum.DUAL_SHORT), shortPositionSize.intValue());
                // REST/WS 持仓可能因交易所延迟返回旧值(仓位归零后重开甚至为 0),
                // 与本次成交张数 filledQty 取最大值兜底,避免 posSize=0 导致止盈止损全部跳过
                int posSize = Math.max(Math.max(queryPositionSize(Position.ModeEnum.DUAL_SHORT), shortPositionSize.intValue()), filledQty);
                extendShortStopLoss(posSize, shortGridElement.getId());
                // [Gate] 止盈挂单:超出基础仓位的部分,挂在多仓第一止损位
                if (GateConfig.EXCESS_TP_CONCENTRATED.equals(config.getPlaceExcessTakeProfit())) {
@@ -886,8 +887,9 @@
                lastLongStopLossGridId = Integer.MAX_VALUE;
                // [Gate-需求2] 加仓后先撤多仓所有止盈+止损,再查交易所持仓后重挂
                cancelAllLongTakeProfitsAndStopLosses();
                // REST 查询可能因交易所延迟返回旧值,与 WS 本地缓存取最大值兜底
                int posSize = Math.max(queryPositionSize(Position.ModeEnum.DUAL_LONG), longPositionSize.intValue());
                // REST/WS 持仓可能因交易所延迟返回旧值(仓位归零后重开甚至为 0),
                // 与本次成交张数 filledQty 取最大值兜底,避免 posSize=0 导致止盈止损全部跳过
                int posSize = Math.max(Math.max(queryPositionSize(Position.ModeEnum.DUAL_LONG), longPositionSize.intValue()), filledQty);
                extendLongStopLoss(posSize, longGridElement.getId());
                // [Gate] 止盈挂单:超出基础仓位的部分,挂在空仓第一止损位
                if (GateConfig.EXCESS_TP_CONCENTRATED.equals(config.getPlaceExcessTakeProfit())) {
@@ -3053,9 +3055,9 @@
     * @param entryGridId 入场网格 ID
     */
    private void placeBaseTakeProfit(int posSize, boolean isLong, int entryGridId) {
        int perGrid = config.getBaseTakeProfitPerGrid();
        BigDecimal perGrid = config.getBaseTakeProfitPerGrid();
        int gridCount = config.getBaseTakeProfitGridCount();
        if (perGrid <= 0 || gridCount <= 0) {
        if (perGrid == null || perGrid.compareTo(BigDecimal.ZERO) <= 0 || gridCount <= 0) {
            return;
        }
        int baseQty = Integer.parseInt(config.getBaseQuantity());
@@ -3078,10 +3080,10 @@
        // 分配范围到止损位的前一格截止(与分散止盈一致)
        int endId = endElem.getId() - dir;
        int remaining = maxQty;
        BigDecimal remaining = BigDecimal.valueOf(maxQty);
        int placed = 0;
        int id = startId;
        while (placed < gridCount && remaining > 0) {
        while (placed < gridCount && remaining.compareTo(BigDecimal.ZERO) > 0) {
            if (isLong ? id > endId : id < endId) {
                break;
            }
@@ -3089,11 +3091,11 @@
            if (elem == null) {
                break;
            }
            int qty = Math.min(perGrid, remaining);
            BigDecimal qty = perGrid.min(remaining);
            final GridElement fe = elem;
            final int gid = id;
            final BigDecimal triggerPrice = elem.getGridPrice();
            final String size = isLong ? negate(String.valueOf(qty)) : String.valueOf(qty);
            final String size = isLong ? negate(qty.toPlainString()) : qty.toPlainString();
            final String orderType = isLong ? ORDER_TYPE_CLOSE_LONG : ORDER_TYPE_CLOSE_SHORT;
            final FuturesPriceTrigger.RuleEnum rule = isLong ? FuturesPriceTrigger.RuleEnum.NUMBER_1
                    : FuturesPriceTrigger.RuleEnum.NUMBER_2;
@@ -3108,7 +3110,7 @@
                                isLong ? "多仓" : "空仓", gid, triggerPrice, size, profitId);
                    }
            );
            remaining -= qty;
            remaining = remaining.subtract(qty);
            placed++;
            id += dir;
        }