Administrator
2026-06-05 1b55621d4dcf3b4ee6b9c4beb81ad69e5b7a5856
refactor(okxNewPrice): 优化止损管理器的挂单数量计算逻辑

- 移除价格差值计算方式,改用简单的计数器递增方式
- 新增多仓和空仓挂单张数计数器,用于跟踪连续止损次数
- 添加计数器重置方法以支持交易重启和订单成交后的状态清理
- 更新日志输出信息以反映新的计数器机制
- 删除不再使用的RoundingMode导入和相关计算逻辑
2 files modified
42 ■■■■■ changed files
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxGridTradeService.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/StopLossManager.java 39 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxGridTradeService.java
@@ -215,6 +215,7 @@
        longPriceQueue.clear();
        currentLongOrderIds.clear();
        currentShortOrderIds.clear();
        stopLossManager.resetAllEntryQuantities();
        // 每次重启重新获取当前本金,确保盈亏对比基准正确
        refreshInitialPrincipal();
@@ -432,6 +433,7 @@
        if (shortGridElement != null && shortGridElement.isHasShortOrder()) {
            int filledQty = Integer.parseInt(shortGridElement.getShortTraderParam().getQuantity());
            stopLossManager.clearShortEntryState(shortGridElement);
            stopLossManager.resetShortEntryQty();
            stopLossManager.extendShortStopLoss(filledQty);
            log.info("[OKX] 空单成交 gridId:{}, qty:{}, 追挂止损", shortGridElement.getId(), filledQty);
            return;
@@ -440,6 +442,7 @@
        if (longGridElement != null && longGridElement.isHasLongOrder()) {
            int filledQty = Integer.parseInt(longGridElement.getLongTraderParam().getQuantity());
            stopLossManager.clearLongEntryState(longGridElement);
            stopLossManager.resetLongEntryQty();
            stopLossManager.extendLongStopLoss(filledQty);
            log.info("[OKX] 多单成交 gridId:{}, qty:{}, 追挂止损", longGridElement.getId(), filledQty);
            return;
src/main/java/com/xcong/excoin/modules/okxNewPrice/StopLossManager.java
@@ -3,7 +3,6 @@
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
 * 止损管理器 — 负责基底止损单挂载、止损触发后的逐步缩进、以及止损追挂。
@@ -25,6 +24,11 @@
    private final OkxConfig config;
    private final OkxTradeExecutor executor;
    /** 多仓挂单张数计数器:止损触发时递增后再使用;挂单成交后重置为1 */
    private volatile int longEntryQty = 1;
    /** 空仓挂单张数计数器:止损触发时递增后再使用;挂单成交后重置为1 */
    private volatile int shortEntryQty = 1;
    public StopLossManager(OkxConfig config, OkxTradeExecutor executor) {
        this.config = config;
@@ -105,14 +109,11 @@
        }
        BigDecimal triggerPrice = newEntryGrid.getGridPrice();
        BigDecimal priceDiff = longEntryPrice.subtract(triggerPrice).abs();
        BigDecimal epsilon = new BigDecimal("0.00000001");
        int count = priceDiff.add(epsilon).divide(config.getStep(), 0, RoundingMode.DOWN).intValue();
        count = Math.max(1, count);
        int entryQty = count * Integer.parseInt(config.getQuantity());
        longEntryQty++;
        int entryQty = longEntryQty * Integer.parseInt(config.getQuantity());
        String size = String.valueOf(entryQty);
        log.info("[OKX] 多仓止损触发 gridId:{}, 在gridId:{}挂{}张多单(价差:{},步长:{},count:{},qty:{})",
                gridId, newEntryGridId, entryQty, priceDiff, config.getStep(), count, config.getQuantity());
        log.info("[OKX] 多仓止损触发 gridId:{}, 在gridId:{}挂{}张多单(计数器:{}, qty:{})",
                gridId, newEntryGridId, entryQty, longEntryQty, config.getQuantity());
        newEntryGrid.getLongTraderParam().setQuantity(size);
        placeEntryOrderWithPreFlag(newEntryGrid, true, triggerPrice, size);
    }
@@ -148,14 +149,11 @@
        }
        BigDecimal triggerPrice = newEntryGrid.getGridPrice();
        BigDecimal priceDiff = shortEntryPrice.subtract(triggerPrice).abs();
        BigDecimal epsilon = new BigDecimal("0.00000001");
        int count = priceDiff.add(epsilon).divide(config.getStep(), 0, RoundingMode.DOWN).intValue();
        count = Math.max(1, count);
        int entryQty = count * Integer.parseInt(config.getQuantity());
        shortEntryQty++;
        int entryQty = shortEntryQty * Integer.parseInt(config.getQuantity());
        String size = String.valueOf(entryQty);
        log.info("[OKX] 空仓止损触发 gridId:{}, 在gridId:{}挂{}张空单(价差:{},步长:{},count:{},qty:{})",
                gridId, newEntryGridId, entryQty, priceDiff, config.getStep(), count, config.getQuantity());
        log.info("[OKX] 空仓止损触发 gridId:{}, 在gridId:{}挂{}张空单(计数器:{}, qty:{})",
                gridId, newEntryGridId, entryQty, shortEntryQty, config.getQuantity());
        newEntryGrid.getShortTraderParam().setQuantity(size);
        placeEntryOrderWithPreFlag(newEntryGrid, false, triggerPrice, size);
    }
@@ -299,4 +297,15 @@
        gridElement.setShortTakeProfitOrderId(profitId);
        OkxGridElement.refreshIndices();
    }
    // ========== 计数器管理 ==========
    /** 重置多仓挂单张数计数器(挂单成交后调用) */
    public void resetLongEntryQty() { longEntryQty = 1; }
    /** 重置空仓挂单张数计数器(挂单成交后调用) */
    public void resetShortEntryQty() { shortEntryQty = 1; }
    /** 重置全部挂单张数计数器(startGrid时调用) */
    public void resetAllEntryQuantities() { longEntryQty = 1; shortEntryQty = 1; }
}