Administrator
3 days ago f6080a67720f6241564589bb5b074661d8157f0f
refactor(gateApi): 优化止损追单逻辑实现

- 将多仓止损追单改为全量持仓拆分模式,从近到远连续挂单
- 空仓止损追单同步调整为全量持仓保护策略
- 止损计算从 min 取值改为 max 取值,确保基础仓位安全
- 添加防重入标记和待重挂机制,增强并发安全性
- 重构注释说明,明确连续网格挂单的分配规则
- 统一长短仓止损逻辑,提升代码一致性和可维护性
1 files modified
24 ■■■■■ changed files
src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/gateApi/GateGridTradeService.java
@@ -2394,8 +2394,10 @@
    // ========== 止损追单(新逻辑:3 个固定位置,每个位置挂多个 1 张止损单) ==========
    /**
     * 多仓止损追单 — 网格数量 = baseQuantity/quantity,从近到远分配。
     * aCount<0跳过, aCount=0→主=2, aCount=1→主=2,辅0=1, aCount>=2→主=aCount,辅依次填1
     * 多仓止损追单 — 把当前多头持仓<b>全量</b>拆分为多笔止损单,挂在靠近入场的连续网格上。
     * 网格数 gridCount = baseQuantity / quantity;最近网格挂大部分张数、其余网格各挂 1 笔 quantity 张,
     * 不足一格的余数单独在更远一网格挂一笔。所有异步挂单完成后通过计数器重置防重入标记;
     * 期间若有入场单成交则打 pendingStopLossReExtend 待重挂。
     */
    private void extendLongStopLoss(int filledQty, int gridId) {
        int qty = Integer.parseInt(config.getQuantity());
@@ -2408,9 +2410,9 @@
            return;
        }
        // [Gate] 止损只针对初始开仓仓位(baseQuantity),加仓部分只做止盈;
        // 持仓不足一个网格量时也按剩余张数挂一张止损(手动重建场景,避免裸奔)
        int slSize = Math.min(filledQty, baseQty);
        // [Gate] 止损覆盖全持仓:加仓部分同样受止损保护,不再只保初始仓位。
        // 取 max 是为了在 REST 时序竞态导致 filledQty 偏小时,至少保住 baseQuantity 的基础仓位
        int slSize = Math.max(filledQty, baseQty);
        int totalOrders = slSize / qty;
        int remainder = slSize % qty;
        int[] orders = new int[gridCount];
@@ -2471,8 +2473,10 @@
    }
    /**
     * 空仓止损追单 — 网格数量 = baseQuantity/quantity,从近到远分配。
     * aCount<0跳过, aCount=0→主=2, aCount=1→主=2,辅0=1, aCount>=2→主=aCount,辅依次填1
     * 空仓止损追单 — 把当前空头持仓<b>全量</b>拆分为多笔止损单,挂在靠近入场的连续网格上。
     * 网格数 gridCount = baseQuantity / quantity;最近网格挂大部分张数、其余网格各挂 1 笔 quantity 张,
     * 不足一格的余数单独在更远一网格挂一笔。所有异步挂单完成后通过计数器重置防重入标记;
     * 期间若有入场单成交则打 pendingStopLossReExtend 待重挂。
     */
    private void extendShortStopLoss(int filledQty, int gridId) {
        int qty = Integer.parseInt(config.getQuantity());
@@ -2485,9 +2489,9 @@
            return;
        }
        // [Gate] 止损只针对初始开仓仓位(baseQuantity),加仓部分只做止盈;
        // 持仓不足一个网格量时也按剩余张数挂一张止损(手动重建场景,避免裸奔)
        int slSize = Math.min(filledQty, baseQty);
        // [Gate] 止损覆盖全持仓:加仓部分同样受止损保护,不再只保初始仓位。
        // 取 max 是为了在 REST 时序竞态导致 filledQty 偏小时,至少保住 baseQuantity 的基础仓位
        int slSize = Math.max(filledQty, baseQty);
        int totalOrders = slSize / qty;
        int remainder = slSize % qty;
        int[] orders = new int[gridCount];