GRID_STRATEGY_DESIGN.md 14 KB

微网格策略设计文档(Grid Trading Strategy)

版本: v1.0.0 日期: 2025-10 适用范围: Pacifica DEX 永续合约(BTC/ETH/SOL)


1. 设计目标

1.1 核心理念

Delta≈0 约束下,通过在价格区间内均匀分布买卖订单,捕捉震荡市场的往返价差,同时保持库存中性。

1.2 优势

  • 实现简单:无需复杂信号(OBI/RV/trade flow),只需价格网格
  • 逻辑清晰:买单成交 → 挂卖单;卖单成交 → 挂买单
  • 对冲压力小:成交频率低,可批量对冲
  • 参数稳定:grid_step 基于波动率,无需频繁调参
  • 回测简单:不依赖微观市场结构

1.3 适用场景

  • 震荡市:BTC 在 48k-52k 反复震荡
  • 高波动低趋势:日内波动 >1%,但无明显方向
  • 资金费率对冲有效:双 venue funding correlation > 0.8

1.4 不适用场景

  • 单边趋势:BTC 从 50k 直线涨到 60k(网格全部卖飞)
  • 低波动:日内波动 <0.3%(网格不触发成交)

2. 策略原理

2.1 基本逻辑

初始状态:在当前价格 P₀ 周围布置 N 层网格

买单网格:P₀ * (1 - grid_step), P₀ * (1 - 2*grid_step), ..., P₀ * (1 - grid_range)
卖单网格:P₀ * (1 + grid_step), P₀ * (1 + 2*grid_step), ..., P₀ * (1 + grid_range)

运行规则:
1. 任一买单成交 @ price_buy
   → 在 price_buy * (1 + grid_step) 挂卖单(获利 grid_step)
   → 更新 Delta(+base_sz)

2. 任一卖单成交 @ price_sell
   → 在 price_sell * (1 - grid_step) 挂买单(获利 grid_step)
   → 更新 Delta(-base_sz)

3. Delta 累积到阈值
   → 触发对冲引擎,跨账户对冲

2.2 数学模型

单笔收益

profit_per_round = base_sz * mid_price * grid_step - fees - hedge_cost

费用模型

fees = base_sz * mid_price * (maker_fee_buy + maker_fee_sell)
     ≈ base_sz * mid_price * (-0.02% * 2)  # maker rebate
     = -base_sz * mid_price * 0.04%

hedge_cost = base_sz * mid_price * (hedge_slippage + taker_fee)
           ≈ base_sz * mid_price * (0.3bps + 5bps)
           = base_sz * mid_price * 0.53%

盈亏平衡点

grid_step > (fees + hedge_cost) / base_sz / mid_price
grid_step > 0.53% - 0.04% = 0.49%

实际建议:grid_step ≥ 0.8%(含安全边际)

日收益估算

假设:
- grid_step = 1%
- 日均往返次数 = 5(震荡市)
- base_sz = 0.01 BTC, mid_price = 50000

daily_profit = 5 * (0.01 * 50000 * 1% - 0.01 * 50000 * 0.49%)
             = 5 * (5 - 2.45)
             = 12.75 USD/day

年化收益率(假设 100k 本金):
12.75 * 365 / 100000 = 4.65%

2.3 网格参数设计

grid_step(网格间距)

计算方法:基于历史波动率
- 获取最近 7 天的日内波动率(high - low)/ mid
- 取 P50 波动率作为 grid_step 基准
- 例如:BTC P50 日内波动 = 2.5% → grid_step = 1.0%(约 40% 的日内波动)

推荐值:
  BTC: 0.8% - 1.2%
  ETH: 1.0% - 1.5%
  SOL: 1.5% - 2.5%

grid_range(网格范围)

计算方法:基于极端波动
- 获取最近 30 天的日内最大波动
- grid_range = max_daily_range * 0.7(覆盖 70% 极端情况)

推荐值:
  BTC: 3% - 5%
  ETH: 4% - 6%
  SOL: 6% - 10%

layers(网格层数)

计算方法:
- layers = grid_range / grid_step
- 例如:grid_range = 4%, grid_step = 1% → layers = 4

单边层数限制:
  min: 3 层(太少无法覆盖波动)
  max: 10 层(太多资金分散)

base_sz(单层订单大小)

计算方法:
- 总名义 = max_notional_abs
- 单侧总层数 = layers
- base_sz = (总名义 / mid_price) / layers / 2(买卖各一半)

例如:
  max_notional_abs = 100000 USD
  mid_price = 50000
  layers = 5
  base_sz = (100000 / 50000) / 5 / 2 = 0.2 BTC

2.4 自适应控制(Adaptive Grid)

为适应不同波动环境,Runner 调度 gridMaker.onTick() 每分钟采样一次 mid 价并执行:

  1. 波动率→网格间距映射:使用 VolatilityEstimator 计算最近窗口的小时波动率(bps),按线性映射更新 grid_step_bps,变化超过阈值(默认 20%)时自动 reset()
  2. 中心偏移监控:若当前 mid 偏离网格中心超过 recenter_threshold_bps 且已过冷却期,重置中心并重新布网格。
  3. 对冲挂单超时grid_pending_hedges 超过 hedge_pending_timeout_ms 会产生 warning,避免对冲单长期悬挂。
  4. 指标输出:Prometheus 暴露 grid_step_bps, grid_volatility_hourly_bps, grid_pending_hedges, grid_current_delta(按 symbol)。Grafana 可绘制波动-间距响应曲线。

运行日志示例:

INFO GridMaker adjusting grid step { hourlyVolBps: 420, currentGridStepBps: 30, targetGridStepBps: 80 }
WARN GridMaker pending hedge expired { orderId: "hedge-...", ageMs: 32000 }

3. 风险管理

3.1 趋势行情风险

问题:单边上涨时,买单全部成交,卖单挂空 → 累积多头仓位

解决方案

方案 A:库存上限熔断

risk:
  max_base_abs: 0.8 BTC  # 单边仓位上限

触发条件:abs(delta) > max_base_abs
动作:
  1. 暂停同方向新订单
  2. 仅允许反方向订单(平仓方向)
  3. 触发对冲引擎强制对冲

方案 B:动态网格中心调整

adaptive_grid:
  enabled: true
  recenter_threshold_bps: 200  # 价格偏离初始中心 2%

触发条件:abs(current_price - grid_center) > grid_center * 2%
动作:
  1. 撤销所有旧网格订单
  2. 以 current_price 为新中心重新布网格
  3. 记录调整事件到审计日志

方案 C:趋势检测暂停

trend_filter:
  enabled: true
  lookback_periods: 12  # 12 * 5min = 1 hour
  trend_threshold: 0.5%  # 1 小时涨跌 > 0.5%

触发条件:abs(price_now - price_1h_ago) / price_1h_ago > 0.5%
动作:
  1. 暂停网格策略
  2. 仅保留对冲功能
  3. 趋势结束后(震荡恢复)自动重启

3.2 低波动风险

问题:价格在窄幅震荡,网格不触发成交 → 无收益且占用资金

解决方案

volatility_monitor:
  min_daily_range_bps: 80  # 日内波动 < 0.8% 时告警
  action:
    - 通知人工审查
    - 可选:自动缩小 grid_step 至 0.3%
    - 可选:切换到被动做市策略

3.3 对冲失败风险

问题:网格成交后,对冲账户 API 故障 → 单边敞口暴露

解决方案(复用现有降级策略):

参考 ARCHITECTURE_DESIGN.md 5.5 节降级矩阵:
- 连续 3 次对冲失败 → 主账户切换为"只平不开"模式
- 仅允许平仓方向的网格订单成交

4. 与剥头皮策略对比

维度 微网格 剥头皮 优势方
实现复杂度 200-300 行 800-1000 行 网格
参数敏感度 低(grid_step 基于波动率) 高(spread/tp/sl 需大量校准) 网格
对冲频率 低(2-5 次/小时) 高(10-20 次/小时) 网格
成交依赖 价格往返震荡 短期价格均值回归 网格(更普遍)
DEX 适应性 高(对延迟不敏感) 低(依赖低延迟) 网格
趋势市表现 差(单边持仓) 中性(有止损) 剥头皮
震荡市表现 优(持续收割) 中(信号频繁) 网格
开发周期 2-3 天 2-3 周 网格
理论收益上限 低(1-2%/月) 高(3-5%/月) 剥头皮

结论:网格作为最小可验证策略,适合优先实施以验证对冲架构;若表现良好,可长期运行或叠加剥头皮。


5. 盈利模型与预期

5.1 理论收益拆解

月收益 = 往返次数 * 单次收益 - 固定成本

往返次数:
- 震荡市(波动 2-3%/天):30-50 次/月
- 趋势市(波动 1-2%/天):10-20 次/月

单次收益(grid_step = 1%, base_sz = 0.1 BTC, mid = 50k):
= 0.1 * 50000 * 1% - 0.1 * 50000 * 0.49%
= 50 - 24.5
= 25.5 USD

月收益(震荡市):
= 40 * 25.5
= 1020 USD

月收益率(本金 100k):
= 1020 / 100000
= 1.02%

5.2 风险调整收益(Sharpe Ratio)

假设:
  月收益: 1.02%
  月波动率: 0.8%(网格有库存上限保护)

月 Sharpe = 1.02% / 0.8% = 1.28
年化 Sharpe = 1.28 * sqrt(12) = 4.43

对比:
  剥头皮理论 Sharpe: 2-3(高频高风险)
  网格 Sharpe: 3-5(低频低风险)

5.3 最坏情况分析

场景 1:连续趋势市(30 天单边上涨 15%)

- 网格买单全部成交,卖单挂空
- 累积多头仓位 = max_base_abs = 0.8 BTC
- 对冲成本 = 0.8 * 50000 * 0.53% = 212 USD
- 趋势结束后网格恢复正常
- 最大损失 ≈ 200-300 USD(0.2-0.3%)

场景 2:低波动横盘(30 天波动 <0.5%/天)

- 网格几乎无成交
- 损失 = 0(仅机会成本)
- 可手动切换策略或缩小 grid_step

场景 3:资金费率双重支付

- 双 venue funding 同向支付 0.01%/8h
- 月成本 = 持仓名义 * 0.01% * 90 次
- 最大持仓名义 = max_base_abs * mid = 0.8 * 50000 = 40000
- 月成本 = 40000 * 0.01% * 90 = 360 USD(0.36%)
- 解决:标的筛选器拒绝 funding correlation < 0.8 的 venue 对

6. 配置示例

6.1 保守配置(低风险)

strategy_mode: grid  # 或 scalper, both

grid:
  enabled: true
  symbols:
    - symbol: BTC
      grid_step_bps: 100  # 1%
      grid_range_bps: 400  # 4%
      base_clip_usd: 500  # 单层 500 USD
      max_layers: 4

  # 趋势防护
  adaptive_recenter:
    enabled: true
    recenter_threshold_bps: 200  # 偏离 2% 重置网格

  trend_filter:
    enabled: true
    lookback_periods: 12
    trend_threshold_bps: 50  # 1h 涨跌 > 0.5% 暂停

  # 对冲策略
  hedge_mode: batch  # batch | immediate
  hedge_threshold_base: 0.3  # 累积 0.3 BTC 触发对冲

  # 低波动处理
  volatility_monitor:
    min_daily_range_bps: 80
    action: notify  # notify | reduce_step | switch_strategy

6.2 激进配置(高收益)

grid:
  enabled: true
  symbols:
    - symbol: BTC
      grid_step_bps: 60   # 0.6%(更密集)
      grid_range_bps: 500  # 5%(更宽)
      base_clip_usd: 1000
      max_layers: 8

  adaptive_recenter:
    enabled: true
    recenter_threshold_bps: 300

  trend_filter:
    enabled: false  # 不过滤趋势(承担单边风险)

  hedge_mode: immediate  # 每笔成交立即对冲

  volatility_monitor:
    min_daily_range_bps: 50  # 更低阈值
    action: reduce_step  # 自动缩小 grid_step

6.3 混合配置(网格 + 剥头皮)

strategy_mode: both

grid:
  enabled: true
  # ...保守配置

scalper:
  enabled: true
  trigger:
    spread_bps: 3.0  # 仅极端 spread 触发(避免与网格冲突)
    min_cooldown_ms: 500
  tp_bps: 5
  sl_bps: 10
  max_clip_ratio: 0.2  # 仓位小于网格

# 策略协调
strategy_coordinator:
  priority: [grid, scalper]  # 网格优先
  conflict_resolution: cancel_lower  # 冲突时取消低优先级

7. 回测目标与验证指标

7.1 回测数据要求

data:
  timeframe: 最近 3 个月
  granularity: 1 分钟 OHLCV
  venues: 双 venue 同时回测(验证对冲)

scenarios:
  - 震荡市(2024-08-01 至 2024-08-31)
  - 趋势市(2024-09-01 至 2024-09-30)
  - 低波动(2024-10-01 至 2024-10-15)

7.2 成功标准

盈利指标:
  - 月收益率 > 0.8%(震荡市)
  - 月收益率 > 0.3%(趋势市)
  - Sharpe Ratio > 2.5
  - 最大回撤 < -2%

风控指标:
  - |Delta| P95 < 0.5 * max_base_abs
  - 对冲成功率 > 98%
  - 对冲延迟 P99 < 2s
  - 资金费率净成本 < 收益的 30%

操作指标:
  - 网格订单成交率 > 60%(震荡市)
  - 趋势暂停触发准确率 > 70%
  - 自动重置网格次数 < 5 次/月

8. 下一步行动

8.1 最小可验证产品(MVP)

目标:2-3 天内完成,验证对冲架构

范围:
  - 固定网格(不支持自动调整)
  - 单一标的(BTC)
  - 批量对冲(累积阈值触发)
  - 复用现有 OrderRouter + HedgeEngine

不包括:
  - 趋势检测
  - 动态网格调整
  - 多标的支持
  - 复杂风控

8.2 增强版(v2.0)

目标:1 周内完成,生产级功能

新增:
  - 自适应网格中心调整
  - 趋势检测与暂停
  - 低波动自动缩小 grid_step
  - 多标的并行运行
  - 完整回测报告

8.3 与剥头皮混合(v3.0)

目标:视 v2.0 表现决定

策略:
  - 网格作为底层持续做市
  - 剥头皮叠加在极端 spread 时触发
  - Strategy Coordinator 协调两者冲突

9. 附录:代码示例

9.1 核心网格逻辑(伪代码)

class GridMaker {
  private grids: Map<number, GridLevel> = new Map();
  private filledGrids: Set<number> = new Set();

  async initialize() {
    const mid = this.shadowBook.mid();
    const { grid_step, grid_range, layers } = this.config;

    // 初始化网格
    for (let i = 1; i <= layers; i++) {
      // 买单网格
      const buyPx = mid * (1 - i * grid_step);
      await this.placeGridOrder(i, 'buy', buyPx);

      // 卖单网格
      const sellPx = mid * (1 + i * grid_step);
      await this.placeGridOrder(-i, 'sell', sellPx);
    }
  }

  async onFill(fill: Fill) {
    const gridLevel = this.findGridLevel(fill.orderId);
    if (!gridLevel) return;

    // 标记该层已成交
    this.filledGrids.add(gridLevel.index);

    // 挂对手单
    const oppositeSide = fill.side === 'buy' ? 'sell' : 'buy';
    const oppositePx = fill.side === 'buy'
      ? fill.px * (1 + this.config.grid_step)
      : fill.px * (1 - this.config.grid_step);

    await this.placeGridOrder(
      gridLevel.index,
      oppositeSide,
      oppositePx
    );

    // 更新 Delta 并检查对冲阈值
    this.updateDelta(fill);
    const hedge = await this.hedgeEngine.maybeHedge(this.symbol, this.currentDelta);
    if (Math.abs(hedge.hedged) > 0 && hedge.orderId) {
      this.pendingHedges.set(hedge.orderId, hedge.hedged);
    }
  }
}

文档完成。详细的实施计划见 GRID_IMPLEMENTATION_PLAN.md