---
title: MoFin 系统数据库统一 - 需求与实施计划
tags: [MoFin, 数据库, 需求文档, 当前工作]
status: 活跃
priority: P0（当前）
created: 2026-06-20
---

# MoFin 系统数据库统一 - 需求与实施计划

## 一、当前状态

### 已完成的管道

```
market_watch.py（每30分，no_agent）
  → 拉取同花顺90个行业板块数据
  → 写入 market.json（最新快照，仅存当前值，无历史）

市场精选推荐-每日（16:00，LLM cron）
  → 读 market.json → 全市场分析
  → 选热门行业 → 查个股实时价 → 候选池 → 星级推荐
  → 写入 candidate_pool.json + 输出报告给老爸
```

### 核心问题

所有数据以 JSON 文件散落存储，**无历史记录、无关联查询能力**：

| 问题 | 影响 |
|------|------|
| market.json 只存最新快照 | 看不到板块涨跌趋势、资金流向变化 |
| 个股不知自己所属板块，板块不知有哪些成分股 | 无法 SQL join 持仓→板块→趋势 |
| 评分/策略变更无历史 | 看不到候选评分变化趋势 |
| 各 JSON 之间无外键约束 | 数据一致性全靠代码保证 |

---

## 二、目标

**将 MoFin 全部数据纳入统一 SQLite 数据库（mofin.db），实现：**

- 数据关系化（持仓 ↔ 板块 ↔ 趋势，一条 SQL 直连）
- 历史可追溯（板块快照、评分变更、策略版本全部时序存储）
- 操作 no_agent 化（常用查询/告警用脚本完成，不消耗 LLM）
- 增量无损迁移（JSON 双写 → 验证 → 切换）

---

## 三、数据库设计（详细见 docs/mofin-database-architecture.md）

### 8 组表

| 表 | 替代的 JSON | 核心字段 |
|----|------------|---------|
| market_snapshots | —（新增） | timestamp, up_ratio, mood |
| sector_snapshots | market.json sectors[] | snapshot_id, name, change_pct, net_inflow |
| stocks | multi_tf_cache.json 的 key | code, name, exchange |
| stock_daily / weekly / monthly | multi_tf_cache 内容 | code, date, ohlcv |
| stock_fundamentals | multi_tf_cache fundamentals | code, pe, pb, eps |
| stock_sectors | **新表（目前无）** | code ↔ sector_name 映射 |
| holdings | portfolio.json holdings | code, shares, cost |
| holding_strategies | decisions.json 策略 | code, stop_loss, tp, entry 区间 |
| watchlist_stocks | watchlist.json | code, name |
| candidates | candidate_pool.json | code, star, promoted |
| candidate_score_history | candidate_pool 内嵌 history | code, score, source |
| price_events | price_events.json | code, event_type, price |

---

## 四、实施计划

### 阶段1：市场快照入库（当前，P0）

改动文件：`market_watch.py`

```
market_watch.py 修改：
  1. 采集 90 个板块数据后
  2. 写 market.json（保留，兼容现有管道）
  3. 同时 INSERT INTO market_snapshots + sector_snapshots
```

**验证标准：**
- market_watch 跑完后，mofin.db 中 market_snapshots 增加一条
- sector_snapshots 有 90 行对应数据
- 现有 pipeline 不受影响（继续读 market.json）

### 阶段2：个股K线入库（P1）

改动文件：`refresh_mtf_cache.py`

- 将 multi_tf_cache.json 的数据同时写入 stock_daily / weekly / monthly
- 补填 stocks 表和 stock_fundamentals 表

### 阶段3：板块成分映射（P1）

新建脚本或集成到 market_watch：

- 从同花顺板块数据中提取成分股（ak.stock_board_industry_cons_em）
- 写入 stock_sectors 表
- 建立个股 ↔ 板块的可查询关系

### 阶段4：业务表迁移（P2）

- holdings / watchlist / candidates / price_events 逐表迁移
- 每表：JSON+SQLite 双写 → 验证 → 切到 SQLite

### 阶段5：no_agent 查询脚本（P3）

- mofin_query.py "SELECT ..." → 输出格式化的报告
- 定时预警：SQL 条件满足时推送通知
- 示例查询见数据库架构文档

---

## 五、接口说明

### market_watch.py 数据格式

输入：同花顺（akshare）90 个行业板块
输出字段（写入 sector_snapshots）：

| 字段 | 来源 | 说明 |
|------|------|------|
| name | 板块名称 | 中文名，如"半导体" |
| change_pct | 涨跌幅 | 百分比，THS 源直接可用，EM 源需÷100 |
| up_count | 上涨家数 | 仅 THS 源有 |
| down_count | 下跌家数 | 仅 THS 源有 |
| net_inflow | 资金净流入(亿) | 仅 THS 源有 |
| lead_stock | 领涨股 | 仅 THS 源有 |
| lead_stock_change | 领涨股涨跌幅 | 仅 THS 源有 |

### 腾讯 API 个股查询

```bash
curl -s --noproxy '*' "http://qt.gtimg.cn/q=sh688981"
# 返回 v_sh688981="1~中芯国际~688981~140.50~...~...~...~字段32=涨跌幅"
# 第4字段 = 当前价，第32字段 = 涨跌幅(%)
```

---

## 六、文件清单

### 项目文件

| 路径 | 说明 |
|------|------|
| /home/hmo/web-dashboard/market_watch.py | 市场数据采集（本阶段改动） |
| /home/hmo/web-dashboard/market_screener.py | 已暂停，暂不涉及 |
| /home/hmo/web-dashboard/refresh_mtf_cache.py | 下一阶段改动 |
| /home/hmo/web-dashboard/data/mofin.db | 目标数据库（待创建） |

### 文档

| 路径 | 说明 |
|------|------|
| docs/mofin-database-architecture.md | 完整数据库架构设计 |
| docs/market-screening-pipeline.md | 当前筛选流程与提示词 |
| docs/market-screening-system-design.md | 筛选系统设计过程 |
| docs/market-data-requirements.md | 原始需求（部分已实现） |
| docs/strategy-evaluation-requirements.md | 策略评估需求 |

---

## 七、当前任务（笑笑接手）

**第一件事：阶段1 - market_watch.py 改双写**

1. 在 data/ 下创建 mofin.db（SQLite）
2. 执行建表 SQL（CREATE TABLE market_snapshots + sector_snapshots + 索引）
3. 修改 market_watch.py 的 main()：
   - 采集板块数据后
   - 写 market.json（已有逻辑，不动）
   - 新增：INSERT market_snapshots（获取 id）
   - 新增：逐板块 INSERT sector_snapshots
4. 验证：手动跑一次 market_watch.py，检查数据库有数据
5. 编写验证脚本 `mofin_query.py`，支持：
   ```bash
   python3 mofin_query.py "半导体最近5次采集的涨跌幅"
   # 输出：时间 | 涨跌幅 | 净流入
   ```

**第二件事：搭建开发环境**
- 项目在 /home/hmo/web-dashboard/
- Python 3.12，标准库 sqlite3
- 需要申请访问 Samba 共享 \\192.168.1.246\hmo-home
- 读 docs/ 下的全部文档了解全貌
