# Grid Trading System

> grid-trading-system

- Skill: `54laowang/grid-trading-system` (Agent Skill)
- Install (CLI): `npx skillmds@latest add 54laowang/grid-trading-system`
- Raw SKILL.md: https://api.skillmd.com/api/skills/54laowang/grid-trading-system/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: 54laowang (https://skillmd.com/u/54laowang)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/54laowang/grid-trading-system

---


# grid-trading-system

ETF网格交易执行系统 - 整合自 `grid-trading-monitor` (608行)，采用达尔文进化方法论。

## 核心定位

**交易执行层**：专注单一ETF的网格交易自动化执行，与监控预警层协同工作。

## 架构设计

### 六大核心模块

```
┌─────────────────────────────────────────────────────────┐
│                  grid-trading-system                     │
├─────────────────────────────────────────────────────────┤
│  1. ConfigManager       配置管理模块                     │
│  2. MarketDataFetcher   行情获取模块                     │
│  3. TradingCalendar     交易日历模块                     │
│  4. TriggerDetector     触发检测模块                     │
│  5. TradeExecutor       交易执行模块                     │
│  6. StateManager        状态管理模块                     │
└─────────────────────────────────────────────────────────┘
```

---

## 模块一：ConfigManager（配置管理模块）

### 核心职责

- 加载网格参数配置（基准价、间距、格数、金额）
- 验证配置完整性（必填字段检查）
- 支持多品种配置管理
- 配置热更新（无需重启）

### 配置文件位置

`~/.hermes/grid-trading/config.json`

### 配置示例

```json
{
  "symbol": "513130",
  "name": "恒生科技ETF",
  "base_price": 0.625,
  "grid_spacing": 0.025,
  "grid_spacing_pct": 0.04,
  "upper_grids": 6,
  "lower_grids": 8,
  "amount_per_grid": 715,
  "initial_position": 3,
  "total_capital": 10000,
  "last_updated": "2026-05-02T10:00:00Z"
}
```

### ✅ 检查点（4个）

| 检查点 | 检查内容 | 通过标准 |
|--------|---------|---------|
| **CP-CONFIG-01** | 配置文件是否存在 | `os.path.exists(config_path)` |
| **CP-CONFIG-02** | JSON格式是否合法 | `json.load()` 无异常 |
| **CP-CONFIG-03** | 必填字段是否完整 | 所有必填字段存在且非空 |
| **CP-CONFIG-04** | 数值范围是否合理 | 基准价>0、间距>0、格数>0、金额>0 |

### ⚠️ 异常处理（4个）

| 异常场景 | 处理策略 | 日志级别 |
|---------|---------|---------|
| **文件不存在** | 使用默认配置 + 警告 | WARNING |
| **JSON解析失败** | 拒绝运行 + 错误提示 | ERROR |
| **字段缺失** | 使用默认值 + 警告 | WARNING |
| **数值异常** | 拒绝运行 + 错误提示 | ERROR |

### 🔲 边界条件（6个）

| 边界条件 | 触发场景 | 处理方式 |
|---------|---------|---------|
| **BC-CONFIG-01** | 基准价≤0 | 拒绝加载，记录错误 |
| **BC-CONFIG-02** | 间距≤0或>基准价50% | 拒绝加载，记录错误 |
| **BC-CONFIG-03** | 格数为0或负数 | 拒绝加载，记录错误 |
| **BC-CONFIG-04** | 金额为0或负数 | 拒绝加载，记录错误 |
| **BC-CONFIG-05** | 上方格数≠下方格数（不对称网格） | 允许，记录INFO日志 |
| **BC-CONFIG-06** | 配置文件编码非UTF-8 | 自动转换或拒绝加载 |

---

## 模块二：MarketDataFetcher（行情获取模块）

### 核心职责

- 四重数据源冗余（新浪→腾讯→东财→AkShare）
- 自动切换失败数据源
- 响应时间监控
- 价格一致性验证

### 数据源优先级

| 优先级 | 数据源 | API | 响应时间 | 状态 |
|--------|--------|-----|---------|------|
| **P0** | 新浪财经 | `http://hq.sinajs.cn/list={symbol}` | ~129ms | ✅ 正常 |
| **P1** | 腾讯财经 | `http://qt.gtimg.cn/q={symbol}` | ~121ms | ✅ 正常 |
| **P2** | 东方财富 | `http://push2.eastmoney.com/api/qt/stock/get` | ~271ms | ✅ 正常 |
| **P3** | AkShare | `ak.fund_etf_spot_em()` | ~17秒 | ✅ 正常 |

### ✅ 检查点（4个）

| 检查点 | 检查内容 | 通过标准 |
|--------|---------|---------|
| **CP-MARKET-01** | 数据源响应状态 | HTTP 200 |
| **CP-MARKET-02** | 价格数值有效性 | 价格>0 |
| **CP-MARKET-03** | 时间戳新鲜度 | 时间戳<5分钟 |
| **CP-MARKET-04** | 多源价格差异 | 差异<0.1% |

### ⚠️ 异常处理（4个）

| 异常场景 | 处理策略 | 日志级别 |
|---------|---------|---------|
| **数据源超时（>10秒）** | 切换下一数据源 | WARNING |
| **价格解析失败** | 尝试下一数据源 | WARNING |
| **所有数据源失败** | 返回None + 错误日志 | ERROR |
| **价格差异>0.1%** | 记录警告 + 使用中位数 | WARNING |

### 🔲 边界条件（6个）

| 边界条件 | 触发场景 | 处理方式 |
|---------|---------|---------|
| **BC-MARKET-01** | 网络完全断开 | 返回None，记录错误 |
| **BC-MARKET-02** | 所有数据源同时失效 | 返回None，推送错误通知 |
| **BC-MARKET-03** | 返回价格=0或负数 | 拒绝使用，切换数据源 |
| **BC-MARKET-04** | 时间戳未来时间（时钟错误） | 拒绝使用，记录错误 |
| **BC-MARKET-05** | ETF停牌（价格不变） | 检测连续3次价格相同，标记停牌 |
| **BC-MARKET-06** | 数据源限流（429错误） | 延迟重试或切换数据源 |

---

## 模块三：TradingCalendar（交易日历模块）

### 核心职责

- 判断是否交易日（排除周末+法定假期）
- 判断是否交易时段（09:30-11:30、13:00-15:00）
- 交易日历缓存（避免重复查询）

### 交易时段划分

| 北京时间 | 状态 | 监控建议 |
|---------|------|---------|
| < 09:25 | 盘前 | 不监控 |
| 09:25-09:30 | 集合竞价 | 可监控 |
| 09:30-11:30 | 早盘 | **监控中** |
| 11:30-13:00 | 午间休市 | 不监控 |
| 13:00-15:00 | 午盘 | **监控中** |
| ≥ 15:00 | 收盘 | 不监控 |

### ✅ 检查点（3个）

| 检查点 | 检查内容 | 通过标准 |
|--------|---------|---------|
| **CP-TIME-01** | AkShare交易日历可用性 | 查询成功 |
| **CP-TIME-02** | 日期格式正确性 | YYYY-MM-DD格式 |
| **CP-TIME-03** | 交易时段边界判断 | 时段划分正确 |

### ⚠️ 异常处理（3个）

| 异常场景 | 处理策略 | 日志级别 |
|---------|---------|---------|
| **AkShare查询失败** | 使用简单判断（排除周末） | WARNING |
| **日期格式错误** | 使用当前日期 | WARNING |
| **缓存过期** | 重新查询 | INFO |

### 🔲 边界条件（6个）

| 边界条件 | 触发场景 | 处理方式 |
|---------|---------|---------|
| **BC-TIME-01** | 五一/国庆/春节长假 | 正确识别为非交易日 |
| **BC-TIME-02** | 周末调休工作日（股市不开盘） | 使用交易日历，不依赖星期几 |
| **BC-TIME-03** | 11:30-13:00午休时段 | 不触发交易 |
| **BC-TIME-04** | 15:00后收盘时段 | 不触发交易 |
| **BC-TIME-05** | 09:25集合竞价时段 | 可监控但不交易 |
| **BC-TIME-06** | 数据源时区不一致 | 强制转换为北京时间 |

---

## 模块四：TriggerDetector（触发检测模块）

### 核心职责

- 计算网格价位（买入/卖出档位）
- 检测价格穿越网格线
- 避免重复触发（同一档位冷却期）
- 触发信号生成

### 网格计算公式

```python
# 买入网格（下方）
buy_grid_price = base_price - grid_spacing × grid_level

# 卖出网格（上方）
sell_grid_price = base_price + grid_spacing × grid_level
```

### 触发逻辑

```python
# 买入触发：价格跌破网格价
if grid["type"] == "BUY" and current_price <= grid["price"]:
    return grid

# 卖出触发：价格突破网格价
if grid["type"] == "SELL" and current_price >= grid["price"]:
    return grid
```

### ✅ 检查点（5个）

| 检查点 | 检查内容 | 通过标准 |
|--------|---------|---------|
| **CP-TRIGGER-01** | 价格是否在网格范围内 | min_grid ≤ price ≤ max_grid |
| **CP-TRIGGER-02** | 是否穿越网格线 | 价格穿越网格价 |
| **CP-TRIGGER-03** | 档位冷却期检查 | 距上次触发>冷却时间 |
| **CP-TRIGGER-04** | 持仓上限检查（卖出时） | 持仓>0 |
| **CP-TRIGGER-05** | 资金下限检查（买入时） | 可用资金≥单格金额 |

### ⚠️ 异常处理（4个）

| 异常场景 | 处理策略 | 日志级别 |
|---------|---------|---------|
| **价格超出网格范围** | 记录日志 + 不触发 | INFO |
| **冷却期内重复触发** | 忽略 | DEBUG |
| **持仓不足卖出** | 记录错误 + 不执行 | ERROR |
| **资金不足买入** | 记录错误 + 不执行 | ERROR |

### 🔲 边界条件（6个）

| 边界条件 | 触发场景 | 处理方式 |
|---------|---------|---------|
| **BC-TRIGGER-01** | 价格触及网格边界（最高/最低档） | 触发交易 + 标记边界 |
| **BC-TRIGGER-02** | 连续穿越多档（快速涨跌） | 只触发最接近的一档 |
| **BC-TRIGGER-03** | 价格刚好等于网格价（边界条件） | 触发交易（允许边界触发） |
| **BC-TRIGGER-04** | 持仓=0时触发卖出 | 拒绝执行，记录错误 |
| **BC-TRIGGER-05** | 资金=0时触发买入 | 拒绝执行，记录错误 |
| **BC-TRIGGER-06** | 网格间距过小（频繁触发） | 警告间距过小，建议调整 |

---

## 模块五：TradeExecutor（交易执行模块）

### 核心职责

- 生成交易指令（模拟交易）
- 更新持仓状态
- 记录交易历史
- 计算盈亏

### 交易执行流程

```
触发信号 → 生成交易指令 → 更新持仓 → 记录历史 → 计算盈亏
```

### ✅ 检查点（3个）

| 检查点 | 检查内容 | 通过标准 |
|--------|---------|---------|
| **CP-EXEC-01** | 交易指令完整性 | 所有字段存在且合法 |
| **CP-EXEC-02** | 状态更新一致性 | 状态文件正确更新 |
| **CP-EXEC-03** | 历史记录追加成功 | 历史文件正确追加 |

### ⚠️ 异常处理（3个）

| 异常场景 | 处理策略 | 日志级别 |
|---------|---------|---------|
| **状态文件写入失败** | 重试3次 | ERROR |
| **历史文件损坏** | 备份 + 重建 | ERROR |
| **计算错误** | 回滚状态 | ERROR |

### 🔲 边界条件（5个）

| 边界条件 | 触发场景 | 处理方式 |
|---------|---------|---------|
| **BC-EXEC-01** | 首笔交易（初始建仓） | 正常执行，初始化持仓 |
| **BC-EXEC-02** | 最后一档平仓 | 正常执行，标记空仓 |
| **BC-EXEC-03** | 满仓状态 | 拒绝买入，允许卖出 |
| **BC-EXEC-04** | 空仓状态 | 拒绝卖出，允许买入 |
| **BC-EXEC-05** | 单日多次交易 | 正常执行，记录所有交易 |

---

## 模块六：StateManager（状态管理模块）

### 核心职责

- 持久化当前持仓、历史交易
- 状态恢复（重启后继续）
- 状态备份（防止丢失）

### 状态文件位置

`~/.hermes/grid-trading/status.json`

### 状态文件结构

```json
{
  "symbol": "513130",
  "current_position": 3,
  "cash": 7850,
  "grid_states": [
    {
      "level": 1,
      "type": "SELL",
      "price": 0.65,
      "status": "WAITING"
    }
  ],
  "trade_history": [
    {
      "timestamp": "2026-05-02T10:15:00Z",
      "type": "BUY",
      "level": 2,
      "price": 0.575,
      "amount": 715
    }
  ],
  "last_updated": "2026-05-02T10:15:00Z"
}
```

### ✅ 检查点（4个）

| 检查点 | 检查内容 | 通过标准 |
|--------|---------|---------|
| **CP-STATE-01** | 状态文件完整性 | 所有必填字段存在 |
| **CP-STATE-02** | JSON格式正确性 | `json.load()` 无异常 |
| **CP-STATE-03** | 时间戳更新 | 更新时间戳为当前时间 |
| **CP-STATE-04** | 备份文件存在 | `status.json.bak` 存在 |

### ⚠️ 异常处理（3个）

| 异常场景 | 处理策略 | 日志级别 |
|---------|---------|---------|
| **文件损坏** | 从备份恢复 | ERROR |
| **备份也损坏** | 从头初始化 | ERROR |
| **并发写入冲突** | 文件锁 | WARNING |

### 🔲 边界条件（4个）

| 边界条件 | 触发场景 | 处理方式 |
|---------|---------|---------|
| **BC-STATE-01** | 首次运行（无状态文件） | 初始化状态文件 |
| **BC-STATE-02** | 状态文件过大（>10MB） | 归档历史 + 重建 |
| **BC-STATE-03** | 历史记录超长（>1000条） | 归档历史 + 重建 |
| **BC-STATE-04** | 异常中断后的状态恢复 | 从备份恢复或重建 |

---

## 运行模式

### 1. 查看当前状态

```bash
python ~/.hermes/grid-trading/grid_monitor.py --status
```

### 2. 单次检查（Cronjob模式）

```bash
python ~/.hermes/grid-trading/grid_monitor.py --check
```

输出 JSON 格式，便于 Cronjob 解析：

```json
{
  "symbol": "513130",
  "current_price": 0.612,
  "triggered": {
    "type": "BUY",
    "level": 2,
    "price": 0.575
  },
  "position": 3,
  "cash": 7850
}
```

### 3. 持续监控（实时盯盘）

```bash
python ~/.hermes/grid-trading/grid_monitor.py --monitor --interval 30
```

---

## Cronjob 集成

### 配置示例

```yaml
name: 网格交易监控-恒生科技ETF
schedule: "*/5 9-11,13-15 * * 1-5"  # 交易时间每5分钟
prompt: |
  执行网格交易检查：
  1. 运行 python ~/.hermes/grid-trading/grid_monitor.py --check
  2. 如果有 triggered 字段，推送微信提醒
enabled_toolsets: ["terminal", "send_message"]
```

---

## 微信推送格式

```
📊 恒生科技ETF 网格交易提醒

📉/📈 [买入/卖出] 信号触发

💹 触发价格: X.XXX 元
📊 成交档位: Lv+X
💰 成交金额: 5,000 元
💼 当前持仓: X 格
⏰ 时间: YYYY-MM-DD HH:MM:SS
```

---

## 与 market-intelligence-system 协作

### 接收数据

| 数据类型 | 来源模块 | 用途 |
|---------|---------|------|
| **市场预警信号** | MarketMonitor | 异常波动时暂停交易 |
| **交易日历更新** | TimeAnchor | 假期调整 |
| **数据源健康度** | DataSourceManager | 切换数据源 |

### 发送数据

| 数据类型 | 目标模块 | 用途 |
|---------|---------|------|
| **交易信号** | BriefGenerator | 简报展示 |
| **持仓状态** | BriefGenerator | 简报展示 |
| **异常事件** | PushNotifier | 错误通知 |

---

## 风险提示

| 风险类型 | 说明 | 应对策略 |
|---------|------|---------|
| **单边上涨** | 踏空（卖飞），错过后续涨幅 | 预留部分底仓 |
| **单边下跌** | 持续补仓，可能满仓套牢 | 设置最大持仓上限 |
| **震荡市** | 最佳场景，持续吃差价 | 正常运行 |
| **仓位控制** | 需预留资金应对下跌 | 设置资金下限 |

---

## 完整度统计

| 检查项 | 目标 | 实际 | 达标 |
|--------|------|------|------|
| **检查点** | 15+ | 23 | ✅ |
| **异常处理** | 10+ | 21 | ✅ |
| **边界条件** | 15+ | 33 | ✅ |
| **完整度** | 100% | 100% | ✅ |

---

## 整合成果

- **源 Skill**: grid-trading-monitor (608行)
- **整合后**: grid-trading-system (本文件)
- **核心改进**:
  - 模块化架构（6大模块）
  - 完整的检查点机制（23个）
  - 系统化异常处理（21处）
  - 边界条件全覆盖（33项）
  - 与监控预警层协同工作

---

## 参考

- 原始 Skill: `~/.hermes/skills/finance/grid-trading-monitor/SKILL.md`
- 监控脚本: `~/.hermes/grid-trading/grid_monitor.py`
- 配置文件: `~/.hermes/grid-trading/config.json`
- 状态文件: `~/.hermes/grid-trading/status.json`

---

## ⚠️ Known Gotchas

### 交易执行问题

- **交易失败**: 余额不足
  ```python
  # 检查可用资金
  available = broker.get_available_cash()
  if available < required:
      print("资金不足，无法执行交易")
  ```

- **滑点过大**: 市价单偏离预期
  ```python
  # 使用限价单
  order = broker.place_limit_order(
      price=current_price * 0.99,  # 1% 滑点容忍
      quantity=100
  )
  ```

### 网格配置问题

- **网格过密**: 手续费侵蚀利润
  ```python
  # 计算最小网格间距
  min_spacing = fee_rate * 2  # 至少覆盖双向手续费
  
  # 例如: 手续费 0.1%
  # 最小间距 = 0.2%
  ```

- **网格过疏**: 错过交易机会
  ```python
  # 根据波动率调整
  if volatility < 0.02:  # 低波动
      spacing = 0.01  # 1%
  else:  # 高波动
      spacing = 0.02  # 2%
  ```

### 监控问题

- **推送失败**: 通知渠道失效
  ```bash
  # 检查企业微信 Webhook
  curl -X POST $WECOM_WEBHOOK_URL     -d '{"msgtype": "text", "text": {"content": "test"}}'
  ```

- **数据源中断**: 行情获取失败
  ```python
  # 多数据源切换
  try:
      price = get_price_from_sina(code)
  except:
      price = get_price_from_eastmoney(code)
  ```

