From e66520b5da9198bfe3154143844d632f8aedd64b Mon Sep 17 00:00:00 2001
From: dongzp_book <90fanhua@gmail.com>
Date: Mon, 20 Jul 2026 22:15:09 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8C=82=E5=8D=95=E6=92=A4=E5=8D=95=E6=96=B0?=
=?UTF-8?q?=E5=A2=9E=E5=8F=82=E6=95=B0cancel=5Fgrid=5Fcount?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
.../trend/strategy/AutoGridStrategy.java | 41 +++++++++++--------
2 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/pom.xml b/pom.xml
index 2dc4bb2..ee24d4a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
* 网格间距 = atr_multiplier × ATR,并限制在 [min_gap, max_gap] 区间。 * 下方买单始终最多挂 1 笔:成交后再挂下一格,不会批量铺满网格。 - * 若现价相对挂单价上行超过间距 × 1.5,撤单并按现价重新挂靠下一格,避免买单悬空。 + * 若挂单价低于「现价 − 撤单网格数 × 间距」,撤单并按现价重新挂靠下一格,避免买单长期悬空。 * 采用限价挂单买入,买单成交后在「入场价 + 间距」挂限价卖单止盈。 * 网格间距变化时不撤销已有挂单,已挂卖单价格保持不变。 */ public class AutoGridStrategy extends BaseStrategy { private static final String MARGIN_MODE = "crossed"; - /** - * 现价高于挂单价超过「间距 × 该倍数」时,撤单重挂 - */ - private static final BigDecimal BUY_REBASE_MULTIPLIER = new BigDecimal("1.5"); private final Logger logger = LoggerFactory.getLogger(AutoGridStrategy.class); @@ -68,6 +64,10 @@ public class AutoGridStrategy extends BaseStrategy { * 最大持仓层数;达到后不再新建买单。待成交买单始终最多 1 笔。 */ private int gridCount; + /** + * 撤单网格数 N:挂单价低于「现价 − N × 间距」时撤单重挂(例:间距 5、N=5 → 撤现价−25 以下的买单)。 + */ + private int cancelGridCount; // 精度 private int pricePrecision = 2; @@ -264,7 +264,7 @@ public class AutoGridStrategy extends BaseStrategy { tryParams("base_quantity", "atr_multiplier", "grid_grp_script", "kline_interval", "kline_period", "grid_adjust_interval", "min_gap", "max_gap", "upper_bound", "lower_bound", - "grid_count", "test_mode"); + "grid_count", "cancel_grid_count", "test_mode"); baseQuantity = getRunParams().getBigDecimal("base_quantity"); atrMultiplier = getRunParams().getBigDecimal("atr_multiplier"); @@ -285,6 +285,10 @@ public class AutoGridStrategy extends BaseStrategy { if (gridCount <= 0) { throw new IllegalArgumentException("grid_count 必须大于 0"); } + cancelGridCount = getRunParams().getInteger("cancel_grid_count"); + if (cancelGridCount <= 0) { + throw new IllegalArgumentException("cancel_grid_count 必须大于 0"); + } if (lowerBound.compareTo(upperBound) >= 0) { throw new IllegalArgumentException("lower_bound 必须小于 upper_bound"); @@ -432,6 +436,7 @@ public class AutoGridStrategy extends BaseStrategy { variables.put("upperBound", upperBound == null ? null : upperBound.doubleValue()); variables.put("lowerBound", lowerBound == null ? null : lowerBound.doubleValue()); variables.put("gridCount", gridCount); + variables.put("cancelGridCount", cancelGridCount); variables.put("leverage", leverage); variables.put("pricePrecision", pricePrecision); variables.put("quantityPrecision", quantityPrecision); @@ -521,11 +526,12 @@ public class AutoGridStrategy extends BaseStrategy { /** * 价格单边上行时,下方买单会悬空永远不成交。 - * 当 现价 - 挂单价 > 间距 × 1.5 时,撤单并按现价重新对齐挂单(例:1532 / 间距 5 → 1530)。 + * 当挂单价低于「现价 − 撤单网格数 × 间距」时,撤单并按现价重新对齐挂单 + * (例:现价 1532、间距 5、撤单网格数 5 → 撤销 1507 以下的买单,再挂到现价下方一格)。 */ private void rebaseStalePendingBuy() { if (!canPlaceBuyOrders() || currentPrice == null || currentGridGap == null - || currentGridGap.compareTo(BigDecimal.ZERO) <= 0) { + || currentGridGap.compareTo(BigDecimal.ZERO) <= 0 || cancelGridCount <= 0) { return; } @@ -535,9 +541,10 @@ public class AutoGridStrategy extends BaseStrategy { } GridBuyOrder pending = pendingBuyOrders.values().iterator().next(); - BigDecimal distance = currentPrice.subtract(pending.buyPrice); - BigDecimal threshold = currentGridGap.multiply(BUY_REBASE_MULTIPLIER); - if (distance.compareTo(threshold) <= 0) { + BigDecimal cancelBelow = currentPrice.subtract( + currentGridGap.multiply(BigDecimal.valueOf(cancelGridCount))); + // 只撤「现价 − N×间距」以下的挂单,避免半格内频繁追价 + if (pending.buyPrice.compareTo(cancelBelow) >= 0) { return; } @@ -549,12 +556,13 @@ public class AutoGridStrategy extends BaseStrategy { try { bitGetClient.cancelOrder(getSymbol(), pending.exchangeOrderId, pending.clientOrderId, null); pendingBuyOrders.remove(priceKey(pending.buyPrice)); - logger.info("买单距现价过远,撤单重挂:旧价={},现价={},间距={},阈值={},新价={}", - pending.buyPrice, currentPrice, currentGridGap, threshold, newPrice); + logger.info("买单距现价过远,撤单重挂:旧价={},现价={},间距={},撤单网格数={},撤单线={},新价={}", + pending.buyPrice, currentPrice, currentGridGap, cancelGridCount, cancelBelow, newPrice); submitAlarm("买单追价重挂", - String.format("旧挂单价 %s,现价 %s,超过间距×1.5(%s),重挂至 %s", - formatPrice(pending.buyPrice), formatPrice(currentPrice), - formatPrice(threshold), formatPrice(newPrice)), + String.format("旧挂单价 %s 低于撤单线 %s(现价 %s − %d×间距 %s),重挂至 %s", + formatPrice(pending.buyPrice), formatPrice(cancelBelow), + formatPrice(currentPrice), cancelGridCount, formatPrice(currentGridGap), + formatPrice(newPrice)), AlarmLevel.INFO); placeLimitBuyOrder(newPrice); } catch (Exception e) { @@ -1214,6 +1222,7 @@ public class AutoGridStrategy extends BaseStrategy { sb.append("