# 微网格策略设计文档（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（网格间距）
```yaml
计算方法：基于历史波动率
- 获取最近 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（网格范围）
```yaml
计算方法：基于极端波动
- 获取最近 30 天的日内最大波动
- grid_range = max_daily_range * 0.7（覆盖 70% 极端情况）

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

#### layers（网格层数）
```yaml
计算方法：
- layers = grid_range / grid_step
- 例如：grid_range = 4%, grid_step = 1% → layers = 4

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

#### base_sz（单层订单大小）
```yaml
计算方法：
- 总名义 = 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：库存上限熔断
```yaml
risk:
  max_base_abs: 0.8 BTC  # 单边仓位上限

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

#### 方案 B：动态网格中心调整
```yaml
adaptive_grid:
  enabled: true
  recenter_threshold_bps: 200  # 价格偏离初始中心 2%

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

#### 方案 C：趋势检测暂停
```yaml
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 低波动风险

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

**解决方案**：

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

### 3.3 对冲失败风险

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

**解决方案**（复用现有降级策略）：

```yaml
参考 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）

```yaml
假设：
  月收益: 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 保守配置（低风险）

```yaml
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 激进配置（高收益）

```yaml
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 混合配置（网格 + 剥头皮）

```yaml
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 回测数据要求

```yaml
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 成功标准

```yaml
盈利指标：
  - 月收益率 > 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 天内完成，验证对冲架构

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

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

### 8.2 增强版（v2.0）

**目标**：1 周内完成，生产级功能

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

### 8.3 与剥头皮混合（v3.0）

**目标**：视 v2.0 表现决定

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

---

## 9. 附录：代码示例

### 9.1 核心网格逻辑（伪代码）

```typescript
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`。
