docs: reorganize — README index, archive old docs, add status headers
This commit is contained in:
@@ -0,0 +1,354 @@
|
||||
# MoFin 统一数据库架构 — 实施文档
|
||||
|
||||
> 最后更新:2026-06-20
|
||||
> 维护人:小小莫(xxm)
|
||||
> 状态:✅ 已完成
|
||||
|
||||
---
|
||||
|
||||
## 一、概述
|
||||
|
||||
将 MoFin 系统散落在 11 个 JSON 文件中的数据统一纳入 SQLite 数据库(`data/mofin.db`),实现:
|
||||
|
||||
- **数据关系化**:持仓 ↔ 板块 ↔ 趋势,一条 SQL 直连
|
||||
- **历史可追溯**:板块快照、价格事件、策略变更全部时序存储
|
||||
- **操作 no_agent 化**:常用查询用脚本完成,不消耗 LLM
|
||||
- **增量无损迁移**:JSON 双写 → 验证 → 消费者切 SQLite → JSON 保留回退
|
||||
|
||||
### 当前状态
|
||||
|
||||
| 阶段 | 状态 |
|
||||
|------|------|
|
||||
| 阶段1:市场快照入库 | ✅ 已完成 |
|
||||
| 阶段2:个股K线入库 | ✅ 已完成 |
|
||||
| 阶段3:板块成分映射 | ✅ 已完成 |
|
||||
| 阶段4:业务表迁移 | ✅ 已完成 |
|
||||
| 阶段5:消费者切 SQLite | ✅ 已完成 |
|
||||
|
||||
---
|
||||
|
||||
## 二、数据库设计
|
||||
|
||||
### 2.1 表结构总览(13 张表)
|
||||
|
||||
```
|
||||
mofin.db
|
||||
├── market_snapshots # 每次市场采集的元信息
|
||||
├── sector_snapshots # 每个板块在每次采集中的快照
|
||||
├── stocks # 个股基本信息
|
||||
├── stock_daily # 日K线
|
||||
├── stock_weekly # 周K线
|
||||
├── stock_monthly # 月K线
|
||||
├── stock_fundamentals # 基本面(PE/PB/EPS/市值)
|
||||
├── stock_sectors # 个股→板块映射
|
||||
├── holdings # 持仓
|
||||
├── holding_strategies # 持仓策略(含版本历史)
|
||||
├── watchlist_stocks # 自选股
|
||||
├── candidates # 候选池
|
||||
├── candidate_score_history # 候选评分历史
|
||||
├── price_events # 价格触发事件
|
||||
├── strategy_evaluations # 策略评估记录
|
||||
├── portfolio_summary # 持仓汇总(总资产/现金/仓位)
|
||||
├── advice_timeline # 建议时间线
|
||||
├── accuracy_stats # 准确率统计
|
||||
└── strategy_feedback # 策略反馈
|
||||
```
|
||||
|
||||
### 2.2 核心表详述
|
||||
|
||||
#### market_snapshots + sector_snapshots
|
||||
|
||||
```sql
|
||||
CREATE TABLE market_snapshots (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
timestamp TEXT NOT NULL, -- '2026-06-20 15:30'
|
||||
source TEXT NOT NULL DEFAULT 'ths',
|
||||
up_ratio REAL, -- 上涨板块占比(%)
|
||||
mood TEXT -- bullish/neutral/bearish
|
||||
);
|
||||
|
||||
CREATE TABLE sector_snapshots (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
snapshot_id INTEGER NOT NULL REFERENCES market_snapshots(id),
|
||||
name TEXT NOT NULL, -- 板块名称
|
||||
change_pct REAL, -- 涨跌幅(%)
|
||||
up_count INTEGER, -- 上涨家数
|
||||
down_count INTEGER, -- 下跌家数
|
||||
net_inflow REAL, -- 资金净流入(亿)
|
||||
lead_stock TEXT, -- 领涨股
|
||||
lead_stock_change REAL -- 领涨股涨跌幅
|
||||
);
|
||||
```
|
||||
|
||||
**写入者**:`market_watch.py`(每30分钟,JSON + SQLite 双写)
|
||||
|
||||
**典型查询**:
|
||||
```sql
|
||||
-- 半导体板块最近5次涨跌幅趋势
|
||||
SELECT s.timestamp, ss.change_pct, ss.net_inflow
|
||||
FROM sector_snapshots ss
|
||||
JOIN market_snapshots s ON ss.snapshot_id = s.id
|
||||
WHERE ss.name = '半导体'
|
||||
ORDER BY s.timestamp DESC LIMIT 5;
|
||||
|
||||
-- 资金连续3天净流入的板块
|
||||
SELECT name, COUNT(*) as times, AVG(net_inflow) as avg_inflow
|
||||
FROM sector_snapshots ss
|
||||
JOIN market_snapshots s ON ss.snapshot_id = s.id
|
||||
WHERE s.timestamp >= date('now', '-3 days') AND net_inflow > 0
|
||||
GROUP BY name HAVING COUNT(*) >= 3
|
||||
ORDER BY avg_inflow DESC;
|
||||
```
|
||||
|
||||
#### stocks + stock_daily/weekly/monthly + stock_fundamentals
|
||||
|
||||
```sql
|
||||
CREATE TABLE stocks (
|
||||
code TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
exchange TEXT DEFAULT 'SH', -- SH/SZ/HK
|
||||
type TEXT DEFAULT 'A' -- A/H
|
||||
);
|
||||
|
||||
CREATE TABLE stock_daily (
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
date TEXT NOT NULL,
|
||||
open REAL, close REAL, high REAL, low REAL,
|
||||
volume REAL, amount REAL,
|
||||
PRIMARY KEY (code, date)
|
||||
);
|
||||
-- stock_weekly, stock_monthly 结构相同
|
||||
```
|
||||
|
||||
**写入者**:`multi_timeframe.py`(缓存写入时双写 SQLite)
|
||||
|
||||
#### holdings + holding_strategies
|
||||
|
||||
```sql
|
||||
CREATE TABLE holdings (
|
||||
code TEXT PRIMARY KEY REFERENCES stocks(code),
|
||||
name TEXT NOT NULL,
|
||||
shares INTEGER NOT NULL,
|
||||
cost REAL,
|
||||
position_pct REAL,
|
||||
is_active INTEGER DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE TABLE holding_strategies (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
code TEXT NOT NULL REFERENCES holdings(code),
|
||||
version INTEGER DEFAULT 1,
|
||||
stop_loss REAL,
|
||||
take_profit REAL,
|
||||
entry_low REAL,
|
||||
entry_high REAL,
|
||||
strategy_type TEXT DEFAULT 'holding', -- holding/watch/decision
|
||||
source TEXT, -- migrate/reassess/manual
|
||||
reason TEXT,
|
||||
created_at TEXT,
|
||||
superseded_at TEXT
|
||||
);
|
||||
```
|
||||
|
||||
**数据来源**:`migrate_all.py` 从 `portfolio.json`、`decisions.json` 迁移
|
||||
|
||||
#### price_events
|
||||
|
||||
```sql
|
||||
CREATE TABLE price_events (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
name TEXT,
|
||||
event_type TEXT NOT NULL, -- entry_zone/stop_loss/take_profit
|
||||
price REAL,
|
||||
trigger_value TEXT,
|
||||
event_label TEXT,
|
||||
date TEXT
|
||||
);
|
||||
```
|
||||
|
||||
**写入者**:`price_monitor.py`(JSON + SQLite 双写)
|
||||
|
||||
---
|
||||
|
||||
## 三、数据流架构
|
||||
|
||||
### 3.1 写入路径
|
||||
|
||||
```
|
||||
market_watch.py ──→ market.json + market_snapshots + sector_snapshots
|
||||
multi_timeframe.py ──→ multi_tf_cache.json + stocks + stock_daily/weekly/monthly
|
||||
price_monitor.py ──→ price_events.json + price_events
|
||||
```
|
||||
|
||||
### 3.2 读取路径(SQLite 优先,JSON 回退)
|
||||
|
||||
```
|
||||
server.py ──→ mofin_db.query_*() ──→ (失败) ──→ JSON 文件
|
||||
strategy_lifecycle.py ──→ mofin_db.query_*() ──→ (失败) ──→ JSON 文件
|
||||
market_insight.py ──→ mofin_db.query_latest_market() ──→ (失败) ──→ market.json
|
||||
strategy_feedback.py ──→ mofin_db.query_price_events() ──→ (失败) ──→ price_events.json
|
||||
system_health_check.py ──→ mofin_db.query_price_events() ──→ (失败) ──→ price_events.json
|
||||
```
|
||||
|
||||
### 3.3 回退策略
|
||||
|
||||
所有消费者使用 `try: SQLite → except: JSON` 模式。SQLite 不可用时自动降级,系统不中断。
|
||||
|
||||
---
|
||||
|
||||
## 四、核心模块
|
||||
|
||||
### 4.1 mofin_db.py — 统一数据库访问层
|
||||
|
||||
所有脚本通过此模块访问数据库,避免重复建表/连接逻辑。
|
||||
|
||||
```python
|
||||
from mofin_db import get_conn, init_all_tables, query_holdings, ...
|
||||
|
||||
conn = get_conn() # WAL模式 + Row工厂 + 外键约束
|
||||
init_all_tables(conn) # 幂等建表
|
||||
holdings = query_holdings(conn)
|
||||
conn.close()
|
||||
```
|
||||
|
||||
**写入函数**:
|
||||
| 函数 | 用途 |
|
||||
|------|------|
|
||||
| `write_market_snapshot()` | 市场快照双写 |
|
||||
| `write_klines()` | K线数据双写 |
|
||||
| `write_price_event()` | 价格事件双写 |
|
||||
|
||||
**查询函数(18个)**:
|
||||
| 函数 | 返回 |
|
||||
|------|------|
|
||||
| `query_holdings()` | 持仓列表(含最新策略) |
|
||||
| `query_watchlist()` | 自选股列表 |
|
||||
| `query_strategies(code)` | 策略版本历史 |
|
||||
| `query_advice_timeline(code)` | 建议时间线 |
|
||||
| `query_candidates()` | 候选池 |
|
||||
| `query_candidate_scores(code)` | 候选评分历史 |
|
||||
| `query_price_events(code)` | 价格事件 |
|
||||
| `query_price_events_by_date(date)` | 某天价格事件 |
|
||||
| `query_stock_sectors(code)` | 个股所属板块 |
|
||||
| `query_sector_stocks(name)` | 板块成分股 |
|
||||
| `query_accuracy_stats()` | 准确率统计 |
|
||||
| `query_strategy_feedback(code)` | 策略反馈 |
|
||||
| `query_strategy_evaluations(code)` | 策略评估记录 |
|
||||
| `query_latest_market()` | 最新市场快照 |
|
||||
| `query_sector_trend(name)` | 板块趋势 |
|
||||
| `query_top_inflow()` | 资金净流入排行 |
|
||||
| `query_consecutive_inflow()` | 连续净流入 |
|
||||
| `query_market_mood()` | 市场情绪趋势 |
|
||||
| `query_db_stats()` | 数据库概览 |
|
||||
|
||||
### 4.2 migrate_all.py — 一次性迁移脚本
|
||||
|
||||
```bash
|
||||
python3 migrate_all.py
|
||||
```
|
||||
|
||||
从所有 JSON 文件迁移历史数据到 SQLite。幂等可重跑(`INSERT OR REPLACE`/`INSERT OR IGNORE`),JSON 文件不修改。
|
||||
|
||||
**迁移映射**:
|
||||
|
||||
| 源 JSON | 目标表 | 迁移量(参考) |
|
||||
|----------|--------|--------------|
|
||||
| stock_profiles.json + 所有源 | stocks | ~55 只 |
|
||||
| portfolio.json | holdings | ~21 只 |
|
||||
| portfolio.json (analysis) | holding_strategies | ~21 条 |
|
||||
| watchlist.json | watchlist_stocks | ~29 只 |
|
||||
| decisions.json (含 changelog) | holding_strategies | ~316 条 |
|
||||
| candidate_pool.json | candidates | ~10 只 |
|
||||
| candidate_pool.json (score_history) | candidate_score_history | ~21 条 |
|
||||
| price_events.json | price_events | ~193 条 |
|
||||
| evaluation.json | strategy_evaluations | ~36 条 |
|
||||
| stock_sector_map.json | stock_sectors | ~62 条 |
|
||||
| portfolio.json (顶层) | portfolio_summary | 1 条 |
|
||||
| decisions.json (advice_timeline) | advice_timeline | ~2547 条 |
|
||||
| accuracy_stats.json | accuracy_stats | 1 条 |
|
||||
| strategy_feedback.json | strategy_feedback | ~37 条 |
|
||||
|
||||
### 4.3 mofin_query.py — 通用查询工具
|
||||
|
||||
```bash
|
||||
python3 mofin_query.py "半导体最近5次采集的涨跌幅"
|
||||
python3 mofin_query.py "今天资金净流入最多的5个板块"
|
||||
python3 mofin_query.py "最近3天连续净流入的板块"
|
||||
python3 mofin_query.py "市场情绪趋势(最近10次)"
|
||||
python3 mofin_query.py "数据库概览"
|
||||
python3 mofin_query.py "SELECT * FROM market_snapshots ORDER BY id DESC LIMIT 5"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、部署指南
|
||||
|
||||
### 5.1 首次部署
|
||||
|
||||
```bash
|
||||
cd /home/hmo/web-dashboard
|
||||
git pull
|
||||
python3 migrate_all.py # 一次性迁移历史数据
|
||||
python3 market_watch.py # 验证双写(需要 akshare)
|
||||
python3 mofin_query.py "数据库概览" # 验证数据入库
|
||||
# 重启 Flask
|
||||
```
|
||||
|
||||
### 5.2 日常运维
|
||||
|
||||
数据库文件:`/home/hmo/web-dashboard/data/mofin.db`
|
||||
|
||||
```bash
|
||||
# 查看数据库大小
|
||||
ls -lh data/mofin.db
|
||||
|
||||
# 手动查询
|
||||
sqlite3 data/mofin.db "SELECT COUNT(*) FROM market_snapshots"
|
||||
sqlite3 data/mofin.db "SELECT COUNT(*) FROM price_events"
|
||||
|
||||
# 备份
|
||||
cp data/mofin.db data/mofin.db.$(date +%Y%m%d).bak
|
||||
```
|
||||
|
||||
### 5.3 故障恢复
|
||||
|
||||
如果 SQLite 损坏或不可用:
|
||||
- 所有消费者自动回退 JSON 文件,系统不中断
|
||||
- 删除 `data/mofin.db`,重新运行 `migrate_all.py` 重建
|
||||
- JSON 文件是数据源,不会丢失
|
||||
|
||||
---
|
||||
|
||||
## 六、架构决策记录
|
||||
|
||||
### ADR-1:为什么选 SQLite 而不是 PostgreSQL
|
||||
|
||||
- 单机部署,无分布式需求
|
||||
- 零运维成本(无需独立进程)
|
||||
- Python 标准库 `sqlite3`,无额外依赖
|
||||
- WAL 模式支持并发读写
|
||||
- 数据量预估 < 100MB,SQLite 完全胜任
|
||||
|
||||
### ADR-2:为什么双写而不是直接切换
|
||||
|
||||
- 消费者(server.py、strategy_lifecycle.py 等)仍在读 JSON
|
||||
- 直接切换风险高,一旦出错影响生产
|
||||
- 双写 → 验证数据一致性 → 消费者切 SQLite → JSON 保留回退
|
||||
|
||||
### ADR-3:为什么 SQLite 优先 + JSON 回退
|
||||
|
||||
- SQLite 查询能力远超 JSON 文件
|
||||
- 保留 JSON 回退确保 SQLite 不可用时系统不中断
|
||||
- 渐进式迁移,降低风险
|
||||
|
||||
---
|
||||
|
||||
## 七、已知限制
|
||||
|
||||
| 限制 | 说明 | 影响 |
|
||||
|------|------|------|
|
||||
| `holdings` 表缺 `price`/`change_pct` | 实时价格由 price_monitor 写入 JSON,SQLite 未同步 | `/api/overview` 的 top_movers 依赖 change_pct,回退 JSON 时正常 |
|
||||
| `market.json` 的 LLM 生成字段 | `insights`、`potential_stocks`、`market_verdict` 等由 LLM cron 生成,SQLite 未存储 | 这些字段仅 market_screener.py 写入,Dashboard 展示用,不影响核心分析 |
|
||||
| `decisions.json` 的复杂嵌套字段 | `trigger`、`changelog`、`evaluation` 等嵌套结构未完全迁移到 SQLite | 部分消费者仍读 JSON(如 server.py 的 decisions API) |
|
||||
| 单文件数据库 | SQLite 是单文件,无主从复制 | 备份需手动或 cron |
|
||||
@@ -0,0 +1,418 @@
|
||||
# MoFin 专家系统 — 完整架构文档 v2.0
|
||||
|
||||
> 最后更新:2026-06-12
|
||||
> 维护人:莫荷(Hermes Agent)
|
||||
> 铁律:任何系统改动必须先读本文档,改完必须同步更新
|
||||
|
||||
---
|
||||
|
||||
## 一、核心理念
|
||||
|
||||
```
|
||||
每份分析都成为下一次分析的养料
|
||||
每次建议都成为下一次建议的参考
|
||||
从内到外(知识→分析),从外到内(分析→沉淀)的持续闭环
|
||||
```
|
||||
|
||||
## 二、股票操作策略生命周期
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ 大环境+行业趋势研判 │
|
||||
│ (盘前热点扫描·每天8:30) │
|
||||
│ 板块扫描→发现新标的 │
|
||||
└──────────┬──────────────────┘
|
||||
│ 写入 watchlist.json
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 自选股池 (watchlist.json) │
|
||||
│ │
|
||||
│ 🟢 可操作 — 价格在买入区内 │
|
||||
│ 🟡 关注 — 距触发3~5% │
|
||||
│ ⚪ 观察 — 距触发>5% │
|
||||
│ │
|
||||
│ 监控: │
|
||||
│ • 快速盯盘(每15分钟) │
|
||||
│ • 持仓情报-盘后(每天) │
|
||||
│ • 自选股体检(每周六) │
|
||||
└──────────┬──────────────────┘
|
||||
进入买入区 │ 建仓
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 持仓股 (portfolio.json) │
|
||||
│ │
|
||||
│ 监控: │
|
||||
│ • 价格监控(每分钟·纯脚本) │
|
||||
│ • 快速盯盘(每15分钟·LLM) │
|
||||
│ • 持仓情报-盘中(每小时·LLM) │
|
||||
│ • 持仓情报-盘后(每天·LLM) │
|
||||
│ • 分析师-持仓复查(每周·LLM) │
|
||||
└──────────┬──────────────────┘
|
||||
触发止损/止盈/清仓 │
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 回到自选股池 │
|
||||
│ (保留策略,等待下次机会) │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
## 三、系统架构总览
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ MoFin 专家系统 v2.0 │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────┐ ┌──────────────────────────────┐ │
|
||||
│ │ 基础设施层(纯脚本) │ │ 分析层(LLM驱动) │ │
|
||||
│ │ 0配额消耗 │ │ 每次运行消耗1次配额 │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ • 价格监控(1分钟) │ │ • 盘前热点扫描(8:30) │ │
|
||||
│ │ 腾讯批量API拉所有股票 │ │ → 持仓分析+板块扫描 │ │
|
||||
│ │ 写入portfolio/watchlist│ │ → 新机会发现→写入watchlist│ │
|
||||
│ │ 比对区间触发→输出 │ │ │ │
|
||||
│ │ │ │ • 集合竞价观察(9:28) │ │
|
||||
│ │ • 市场数据采集(30分钟) │ │ → A股竞价异常监控 │ │
|
||||
│ │ 板块数据→market.json │ │ │ │
|
||||
│ │ │ │ • 快速盯盘(每15分钟) │ │
|
||||
│ │ • 数据同步(8:55) │ │ → 持仓操作窗口+自选接近提醒 │ │
|
||||
│ │ update_data+server检查│ │ │ │
|
||||
│ │ │ │ • 持仓情报-盘中(每小时40分) │ │
|
||||
│ │ • XMPP中继(每分钟) │ │ → 详细盘中分析 │ │
|
||||
│ │ 扫输出目录→推知微 │ │ │ │
|
||||
│ │ │ │ • 持仓情报-盘后(20:00) │ │
|
||||
│ │ • 港股低延迟行情中继 │ │ • 分析师-持仓复查(周四20:00) │ │
|
||||
│ │ tdx-relay (Windows) │ │ → 基本面深度复查 │ │
|
||||
│ │ opentdx→招商证券7727 │ │ │ │
|
||||
│ │ POST → /api/update/ │ │ │ │
|
||||
│ │ realtime │ │ │ │
|
||||
│ └─────────┬───────────────┘ │ │ │
|
||||
│ │ │ │ │
|
||||
│ ▼ │ │ │
|
||||
│ ┌─────────────────────────┐ │ │ │
|
||||
│ │ 数据层 │ │ │ │
|
||||
│ │ portfolio.json(持仓) │ │ │ │
|
||||
│ │ watchlist.json(自选) │ │ → 每只自选评估:保留/移除 │ │
|
||||
│ │ decisions.json(决策库) │ │ │ │
|
||||
│ │ market.json(板块数据) │ │ • 知微周复盘(周日22:00) │ │
|
||||
│ │ daily_reviews.json │ │ → 周度总结 │ │
|
||||
│ │ stock_profiles.json │ └──────────┬───────────────────┘ │
|
||||
│ └─────────┬───────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ 推送层 │ │
|
||||
│ │ cron_to_xmpp.py(每分钟·纯脚本) │ │
|
||||
│ │ 扫描 ~/.hermes/cron/output/*/ 目录 │ │
|
||||
│ │ 发现新 .md 文件 → 提取正文 → XMPP推送【知微】 │ │
|
||||
│ │ 已推送的记在 .relay_journal.json,不重复推 │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 四、完整 Cron Job 清单(14个)
|
||||
|
||||
### 🟢 基础设施层(纯脚本,0配额消耗)
|
||||
|
||||
| # | 名称 | 频率 | 脚本 | 输出 | 说明 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | **价格监控-1分钟** | 工作日 每分钟(9-11/12/13-16) | `price_monitor.py` | 有触发→推送;无→SILENT | 腾讯批量API拉所有股票实时价,写入portfolio/watchlist,比对区间触发条件 |
|
||||
| 2 | **市场数据采集** | 工作日 每30分钟 | `market_watch.py` | 成功→SILENT;失败→报错 | 东方财富API采集板块数据→market.json |
|
||||
| 3 | **数据同步-dashboard** | 每天 8:55 | `sync_dashboard.py` | 有数据→推送;无→SILENT | 跑update_data.py+检查server,挂了自动重启 |
|
||||
| 4 | **cron-推XMPP中继** | 工作日 每分钟(9-16) | `cron_to_xmpp.py` | 有新报告→推送;无→静默 | 扫所有job输出目录,推新报告到XMPP |
|
||||
| 5 | **中继-16点收盘** | 工作日 16:00-16:10 | `cron_to_xmpp.py` | 同上 | 收盘时段推港股报告 |
|
||||
|
||||
### 🔵 分析层(LLM驱动,每次1次配额)
|
||||
|
||||
| # | 名称 | 频率 | 关键职责 | 价格获取方式 |
|
||||
|---|------|------|---------|------------|
|
||||
| 6 | **盘前热点扫描** | 工作日 8:30 | 持仓分析+**板块扫描→新机会发现→写入watchlist** | 读文件(price_monitor刷新) |
|
||||
| 7 | **集合竞价观察** | 工作日 9:28 | A股竞价异常监控,无异常SILENT | A股curl竞价价+港股读文件 |
|
||||
| 8 | **快速盯盘-15分钟** | 工作日 每15分钟 | 持仓操作窗口+**自选股接近买入区提醒**,无则SILENT | 读文件 |
|
||||
| 9 | **持仓情报-盘中** | 工作日 每小时40分 | 详细盘中分析+异动搜因 | 读文件 |
|
||||
| 10 | **持仓情报-盘后** | 工作日 20:00 | 完整复盘+**自选股回顾**+数据沉淀daily_reviews | 读文件 |
|
||||
| 11 | **分析师-持仓复查** | 周四 20:00 | 每周基本面深度复查 | 读文件 |
|
||||
| 12 | **自选股体检-每周** | **周六 20:00 🆕** | 每只自选评估:已建仓→移除、>30天未接近→建议移除、行业变化→更新理由 | 读文件+web_search |
|
||||
| 13 | **知微周复盘** | 周日 22:00 | 周度总结 | 读文件 |
|
||||
| 14 | **策略评估-每日** | 工作日 21:00 | 双维度评估36条策略,生成反馈闭环 | 读文件+LLM | 无变化→SILENT |
|
||||
| 15 | **建议对账-每周** | 周六 20:00 | 对比建议vs实际持仓变化,算准确率 | 纯脚本 | 有数据→推送 |
|
||||
| 16 | **策略评估-每周** | 周六 21:00 | 完整评分+趋势分析+策略参数调整 | 纯脚本 | 有数据→推送 |
|
||||
|
||||
## 五、数据文件
|
||||
|
||||
| 文件 | 路径 | 作用 | 更新频率 | 更新者 |
|
||||
|------|------|------|---------|--------|
|
||||
| 持仓数据 | `data/portfolio.json` | 持仓快照+实时价 | 每分钟 | price_monitor |
|
||||
| 自选数据 | `data/watchlist.json` | 自选股列表+买入区+实时价 | 每分钟 | price_monitor+盘前扫描+自选体检 |
|
||||
| 决策库 | `data/decisions.json` | 策略+trigger+建议历史+评估数据 | 每次讨论后+每日评估 | LLM job+策略评估 |
|
||||
| 每日复盘 | `data/daily_reviews.json` | 当日判断+修正沉淀 | 每日20:00 | 持仓情报-盘后 |
|
||||
| 股票档案 | `data/stock_profiles.json` | 行业/业务/逻辑 | 发现新信息时 | LLM |
|
||||
| 市场数据 | `data/market.json` | 板块涨跌+概念热度 | 每30分钟 | market_watch |
|
||||
| 价格事件 | `data/price_events.json` | 价格触发记录(止盈/止损/买入区) | 每分钟 | price_monitor |
|
||||
| 评估结果 | `data/evaluation.json` | 双维度评估+评分 | 每天21:00 | 策略评估 |
|
||||
| 准确率统计 | `data/accuracy_stats.json` | 建议对账+准确率 | 每周六20:00 | 对账脚本 |
|
||||
| 反馈闭环 | `data/strategy_feedback.json` | 反馈+调整建议+知识萃取 | 每天21:00 | 策略评估 |
|
||||
| 区间偏离 | `~/.hermes/zone_breach.json` | 价格偏离标记 | 每分钟 | price_monitor |
|
||||
| 触发状态 | `~/.hermes/price_trigger_state.json` | 每只股票各区间的进出状态 | 每分钟 | price_monitor |
|
||||
| relay状态 | `data/relay_state.json` (新增) | tdx-relay在线/离线状态 | 每分钟 | server.py(update/realtime更新) |
|
||||
|
||||
## 六、数据流转
|
||||
|
||||
```
|
||||
tdx-relay (Windows·xxm负责)
|
||||
│ opentdx → 招商证券7727扩展行情服务
|
||||
│ 拉取17只港股实时行情(1~3秒延迟)
|
||||
│ POST → http://192.168.1.246:8899/api/update/realtime
|
||||
│
|
||||
├──→ server.py 接收 → 更新 portfolio.json / watchlist.json
|
||||
│ 港股 data_source = "tdx_relay"
|
||||
│ 更新 relay_state.json
|
||||
│
|
||||
└──→ price_monitor 检测 relay 状态
|
||||
relay 在线 → 跳过港股腾讯API拉取(保留实时价)
|
||||
relay 离线(>60秒) → 回退腾讯 API 兜底
|
||||
|
||||
price_monitor(每分钟)
|
||||
│ 腾讯批量API 1次请求
|
||||
│
|
||||
├──→ portfolio.json (持仓实时价)
|
||||
├──→ watchlist.json (自选实时价)
|
||||
├──→ 比对decisions.json的trigger区间
|
||||
├──→ 有触发 → 输出 → 中继 → 知微
|
||||
└──→ 无触发 → [SILENT] → 丢弃
|
||||
|
||||
market_watch(每30分钟)
|
||||
│ 东方财富API
|
||||
└──→ market.json (板块数据)
|
||||
|
||||
盘前热点扫描(每天8:30)
|
||||
│ 读 market.json → 分析强势板块
|
||||
│ 发现新标的 → 写入 watchlist.json
|
||||
└──→ 输出报告 → 中继 → 知微
|
||||
|
||||
快速盯盘(每15分钟)
|
||||
│ 读 portfolio.json + watchlist.json
|
||||
│ 持仓操作窗口 + 自选接近买入区
|
||||
└──→ 有发现 → 输出 → 中继 → 知微
|
||||
|
||||
持仓情报-盘后(每天20:00)
|
||||
│ 读 portfolio.json + watchlist.json
|
||||
│ 持仓回顾 + 自选回顾
|
||||
└──→ 写入 daily_reviews.json
|
||||
└──→ 输出报告 → 中继 → 知微
|
||||
|
||||
自选股体检(每周六20:00)
|
||||
│ 读 watchlist.json + portfolio.json
|
||||
│ 每只评估:保留/移除/更新
|
||||
└──→ 输出报告 → 中继 → 知微
|
||||
```
|
||||
|
||||
## 七、报告推送策略
|
||||
|
||||
| 报告 | 推送 | 频率 | 静默规则 |
|
||||
|------|------|------|---------|
|
||||
| 价格监控 | ✅ 有触发才推 | 每分钟 | 无触发→[SILENT] |
|
||||
| 盘前扫描 | ✅ | 每日1次 | 有发现才写 |
|
||||
| 集合竞价 | ✅ 有异常才推 | 每日1次 | 无异常→SILENT |
|
||||
| 快速盯盘 | ✅ 有发现才推 | 每15分钟 | 无操作窗口+无自选接近→SILENT |
|
||||
| 持仓情报-盘中 | ✅ 有发现才推 | 每小时40分 | 无操作窗口→合并后停止 |
|
||||
| 持仓情报-盘后 | ✅ | 每日20:00 | 有实质内容才写 |
|
||||
| 分析师复查 | ✅ | 每周四 | 有发现才写 |
|
||||
| 自选股体检 | ✅ | 每周六 | 有建议才写 |
|
||||
| 知微周复盘 | ✅ | 每周日 | 有实质内容才写 |
|
||||
| 市场数据采集 | ❌ 不推 | 每30分钟 | 只写文件 |
|
||||
| 数据同步 | ✅ 有数据才推 | 每天8:55 | 无更新→SILENT |
|
||||
|
||||
## 八、关键设计决策
|
||||
|
||||
| 方面 | 决策 | 原因 |
|
||||
|------|------|------|
|
||||
| 价格获取 | 腾讯批量API `qt.gtimg.cn/q=sh600110,sz000001,...` | 1次请求拉所有股票,无频率限制 |
|
||||
| 价格监控类型 | 纯脚本(`no_agent=True`) | 不需要LLM,0配额消耗 |
|
||||
| 中继类型 | 纯脚本(`no_agent=True`) | 文件扫描+XMPP推送,不需要LLM |
|
||||
| 市场数据采集 | 纯脚本(`no_agent=True`) | 只写文件不输出,不需要LLM |
|
||||
| 数据同步 | 纯脚本(`sync_dashboard.py`) | 包装脚本含server检查,不需要LLM |
|
||||
| LLM job价格来源 | 读文件(price_monitor每1分钟刷新) | 不再逐个curl,节省配额 |
|
||||
| 新机会发现 | 合并到盘前热点扫描(每天) | 每天分析板块数据,发现新标的写入watchlist |
|
||||
| 自选股进出管理 | 自选股体检(每周六) | 系统评估+提请确认,不自动删除 |
|
||||
| 午休 | 价格监控跳过12:05-12:55(保留12:00) | A股午休无行情 |
|
||||
|
||||
## 九、配额消耗估算(一个上午)
|
||||
|
||||
| 组件 | 运行次数 | 配额消耗 |
|
||||
|------|---------|---------|
|
||||
| 价格监控 | ~240次(每分钟) | **0** (纯脚本) |
|
||||
| 市场数据采集 | ~10次 | **0** (纯脚本) |
|
||||
| 数据同步 | 1次 | **0** (纯脚本) |
|
||||
| XMPP中继 | ~240次 | **0** (纯脚本) |
|
||||
| 盘前热点扫描 | 1次 | **1次** |
|
||||
| 集合竞价 | 1次 | **1次** |
|
||||
| 快速盯盘 | ~20次 | **~20次** (有操作窗口才跑,无则SILENT不消耗) |
|
||||
| 持仓情报-盘中 | ~6次 | **~6次** |
|
||||
| 策略评估-每日 | 1次 | **1次** |
|
||||
| **总计** | | **~29次 LLM调用** |
|
||||
|
||||
---
|
||||
|
||||
## 十、策略评估反馈闭环架构
|
||||
|
||||
### 核心流程
|
||||
|
||||
```
|
||||
price_monitor(每分钟·纯脚本)
|
||||
│ 腾讯批量API拉所有股票实时价
|
||||
│ 比对策略区间 → 触发 → 记录到 price_events.json
|
||||
│
|
||||
├──→ 价格触发事件持久化(price_events.json)
|
||||
│ event_type: entry_zone / stop_loss / take_profit
|
||||
│ code, name, price, trigger_value, timestamp
|
||||
│
|
||||
▼
|
||||
strategy_evaluator(每天21:00·纯脚本)
|
||||
│ 读 decisions.json + price_events.json + portfolio.json
|
||||
│ 双维度评估每只股票:
|
||||
│ 阶段一(策略制定→价格达标):
|
||||
│ - 理论:价格是否达到过止盈/止损/买入区
|
||||
│ - 实际:持仓盈亏、建议执行情况
|
||||
│ 阶段二(价格回落→新止损验证):
|
||||
│ - 新止损是否被后续走势验证
|
||||
│ 写入 decisions.json 的 evaluation 字段
|
||||
│
|
||||
├──→ 写入 evaluation.json
|
||||
│
|
||||
▼
|
||||
strategy_feedback(每天21:00·纯脚本,评估后自动)
|
||||
│ 读 evaluation.json
|
||||
│ 自动决策:
|
||||
│ - 价格达到止盈 → 标记阶段一成功,萃取经验
|
||||
│ - 跌破止损 → 标记阶段一失败,生成新区间
|
||||
│ - 14天无触发 → 标记 stale,建议重评
|
||||
│ - 准确率持续下降 → 收紧区间宽度
|
||||
│ 写入 strategy_feedback.json
|
||||
│
|
||||
├──→ 写入 strategy_feedback.json
|
||||
│
|
||||
▼
|
||||
每日评估 cron(每天21:00·LLM驱动)
|
||||
│ 读 strategy_feedback.json
|
||||
│ 处理反馈 → 更新策略 → 输出日报
|
||||
│ 无变化 → [SILENT]
|
||||
│
|
||||
▼
|
||||
盘后知识萃取(每天16:30·LLM驱动)
|
||||
│ 读 feedback 中的 knowledge 字段
|
||||
│ 写入 analyst-knowledge-log.md
|
||||
│
|
||||
▼
|
||||
建议对账(每周六20:00·纯脚本)
|
||||
│ 对比 advice_timeline vs portfolio.json
|
||||
│ 算准确率 → 写入 accuracy_stats.json
|
||||
│
|
||||
▼
|
||||
策略评估-每周(每周六21:00·纯脚本)
|
||||
│ 完整评分 → 趋势分析 → 策略参数调整
|
||||
│ 写入 evaluation.json + strategy_feedback.json
|
||||
```
|
||||
|
||||
### 双维度评估模型
|
||||
|
||||
| 维度 | 阶段一 | 阶段二 |
|
||||
|------|--------|--------|
|
||||
| 理论(策略规划) | 价格是否达到止盈/止损/买入区?何时?理论盈亏? | 新止损是否被后续走势验证? |
|
||||
| 实际(用户执行) | 实际持仓盈亏?建议是否被采纳? | 用户是否按新止损操作?实际损失? |
|
||||
|
||||
### 反馈引擎自动决策规则
|
||||
|
||||
| 检测条件 | 自动动作 |
|
||||
|----------|----------|
|
||||
| 价格达到止盈位 | 标记阶段一成功,萃取经验到知识日志,创建新自选策略 |
|
||||
| 跌破止损位 | 标记阶段一失败,分析原因,生成新止损/买入区间 |
|
||||
| 策略14天未触发任何区间 | 标记为 stale,建议重新评估基本面和技术面 |
|
||||
| 准确率持续下降(<50%) | 收紧策略区间宽度(10%→8%) |
|
||||
| 准确率持续上升(>80%) | 放宽策略区间宽度(10%→12%) |
|
||||
|
||||
---
|
||||
|
||||
## 十、v2.0 更新说明(2026-06-09)
|
||||
|
||||
本次更新基于知微与莫荷、老爸的深入讨论,对系统做了全面重构。以下记录讨论过程中的关键意图、决策和待办事项。
|
||||
|
||||
### 本次改动驱动因素
|
||||
|
||||
1. **火山引擎(volcengine) 429配额超限** → 触发对 provider 配置和 fallback 链的全面梳理
|
||||
2. **发现价格监控逐个curl拉取价格** → 效率极低且浪费配额,触发了对价格获取方式的全面改造
|
||||
3. **知微反馈"问了不在回答长篇报告"** → 触发了对 session 管理、system prompt、对话识别机制的修复
|
||||
4. **老爸指出持仓和自选股之间的动态生命周期关系** → 触发了对股票操作策略完整生命周期的重新设计
|
||||
|
||||
### 已完成的改造
|
||||
|
||||
**基础设施层:**
|
||||
- 价格监控从 LLM驱动(每5分钟) 改为 纯脚本(每1分钟),使用腾讯批量API一次拉所有股票
|
||||
- XMPP中继从 LLM驱动 改为 纯脚本(每1分钟)
|
||||
- 市场数据采集从 LLM驱动 改为 纯脚本
|
||||
- 数据同步从 LLM驱动 改为 纯脚本(含server检查包装脚本)
|
||||
- 所有LLM job的价格获取从"逐个curl拉取"改为"直接读文件(price_monitor每1分钟刷新)"
|
||||
|
||||
**股票生命周期完善:**
|
||||
- 新机会发现:合并到盘前热点扫描(每天8:30),板块扫描→发现新标的→写入watchlist
|
||||
- 自选接近提醒:快速盯盘(每15分钟)新增自选接近买入区(<5%)单独提醒
|
||||
- 自选回顾:持仓情报-盘后(每天20:00)新增自选股回顾板块
|
||||
- 自选体检:新增每周六20:00的自动评估+建议移除/保留
|
||||
|
||||
**provider配置统一:**
|
||||
- 莫荷(默认profile):默认ocg-old(旧key) → fallback ocg-new(新key) → volcengine(火山)
|
||||
- 知微(position-analyst):默认volcengine(火山) → fallback ocg-old(旧key) → ocg-new(新key)
|
||||
- 火山已恢复可用
|
||||
|
||||
**对话机制修复:**
|
||||
- 知微SOUL新增对话上下文识别规则(打招呼vs分析请求vs模糊提问)
|
||||
- 知微SOUL新增系统自动追加消息(bg-review)说明
|
||||
- position-analyst启用压缩(protect_last_n=200, hygiene_hard_message_limit=400)
|
||||
|
||||
**策略评估反馈闭环(v2.0 深夜追加):**
|
||||
- 价格事件持久化:price_monitor每分钟记录价格触发事件到price_events.json
|
||||
- 双维度评估:strategy_evaluator每天评估36条策略,分阶段一(策略制定→价格达标)和阶段二(价格回落→新止损验证),每个阶段同时记录理论盈亏和实际盈亏
|
||||
- 反馈引擎:strategy_feedback自动检测止盈/止损/stale策略,生成调整建议,萃取知识到知识日志
|
||||
- Dashboard评估tab:展示评分、理论vs实际盈亏对比、反馈闭环卡片
|
||||
- 建议对账:advice_reconciliation.py每周对比建议vs实际持仓变化算准确率
|
||||
- 36条策略全部填充建议记录,平均分4.8/10
|
||||
|
||||
### 设计原则/意图
|
||||
|
||||
1. **知微是分析师,不是决策者** — 她出建议,老爸决定是否执行,是否执行的唯一真相来源是截图/持仓更新
|
||||
2. **莫荷是参谋,不是执行者** — 莫荷出报告和建议,不做交易操作
|
||||
3. **建议≠事实** — 不能假设建议=被执行,需要等持仓更新来验证
|
||||
4. **持仓/自选动态循环** — 持仓清仓→自动转自选保留策略,自选建仓→自动转为持仓管理
|
||||
5. **自选股进出需人工确认** — 系统可以建议移除,但不能自动删除,需老爸确认
|
||||
6. **轻对话,重分析** — 不是每条消息都需要全面分析报告,区分打招呼和干活
|
||||
|
||||
### 尚未完成/待定事项
|
||||
|
||||
1. **建议自动记录+对账闭环** — 莫荷发出的建议自动记入decisions.json的advice_timeline,每周对比实际持仓变化,统计准确率(✅ 已完成:/api/advice/record + advice_reconciliation.py + accuracy_stats.json)
|
||||
2. **MoFin Dashboard整合** — server.py应整合所有数据源,包括待确认决策、准确率统计等(✅ 已完成:决策库tab + 评估tab + 反馈闭环tab)
|
||||
3. **知微XMPP通信通道优化** — 当前xmpp_zhiwei_bot.py断线重连机制有缺陷(Event().wait阻塞),需修复(✅ 已完成:watchdog循环每10秒检查连接状态)
|
||||
4. **session跨profile检索** — 知微无法搜到莫荷CLI session的内容,需手动转发(✅ 已完成:session_search profile参数可用)
|
||||
5. **策略双维度评估体系** — 理论策略vs实际执行,分阶段跟踪,自动反馈闭环(✅ 已完成:strategy_evaluator.py + strategy_feedback.py + 每日/每周cron)
|
||||
6. **价格事件持久化** — price_monitor每分钟记录价格触发事件供回溯评估(✅ 已完成:price_events.json + record_event())
|
||||
|
||||
### tdx-relay 集成(小小莫Windows端 + 知微Linux端)
|
||||
|
||||
详见单独文档:`TDX_RELAY_COLLAB.md`
|
||||
|
||||
职责分工:
|
||||
- **小小莫**:Windows端 tdx-relay 开发维护(opentdx→招商证券7727→港股实时行情推送)
|
||||
- **知微**:Linux端 MoFin API 兼容(/api/update/realtime 已实现,/api/relay/status 待实现)+ price_monitor relay 检测+回退逻辑
|
||||
|
||||
当前状态:
|
||||
- ✅ `/api/update/realtime` 端点已在 server.py 中实现
|
||||
- ⏳ `relay_state.json` 持久化(待实现)
|
||||
- ⏳ `/api/relay/status` GET 端点(待实现)
|
||||
- ⏳ `price_monitor.py` relay 活跃检测(待实现)
|
||||
- ⏳ relay 离线时自动回退腾讯 API(待实现)
|
||||
|
||||
### 正在进行的优化(2026-06-12)
|
||||
|
||||
1. **报告格式精简** — 老爸反复强调太长无重点。已改为:重点推荐(≤3只)+风险关注(≤3只)+其余持仓一行。全文≤500字。
|
||||
2. **技术面分析取代百分比策略** — 支撑/压力位用枢轴点算法,止损=min(强支撑, 成本×0.85),买入区=弱撑~弱压之间,止盈在盈亏比≥1:2处。
|
||||
3. **MoFin 决策库重构** — 清空旧记录(标记obsolete),从6月11日起重新记录。新增 active_manual / current_recommend 标签,支持按此筛选排序。新增搜索框。
|
||||
4. **格式校验器** — cron_to_xmpp.py 新增 validate_format(),拦截无重点/超长/含模棱两可词语的报告。记录到 daily 汇总(不拦截推送,只记录违规)。
|
||||
@@ -0,0 +1,20 @@
|
||||
# Archive — 历史文档
|
||||
|
||||
这些文档是早期设计、需求分析、诊断报告。**不代表当前系统状态**。保留供参考。
|
||||
|
||||
| 文件 | 内容 | 日期 |
|
||||
|------|------|------|
|
||||
| REQUIREMENTS.md | 初始需求文档 | 2026-06 |
|
||||
| EXPERT_SYSTEM_DESIGN.md | 专家系统设计 | 2026-06 |
|
||||
| data-pipeline-diagnosis.md | 数据管道诊断 | 2026-06 |
|
||||
| refactor-for-xiaoxiao.md | 重构方案 | 2026-06 |
|
||||
| session-handover-20260630.md | 会话交接 | 2026-06 |
|
||||
| DATABASE_ARCHITECTURE.md | 旧 DB 架构(被 portfolio-data-model 取代) | 2026-06 |
|
||||
| mofin-database-architecture.md | 旧 DB 架构 | 2026-06 |
|
||||
| market-data-requirements.md | 旧市场数据需求 | 2026-06 |
|
||||
| market-screening-system-design.md | 旧市场筛选设计 | 2026-06 |
|
||||
| strategy-evaluation-requirements.md | 旧策略评估需求 | 2026-06 |
|
||||
| self-healing-loop.md | 旧自愈循环 | 2026-06 |
|
||||
| analyst-knowledge-log.md | 分析师知识日志 | 2026-07 |
|
||||
|
||||
当前系统文档见 `../README.md`。
|
||||
@@ -0,0 +1,189 @@
|
||||
---
|
||||
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/ 下的全部文档了解全貌
|
||||
@@ -0,0 +1,132 @@
|
||||
# 知微分析师知识日志
|
||||
|
||||
## 2026-06-11
|
||||
|
||||
### 新增条目
|
||||
- [BUG] 华恒生物688639 触发止损但 cron 报告里还显示"剩余空间很大"
|
||||
- 场景:2026-06-11 14:00 触发止损,策略状态已变
|
||||
- bug:cron_report 读 stale 数据 → 跟实际不一致
|
||||
- 修复:stale_push_wlin.py 加价格比对的权重
|
||||
|
||||
## 2026-06-29
|
||||
|
||||
### 修复
|
||||
- [BUG] intraday_health_check.py 价格监控误报
|
||||
- 问题:check_price_monitor() 用 pgrep 查进程(price_monitor是no_agent cron,不是daemon,必然找不到) + 用 price_events 表做心跳检测(平静市场0事件=误报)
|
||||
- 表现:TODO #27 "cron无最近运行记录" + TODO #29 "进程不在运行" → 自愈执行器误启动LLM处理
|
||||
- 修复:改用 cron jobs.json 的 last_run_at(主指标)+ portfolio.json 的 updated_at(副指标)
|
||||
- 文件:intraday_health_check.py → check_price_monitor() 函数重写
|
||||
- 验证:手动执行 intraday_health_check.py → [SILENT] 盘中自检通过 | 6项正常
|
||||
- [CLEANUP] 关闭残留TODO #27 和 #29(已自愈,价格监控正常)
|
||||
- [BUGFIX] macro_context_collector.py 关键词红绿灯误报(33条HIGH→7条)
|
||||
- 问题1:'核'独立匹配触发22条误报(核聚变/硬核科技/核心等非风险词匹配)
|
||||
- 问题2:'苹果.*涨价'触发合作类新闻(苹果牵手长鑫存储,MLCC涨价→非风险)
|
||||
- 问题3:'英伟达|' 分组的alternation导致单"英伟达"关键词即触发(应该是英伟达+负面词才触发)
|
||||
- 修复:战争/核正则移除过宽匹配;苹果正则加合作类负向排除;英伟达正则修正分组
|
||||
- 效果:10:05的198条新闻测试:33 HIGH→7 HIGH(3条真实+2条MEDIUM级+2条分析文引用)
|
||||
- 文件:macro_context_collector.py → HIGH_PATTERNS (行30-61)
|
||||
|
||||
### 自愈
|
||||
- [BUG] intraday_health_check.py 宏观风险HIGH TODO无详情
|
||||
- 问题:TODO #28 宏观风险HIGH 详情为空。intraday_health_check.py 读 risk.get("reason", ""),但 macro_risk_state.json 用 signals[].summary,没有 reason 字段 → reason始终为空
|
||||
- 修复:改成读 signals[0].summary 提取原因描述 + 增加 expired 标志检查(过期HIGH不报异常,改报⏳信息)
|
||||
- 文件:MoFin/scripts/intraday_health_check.py → check_signal_pipeline() 中宏观风险检查段
|
||||
- 验证:修复后运行 → [SILENT] 盘中自检通过 | 6项正常(不再因过期HIGH误报)
|
||||
|
||||
- [BUG] portfolio.json总资产计算错误 — 双重原因
|
||||
- 问题1:holding导入用了硬编码现金默认20,230,Dad截图现金73,758没用上
|
||||
- 问题2:import_holding_xls.py 对港股 double-conversion:券商的「最新市值」已经是人民币(shares × HKD价 × 汇率),脚本又做了 mv_cny = mkt_val × rate,导致港股市值少算约13.24%
|
||||
- 问题3:per_stock_reassess.py 更新了个股价格后,总资产没有随之更新(仍用导入时的旧值)
|
||||
- 修复:portfolio.json用 shares*price 重新求和(858,542)+ 现金73,758 = 总资产932,300
|
||||
- 文件:portfolio.json, import_holding_xls.py(去掉港股double-conversion + 去硬编码现金默认)
|
||||
- 经验:Dad的现金=截图现金,holding文件没有现金行。券商最新市值已经含汇率换算。
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 修复
|
||||
- [BUGFIX] macro_signal_consumer 修正覆盖信号仍导致level=high
|
||||
- 问题:LLM深度分析修正了采集器误报(写"修正覆盖"),但INSERT时保留了宏观-WATCH_HIGH sentiment。consumer聚合所有未处理信号时取最高级别→level=high,即使修正内容说"实际是MEDIUM"
|
||||
- 表现:state.json level=high但实际风险是MEDIUM。盘中自检持续产生"HIGH" TODO误报
|
||||
- 修复:consumer新增_effective_level()函数,检测"修正覆盖"摘要后取修正后的实际级别(HIGH→MEDIUM,零风险→INFO),不再只依赖sentiment字段
|
||||
- 文件:macro_signal_consumer.py → 聚合段新增_effective_level()逻辑
|
||||
- 配套:清理了state.json(恢复MEDIUM),关闭了残留TODO #39/#40
|
||||
- [DOC] macro-risk-scanner SKILL.md修正原则补充
|
||||
- 修正时必须同时更新overall_sentiment为修正后的级别(不再保留HIGH)
|
||||
- 修正后的INSERT使用正确sentiment(如宏观-WATCH_MEDIUM)
|
||||
- 新增SQL示例展示错误vs正确做法
|
||||
- 文件:SKILL.md → 修正原则段 + LLM修正工作流段
|
||||
|
||||
### 修复
|
||||
- [BUG] 个股行情数据来源不规范 — 海博思创266.02误读事件
|
||||
- 问题:2026-07-01 11:40对海博思创的分析中,我用了266.02作为当前价(实际265.00),并将K线描述为"光头光脚阴线"(实际是长下影线,低点248.68)。266.02来自新浪原始CSV的ask2字段(第二档卖盘价),被我误读为当前价
|
||||
- 根因:没有统一的权威价格源。LLM有时读portfolio.json、有时读decisions.json、有时直接解析原始API——解析CSV时字段极易混淆
|
||||
- 修复1(脚本级):创建 stock_quote.py — 统一行情查询工具。自动识别A股/港股,按东财→新浪→腾讯优先级获取,自带验证(price在[low,high]内,change_pct自洽)。输出结构化JSON,LLM禁止解析原始API
|
||||
- 修复2(管道级):mofin_collect.py 增加 stock_quote.py --all-holdings 注入步骤。每个cron分析前自动注入持仓行情数据,LLM只需读注入数据
|
||||
- 修复3(记忆级):增加"数据来源铁律"记忆条目——输出价格前必须验证
|
||||
- 文件:新增 MoFin/scripts/stock_quote.py,修改 mofin_collect.py(加步骤4),新增记忆条目
|
||||
- 原则:用脚本固定规范,不依赖LLM"随机遵守"
|
||||
### 审计
|
||||
- [AUDIT] 全系统"脚本强制规范"覆盖审计
|
||||
- 结果:开盘简报✓ 收盘简报✓ MoFin盘前中监控✓(已在mofin_collect中注入stock_quote) MoFin午后监控✓
|
||||
- 违规:策略评估-每日(stale_detector.py直接调用腾讯API) ✗ → 已修复:改调stock_quote.py,原腾讯API降级为兜底
|
||||
- 违规:策略评估SKILL.md写"数据源:腾讯API实时行情" ✗ → 已修复:改为"数据源:decisions.json/stock_quote.py"
|
||||
- 违规:芯片微装-价格监控prompt未指定数据源 ✗ → 已修复:添加"数据源铁律:从decisions.json或stock_quote.py获取"
|
||||
- 不修复:price_monitor.py是no_agent脚本,直接写portfolio.json供LLM读,不经过LLM解析,风险可控
|
||||
- ⚠️ 补充审计(12:21):此前标记「已修复」的 stale_detector.py 实际未改——代码仍直接调腾讯API qt.gtimg.cn。已重新修复:fetch_prices() 优先调 stock_quote.py,腾讯API降级为兜底fallback
|
||||
- 验证:stale_detector.py 当前运行输出正常(芯碁微装521.12 -5.15%、中钨高新95.86 +0.15%等),数据来源已切换至stock_quote.py
|
||||
- .pyc 回收规范验证:仅 macro_context_collector.py 有 .pyc 缓存(已清除+加固完整性校验),其余脚本 __pycache__ 为空
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 修复: macro_context_collector.py .pyc缓存过期导致误报复发
|
||||
|
||||
发现: self-healing executor 报告 12:00 采集器误将 KOSPI -1%(正常日内波动)和基金经理展望(正面评论)判为 HIGH 宏观风险。
|
||||
|
||||
根因: .pyc 缓存过期。当前 .py 的 HIGH_PATTERNS 已包含"指数+跌幅≥2%"阈值和"指数+暴跌词"强词检测,但 cron 运行时 Python 加载了过期 .pyc(旧版模式),导致 KOSPI -1% 依然匹配旧版"指数.*跌幅"模式。
|
||||
|
||||
修改:
|
||||
1. 删除 `__pycache__/` + touch `.py` — 强制重新编译
|
||||
2. 《macro_context_collector.py》加固模式完整性校验 _PATTERN_CHECKS:
|
||||
- 新增 index 8 检查: 必须包含"暴跌|熔断|闪崩|重挫"(禁止"跌幅"弱词命中)
|
||||
- 新增 index 9 检查: 必须包含"[2-9]%"(禁止 1% 正常波动触发)
|
||||
- 新增 _KNOWN_BAD_SIGS 旧版签名扫描: 检查"指数.*跌幅""|核|""英伟达|nvidia.*跌""导弹.*发射"是否残留
|
||||
3. 清除 stale macro_risk_state.json(level=high→expired)
|
||||
4. 关闭 TODO #41
|
||||
|
||||
验证: 三条误报标题在修复后均不触发 HIGH 匹配。
|
||||
|
||||
## 2026-07-02 修复:intraday_health_check.py 盘中自检三项BUG
|
||||
|
||||
**发现的问题:**
|
||||
1. 缺少 `sys.path.insert(0, "/home/hmo/MoFin")` → `from mo_data import ...` 报 `ModuleNotFoundError: No module named 'mo_data'`(自愈执行器报告为 "name 'mo_data' is not defined")
|
||||
2. `check_xiaoguo()` 里 `urllib.request.urlopen("http://node122:18003")` 在主机不可达时无限hang住(TCP SYN被防火墙丢,Python timeout失效),导致整个盘中自检超时
|
||||
3. `datetime.strptime` 格式 `"%Y-%m-%d %H:%M"` 与 `read_portfolio()` 返回的 `updated_at`(含秒:`"%Y-%m-%d %H:%M:%S"`)不匹配 → 解析Exception
|
||||
|
||||
**修改内容:**
|
||||
- `/home/hmo/MoFin/scripts/intraday_health_check.py`
|
||||
- 添加 `import socket` 和 `sys.path.insert(0, "/home/hmo/MoFin")`
|
||||
- `check_xiaoguo()`: 用 `socket.settimeout(3)` 替换 `urllib` HTTP检查,防止hang死
|
||||
- `check_price_monitor()`: 将 `strptime` 格式从 `"%Y-%m-%d %H:%M"` 改为 `"%Y-%m-%d %H:%M:%S"`
|
||||
- `check_http()`: 默认timeout从8秒降至5秒(加强健壮性)
|
||||
|
||||
**效果预期:**
|
||||
- 盘中自检不再因 `mo_data` 导入失败而报错
|
||||
- 盘中自检不再因 `node122` 不可达而超时hang死
|
||||
- 价格新鲜度检查正确解析 `updated_at` 时间戳
|
||||
- 相关TODO(#48, #52)已标记resolved
|
||||
|
||||
**发现的问题:**
|
||||
1. price_monitor.py 的 refresh_data_prices() 在 DB 持仓价格为 NULL 时崩溃。`s.get('price', 0)` 在 key 存在但值为 None 时返回 None(不是 0),导致 `abs(None - price)` 触发 TypeError。
|
||||
2. 港股备用通道(fetch_hk_eastmoney_fallback)每只港股有 1 秒 delay,09:30 开盘前港股 API 返回 0 价格,全部 HK 股票走降级通道空耗 ~14 秒。
|
||||
3. Hermes cron 版(profile/scripts/price_monitor.py)与系统 crontab 版(MoFin/price_monitor.py)并存,系统 crontab 每次运行会覆盖 JSON 文件。
|
||||
|
||||
**修改内容:**
|
||||
- `/home/hmo/.hermes/profiles/position-analyst/scripts/price_monitor.py`
|
||||
- 第 335-337 行:`old = s.get('price'); if old is None: old = 0` — 处理 DB NULL 价格
|
||||
- 第 377-379 行:同上,watchlist 更新部分
|
||||
- 第 305-311 行:港股降级通道增加 09:30 开盘检查,开盘前跳过
|
||||
|
||||
**效果预期:**
|
||||
- Hermes cron 版 price_monitor 不会再因 NULL 价格崩溃,DB 已更新 11 只 A 股持仓价格
|
||||
- 港股开盘前不会再空耗 14+ 秒走东财降级通道
|
||||
- 盘中健康检查下次运行时将看到新鲜数据,不再误报
|
||||
@@ -0,0 +1,180 @@
|
||||
# MoFin 系统数据管道诊断报告(2026-06-29 交笑笑重构参考)
|
||||
|
||||
## 一、当前数据架构总图
|
||||
|
||||
```
|
||||
腾讯实时行情API (qt.gtimg.cn / ifzq.gtimg.cn)
|
||||
│
|
||||
▼
|
||||
price_monitor.py (每2分钟 cron)
|
||||
│
|
||||
├──→ 写 portfolio.json(CNY 价 + 总市值 + 总资产 + 现金)
|
||||
│ ├── holdings[].price = CNY(港股 × HK_RATE)
|
||||
│ ├── total_mv = 持仓市值CNY之和
|
||||
│ ├── cash_available + cash_frozen = 现金CNY
|
||||
│ └── total_assets = total_mv + cash
|
||||
│
|
||||
├──→ 写 watchlist.json(CNY 价,同上规则)
|
||||
│
|
||||
├──→ 写 zone_breach.json(触发止损/买入区的事件)
|
||||
│
|
||||
├──→ 写 price_events.json(价格变化事件流)
|
||||
│
|
||||
└──→ 写 decisions.json(⚠️ 仅港股要转 CNY 的问题见下)
|
||||
├── price = 港股 HKD(腾讯原始值)
|
||||
└── stop_loss/entry/take_profit = HKD(策略生成时就是 HKD)
|
||||
|
||||
其他脚本:
|
||||
├── stale_push_wlin.py(自选买入提醒报告)── 自己拉腾讯API,HK价×0.87
|
||||
├── stale_detector.py(策略时效检查)── 读 decisions.json
|
||||
├── per_stock_reassess.py(单股重评)── 读 decisions.json
|
||||
├── system_audit.py(全局审计)── 读 decisions.json + portfolio.json
|
||||
├── collect_evaluation_data.py(策略评估前数据采集)
|
||||
└── strategy_evaluator.py(策略评估)── 读 collect_evaluation_data 输出
|
||||
```
|
||||
|
||||
## 二、已知系统性问题
|
||||
|
||||
### 问题1:港股价格币种不统一(最高频出错)
|
||||
|
||||
| 文件 | A股价 | 港股价 | 备注 |
|
||||
|------|-------|-------|------|
|
||||
| portfolio.json | CNY ✅ | CNY (×0.87) ✅ | price_monitor负责转 |
|
||||
| decisions.json | CNY ✅ | HKD ❌ | 策略生成时就是HKD,price_monitor曾试图转CNY又回退了 |
|
||||
| watchlist.json | CNY ✅ | CNY (×0.87) ✅ | price_monitor转的 |
|
||||
|
||||
**出错场景:**
|
||||
- LLM cron 报告读 portfolio.json(CNY)←→ 又读 decisions.json 止损(HKD)→ 交叉比较出错
|
||||
- 6/29 建滔积层板:「CNY 96.7 vs HKD 86.3 止损 → 止损已破」(错误的结论,实际盈利)
|
||||
|
||||
**当前状态(6/30):**
|
||||
- decisions.json 中的港股价格保留 HKD,加了 `currency: "HKD"` 标记
|
||||
- 但 stale_push_wlin 拉腾讯 API 后 ×0.87 再比较 decisions.json 的 HKD 止损 → 又错了
|
||||
- 根源:**比较时不知道文件里是什么币种**
|
||||
|
||||
### 问题2:总资产数字计算路径不统一
|
||||
|
||||
| 报告类型 | 总资产计算方式 | 风险 |
|
||||
|---------|--------------|------|
|
||||
| stale_push_wlin | 自己算:`sum(holdings.price×shares) + cash` | 可能用不同价格源 |
|
||||
| 开盘/收盘简报(LLM cron) | 读 portfolio.json 的 total_assets | 依赖 price_monitor 更新 |
|
||||
| 每日策略评估(LLM cron) | 读 portfolio.json 的 total_assets | 同上 |
|
||||
| price_monitor 内部 | 计算 total_mv + cash → 写回 portfolio.json | 唯一正确的地方 |
|
||||
|
||||
**出错场景:** 不同报告读不同来源,数字不一致。Dad 看到「总资产每次都不一样」。
|
||||
|
||||
### 问题3:现金更新没有日志
|
||||
|
||||
流程是:Dad 发截图 → 我手动解析 → 修改 portfolio.json 的 cash_available 字段。但:
|
||||
- 没有 changelog 记录「什么时候、为什么改了现金数字」
|
||||
- 冻结资金(cash_frozen)经常漏算
|
||||
- 如果 Dad 在券商端操作了(买卖成交),系统不知道 → 现金数字滞后
|
||||
|
||||
### 问题4:价格滞后
|
||||
|
||||
- price_monitor 每 2 分钟拉腾讯 API,正确无误
|
||||
- 但 LLM cron 报告的 prompt 没有强制要求读 `price_monitor` 刚刷新的价格
|
||||
- 有些报告自己拉腾讯 API(可能拉的是不同时间的值)
|
||||
|
||||
## 三、建议重构方向(给笑笑)
|
||||
|
||||
### 3.1 数据层统一
|
||||
|
||||
```
|
||||
单一日志数据源原则:
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ Single Source of Truth │
|
||||
│ decisions.json (统一存HKD,不做币种转换) │
|
||||
│ - price = 原始币种 │
|
||||
│ - currency = "HKD" / "CNY" │
|
||||
│ - stop_loss/entry/take_profit = 原始币种 │
|
||||
└─────────────────────────────────────────────────┘
|
||||
|
||||
所有报告脚本只读 decisions.json,不自拉价格
|
||||
不是由报告脚本来决定价格→而是由 price_monitor 来写入 decisions.json
|
||||
```
|
||||
|
||||
### 3.2 统一价格写入路径
|
||||
|
||||
```
|
||||
腾讯API → price_monitor(唯一入口)
|
||||
│
|
||||
├──→ decisions.json.price(原始币种)
|
||||
├──→ decisions.json.price_cny(CNY折算值,做总资产用)
|
||||
├──→ portfolio.json.total_mv(CNY)
|
||||
└──→ portfolio.json.holdings[].price_cny
|
||||
```
|
||||
|
||||
### 3.3 现金管理系统化
|
||||
|
||||
```
|
||||
现金变更的每个来源记录 changelog:
|
||||
- Dad 发送截图 → 系统解析 → 写入 cash_available + cash_frozen + changelog
|
||||
- price_monitor 检测到 cash_frozen 到期释放 → 自动调整
|
||||
- 持仓卖出 → 自动更新 cash
|
||||
|
||||
cash 字段在 portfolio.json 中要有:
|
||||
{
|
||||
"cash_available": 73758.85,
|
||||
"cash_frozen": 39481.40,
|
||||
"cash_updated_at": "2026-06-29 15:30",
|
||||
"cash_changelog": [
|
||||
{"time": "2026-06-29 10:15", "delta": +18920, "reason": "卖出法拉电子100股@189.2"},
|
||||
{"time": "2026-06-27 09:00", "delta": 0, "reason": "Dad截图初始化,含冻结39,481"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 比较逻辑必须带币种感知
|
||||
|
||||
```python
|
||||
def compare_price_vs_stop(current_price, stop_loss, currency="CNY"):
|
||||
\"\"\"同币种比较,跨币种抛异常\"\"\"
|
||||
# 永远不要做跨币种数字比较
|
||||
```
|
||||
|
||||
### 3.5 数据管道重新设计
|
||||
|
||||
```
|
||||
价格层: price_monitor(唯一能拉腾讯API的地方)
|
||||
│
|
||||
缓存层: prices_cache.json(holdings + watchlist 的实时股价,原始币种)
|
||||
│
|
||||
数据层: decisions.json 从 prices_cache 读最新价更新
|
||||
portfolio.json 从 prices_cache 读CNY价更新总资产
|
||||
│
|
||||
报告层: 所有 cron 只读 decisions.json + portfolio.json 的 total_assets
|
||||
不自拉任何外部API
|
||||
```
|
||||
|
||||
## 四、当前文件清单
|
||||
|
||||
### 核心脚本
|
||||
| 文件 | 用途 | 当前状态 |
|
||||
|------|------|---------|
|
||||
| price_monitor.py | 实时价格拉取+写盘 | ✅ 可用,但港股CNY写入加了又回退了 |
|
||||
| stale_push_wlin.py | 自选买入区提醒(推XMPP) | ⚠️ HK价重复×0.87问题 |
|
||||
| stale_detector.py | 策略时效性检查 | ⚠️ 币种感知逻辑不完整 |
|
||||
| per_stock_reassess.py | 单股策略重评 | ✅ 可用 |
|
||||
| strategy_lifecycle.py | 策略生命周期核心引擎 | ⚠️ HK价未统一 |
|
||||
| import_holding_xls.py | 导入券商持有文件 | ✅ 可用 |
|
||||
| data_validate.py | 数据一致性检查(新增) | ⚠️ 6/29新建,检查项不全 |
|
||||
| capital_flow_collector.py | 资金流数据采集(新增) | ✅ 可用 |
|
||||
| fix_trigger.py | 一次性trigger修复(已完成) | ✅ 已用 |
|
||||
| clean_watchlist.py | 日常自选清理 | ✅ 可用 |
|
||||
|
||||
### 核心数据文件
|
||||
| 文件 | 币种状态 |
|
||||
|------|---------|
|
||||
| decisions.json | A股CNY / 港股HKD(标记currency字段) |
|
||||
| portfolio.json | 统一CNY |
|
||||
| watchlist.json | 统一CNY |
|
||||
| zone_breach.json | N/A |
|
||||
|
||||
## 五、当前TODO
|
||||
|
||||
- 接替知微继续修正的思路 → 读 MoFin 项目代码 + skills + cron jobs,按3.1-3.5重构
|
||||
- 特别注意 stale_push_wlin 的 HK 价 ×0.87 逻辑(已冗余,因为 price 已 CNY)
|
||||
- 确保所有比较函数同币种
|
||||
- 现金 changelog 机制
|
||||
- 删除所有冗余的「自拉腾讯API」逻辑(统一由 price_monitor 做)
|
||||
@@ -0,0 +1,387 @@
|
||||
---
|
||||
title: 市场数据体系 + 小果情报分析需求文档
|
||||
tags: [需求文档, 知微, 市场数据, 小果, 行业热点]
|
||||
created: 2026-06-18
|
||||
status: 活跃
|
||||
priority: 高
|
||||
---
|
||||
|
||||
# 市场数据体系 + 小果情报分析需求文档
|
||||
|
||||
## 一、痛点现状
|
||||
|
||||
### 1.1 MoFin 市场模块三个子页面全部失效
|
||||
|
||||
| 页面 | 状态 | 问题 |
|
||||
|------|------|------|
|
||||
| 行业热点 | 数据虚假 | 行业涨幅为编造(如塑料+389%),数据源是 LLM cron 凭空生成,不是真实API |
|
||||
| 知微洞察 | 空白 | "暂无洞察",没有分析流程 |
|
||||
| 潜力股挖掘 | 空白 | "暂无挖掘",没有挖掘流程 |
|
||||
|
||||
根因:原 cron `b818e2bfd8d1`(市场数据采集)是 LLM 驱动的,不是真正的数据采集脚本。LLM 没有真实数据源,只能编造。该 cron 已失效,但 market.json 中的假数据还在。
|
||||
|
||||
### 1.2 行业数据割裂
|
||||
|
||||
- `stock_profiles.json` 中 16/38 只有行业数据(仅覆盖持仓股),22只自选股行业为空
|
||||
- 行业分类无标准化体系(各行业中文名不一致)
|
||||
- 无自动化行业补全流程
|
||||
- `market_watch.py`(东方财富API行业采集脚本)已开发但未接入 Dashboard
|
||||
|
||||
### 1.3 小果本地 LLM 可用但未被利用
|
||||
|
||||
- 小果(node122:18003, MLX Qwen3.6-27B, API port 8645)
|
||||
- 免费(本地运行),适合做不需要高推理能力但费 token 的重复活
|
||||
- 当前未被整合到知微的情报分析流程中
|
||||
|
||||
---
|
||||
|
||||
## 二、总体设计原则
|
||||
|
||||
### 2.1 数据来源唯一铁律
|
||||
|
||||
**所有 MoFin Dashboard 展示的数据,必须来自真实API,禁止 LLM 编造。**
|
||||
LLM 只能分析真实数据,不能生成伪数据。
|
||||
|
||||
### 2.2 分类规范
|
||||
|
||||
- **市场模块展示内容 = 真实API数据 + 知微(智)分析 + 小果情报**
|
||||
- 数据层(纯脚本)→ 分析层(LLM/知微)→ 展示层(Dashboard)
|
||||
- 每条展示数据的来源必须可追溯
|
||||
|
||||
### 2.3 小果定位
|
||||
|
||||
- **不是用来替代知微的**,是辅助工具
|
||||
- 跑在本地 Mac Mini,免费,但慢且推理能力弱
|
||||
- 适合:分类/标注/情感分析/简单判断
|
||||
- 不适合:复杂推理/多步决策/需要深度分析
|
||||
- 输出给知微参考,知微做最终判断
|
||||
|
||||
---
|
||||
|
||||
## 三、模块一:行业热点(行业数据采集体系)
|
||||
|
||||
### 3.1 核心流程
|
||||
|
||||
```
|
||||
东方财富 push2 API
|
||||
↓ (market_watch.py, no_agent 纯脚本, 每30分钟)
|
||||
行业原始数据 (涨跌/成交量/资金流向/上涨家数/下跌家数)
|
||||
↓ (清洗+标准化)
|
||||
market.json (标准化数据,写入 Dashboard data/)
|
||||
↓ (供各模块使用)
|
||||
MoFin 行业热点 | 知微D2行业分析 | 小果情报参考
|
||||
```
|
||||
|
||||
### 3.2 API 规范
|
||||
|
||||
**首选:东方财富 push2 API**
|
||||
|
||||
行业板块:
|
||||
```
|
||||
GET https://push2.eastmoney.com/api/qt/clist/get
|
||||
?pn=1&pz=15&po=1&np=1
|
||||
&fields=f2,f3,f4,f12,f14
|
||||
&fs=m:90+t:2
|
||||
```
|
||||
返回字段:f2(最新价), f3(涨跌幅%), f4(涨跌额), f12(代码), f14(名称)
|
||||
|
||||
概念板块:
|
||||
```
|
||||
GET https://push2.eastmoney.com/api/qt/clist/get
|
||||
?pn=1&pz=10&po=1&np=1
|
||||
&fields=f2,f3,f4,f12,f14
|
||||
&fs=m:90+t:3
|
||||
```
|
||||
|
||||
**降级:akshare(同花顺数据)**
|
||||
```
|
||||
ak.stock_board_industry_summary_ths()
|
||||
→ 涨跌幅, 上涨家数, 下跌家数, 净流入资金
|
||||
```
|
||||
|
||||
**三级降级:web_search 兜底**
|
||||
当前两个API都失败时,web_search 搜索当日行业涨跌排行补充
|
||||
|
||||
### 3.3 行业分类标准化
|
||||
|
||||
建立一级/二级行业分类体系(参考申万/Swift行业分类):
|
||||
|
||||
| 一级 | 二级 | 对应持仓/自选 |
|
||||
|------|------|-------------|
|
||||
| TMT/科技 | 半导体/消费电子/互联网/通信设备 | 中芯/德明利/丘钛/腾讯/阿里/博创/长飞 |
|
||||
| 新能源 | 新能源汽车/储能/新能源材料 | 比亚迪/宁德/海博思创/中科电气/信义光能 |
|
||||
| 金融地产 | 银行/保险/房地产 | 招商银行/中银香港/中国平安/万科/人寿 |
|
||||
| 医药 | 创新药/医药流通 | 百济神州/辽宁成大 |
|
||||
| 工业材料 | 有色金属/复合材料/电子元器件/新材料 | 紫金矿/法拉电子/中科/诺德 |
|
||||
| 资源 | 黄金/贵金属 | 黄金ETF |
|
||||
| 消费 | 汽车/消费电子 | 小鹏/TCL |
|
||||
| ... | ... | ... |
|
||||
|
||||
**存量补全规则**:
|
||||
- 持仓股:补全行业 + 业务描述(优先级高)
|
||||
- 自选股:补全行业(优先级中)
|
||||
- 新入自选:创建时即补全行业(规范)
|
||||
|
||||
补全方法:优先查腾讯 API 的行业字段,次选 akshare,最后 web_search
|
||||
|
||||
### 3.4 market.json 输出结构
|
||||
|
||||
```json
|
||||
{
|
||||
"timestamp": "2026-06-18 14:30",
|
||||
"total_sectors": 56,
|
||||
"up_ratio": 45.2,
|
||||
"mood": "neutral",
|
||||
"sectors": [
|
||||
{
|
||||
"name": "半导体",
|
||||
"code": "BK0477",
|
||||
"price": 5287.63,
|
||||
"change_pct": 2.35,
|
||||
"volume": 325.6,
|
||||
"turnover": 528.4,
|
||||
"up_count": 68,
|
||||
"down_count": 12,
|
||||
"net_inflow": 12.5
|
||||
}
|
||||
],
|
||||
"concepts": [...],
|
||||
"top_gainers": [前5],
|
||||
"top_losers": [末3],
|
||||
"source": "eastmoney"
|
||||
}
|
||||
```
|
||||
|
||||
字段规范:
|
||||
- `change_pct`: **百分数**(如+2.35表示涨2.35%),不是绝对点数
|
||||
- `price`: 板块指数点,不是股票价格
|
||||
- `up_count/down_count`: 板块内上涨/下跌家数(仅 ak 降级时才有)
|
||||
- `net_inflow`: 资金净流入(亿元,仅 ak 降级时才有)
|
||||
- `source`: 数据来源标识(eastmoney/ths/web)
|
||||
|
||||
### 3.5 stock_profiles.json 行业数据维护
|
||||
|
||||
**自动补全流程**(每周/每月):
|
||||
```
|
||||
第1步:筛选 stock_profiles.json 中 sector 为空的条目
|
||||
第2步:查腾讯 API 的行业分类字段(港股/A股)→ 匹配申万行业
|
||||
第3步:腾讯没有 → 查 akshare 股票基本信息
|
||||
第4步:都不行 → web_search 查公司主营业务,提取行业关键词
|
||||
第5步:写入 stock_profiles.json
|
||||
第6步:记录补全日志(谁补的、依据来源、置信度)
|
||||
```
|
||||
|
||||
**人工审核流程**:
|
||||
- 自动补全的行业标记为"待审核"
|
||||
- 知微在分析中遇到缺失/错误时手动修正
|
||||
- 老爸也可以直接编辑
|
||||
|
||||
---
|
||||
|
||||
## 四、模块二:知微洞察 + 潜力股挖掘
|
||||
|
||||
### 4.1 知微洞察
|
||||
|
||||
定义:基于行业数据和持仓分析,每日输出 1-3 条有操作价值的洞察。
|
||||
|
||||
**数据来源**:
|
||||
- market.json 行业热点(当日涨跌幅+资金流向)
|
||||
- decisions.json 策略评估结果
|
||||
- 小果情报分析(见第五部分)
|
||||
- web_search 新闻
|
||||
|
||||
**洞察类型**:
|
||||
|
||||
| 类型 | 触发条件 | 示例 |
|
||||
|------|---------|------|
|
||||
| 行业轮动预警 | 持仓行业连续3天跑输大盘>2% | 新能源材料连续3天跑输,需关注 |
|
||||
| 资金异动提醒 | 行业资金净流入/出异常>5亿 | 半导体单日净流入12亿,板块转强 |
|
||||
| 策略调整建议 | 某行业趋势反转,影响持仓策略 | 银行板块跌破MA60,万科止损需收紧 |
|
||||
| 新机会发现 | 非持仓行业连续强势>3天 | 军工板块连涨3天,值得关注 |
|
||||
| 风险预警 | 行业政策突变/突发事件 | 美国关税政策影响光伏行业 |
|
||||
|
||||
**输出位置**:
|
||||
- MoFin Dashboard → 知微洞察
|
||||
- XMPP 推送(有实质内容才推)
|
||||
- 关联到策略评估的 D5 消息面
|
||||
|
||||
### 4.2 潜力股挖掘
|
||||
|
||||
定义:从行业热点中筛选出与现有持仓/自选相关的潜力标的。
|
||||
|
||||
**挖掘流程**:
|
||||
1. 每日从行业热点中找出最强势的 1-3 个行业
|
||||
2. 从强势行业中筛选出:基本面+技术面+估值 都符合标准的个股
|
||||
3. 对比现有持仓/自选,去重
|
||||
4. 写入 watchlist.json(如果符合买入条件)
|
||||
5. 输出到 MoFin 潜力股挖掘
|
||||
|
||||
**筛选标准**:
|
||||
- 所属行业排名前20%(当日涨幅)
|
||||
- PE/估值合理(非亏损股)
|
||||
- 技术形态向好(近期有放量突破)
|
||||
- 与现有持仓/自选不重复
|
||||
|
||||
**输出形式**:
|
||||
- 每只标的名 + 行业 + 选取理由(一句话)
|
||||
- 建议关注级别(高/中/低)
|
||||
- 建议买入区间(可选)
|
||||
|
||||
---
|
||||
|
||||
## 五、模块三:小果情报分析
|
||||
|
||||
### 5.1 小果能力概述
|
||||
|
||||
| 能力 | 适用场景 | 精度要求 | 频率 |
|
||||
|------|---------|---------|------|
|
||||
| 新闻情感分类 | 个股新闻/行业新闻 → 正面/负面/中性 | 70%+ 即可 | 每日 |
|
||||
| 量价异常标注 | 当日成交量/换手率/量比异常识别 | 80%+ | 每日20:00 |
|
||||
| 行业热词提取 | 行业新闻关键词提取 | 可接受 | 每日 |
|
||||
| 简单问答 | 替代知微做低精度任务 | 看情况 | 按需 |
|
||||
|
||||
**调用方式**:
|
||||
- 知微通过 Hermes delegate_task 向 xiaoguo profile 派发任务
|
||||
- 或通过 API 直调(http://node122:8645)
|
||||
- 小果的结果作为知微分析的输入参考
|
||||
|
||||
### 5.2 新闻情感分析
|
||||
|
||||
**输入**:从 web_search 搜索到的个股/行业新闻标题+摘要
|
||||
|
||||
**输出**(JSON):
|
||||
```json
|
||||
{
|
||||
"code": "00700",
|
||||
"name": "腾讯控股",
|
||||
"news": [
|
||||
{
|
||||
"title": "腾讯游戏业务Q2增长超预期",
|
||||
"source": "新浪财经",
|
||||
"sentiment": "positive",
|
||||
"confidence": 0.85,
|
||||
"keywords": ["游戏", "超预期", "增长"]
|
||||
}
|
||||
],
|
||||
"overall_sentiment": "positive"
|
||||
}
|
||||
```
|
||||
|
||||
**实现方式**:
|
||||
- 知微在评估 cron 中,web_search 拉取新闻后,将新闻文本发给小果分类
|
||||
- 小果返回情感标签 + 置信度
|
||||
- 知微汇总到 D5 消息面分析
|
||||
|
||||
### 5.3 量价异常标注
|
||||
|
||||
**输入**:当日行情数据(收评)——价格/成交量/换手率/量比
|
||||
|
||||
**输出**(JSON):
|
||||
```json
|
||||
{
|
||||
"code": "300750",
|
||||
"name": "宁德时代",
|
||||
"anomalies": [
|
||||
{
|
||||
"type": "volume_surge",
|
||||
"detail": "今日成交量3.2倍于20日均量",
|
||||
"assessment": "放量下跌,警惕"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**异常类型**:
|
||||
- `volume_surge`: 量比>2 的异常放量
|
||||
- `volume_shrink`: 量比<0.5 的异常缩量
|
||||
- `price_volume_divergence`: 价量背离(价涨量缩或价跌量放)
|
||||
- `turnover_spike`: 换手率异常高(>20只日均换手3倍)
|
||||
- `amplitude_surge`: 振幅异常大
|
||||
|
||||
**实现方式**:
|
||||
- 数据收集脚本(collect_evaluation_data.py)收评后,将当日数据发给小果
|
||||
- 小果标注异常点
|
||||
- 标注结果写入 evaluation_input.json 的 anomaly 字段
|
||||
|
||||
### 5.4 持续情报监控(新增)
|
||||
|
||||
让**小果持续跑**,不只在收评时分析:
|
||||
|
||||
```
|
||||
小果持续运行(每15-30分钟)
|
||||
↓
|
||||
扫描行业热点数据(market.json)
|
||||
↓
|
||||
发现异常 → 写入 小果情报日志
|
||||
↓
|
||||
知微评估 cron 读取情报日志,判断是否有价值 → 整合到分析报告
|
||||
```
|
||||
|
||||
**持续监控内容**:
|
||||
- 行业排行榜变化:前3名/末3名的行业
|
||||
- 涨跌比变化:上涨/下跌比例突变
|
||||
- 资金流向变化:突然转向的行业
|
||||
- 新闻突发:web_search 发现的重大新闻
|
||||
|
||||
---
|
||||
|
||||
## 六、废弃清单
|
||||
|
||||
### 立即废弃
|
||||
|
||||
| 组件 | 原因 | 替代 |
|
||||
|------|------|------|
|
||||
| `strategy_evaluator.py` 中的评估逻辑(R/R、评分、阶段一/二) | LLM cron 做六维评估,脚本不做判断 | 保留脚本做数据采集/统计部分 |
|
||||
| 旧 cron `b818e2bfd8d1`(市场数据采集 LLM 版) | 不可靠、数据虚假 | 新建 no_agent market_watch cron |
|
||||
| `market.json` 旧数据 | 虚假数据 | 新 market_watch 覆盖 |
|
||||
|
||||
### 逐步废弃
|
||||
|
||||
| 组件 | 原因 | 替代 |
|
||||
|------|------|------|
|
||||
| 旧 `EXPERT_SYSTEM_DESIGN.md`(项目目录和 Dashboard 目录各一份) | 过时,与新系统不一致 | 新需求文档统一管理 |
|
||||
| `stock_profiles.json` 中空字段 | 无数据占位 | 自动补全脚本 |
|
||||
|
||||
---
|
||||
|
||||
## 七、实施优先级
|
||||
|
||||
### P0(当前可做)
|
||||
|
||||
1. 修复 market_watch 脚本:输出目录改为 Dashboard data/
|
||||
2. 创建 market_watch cron(no_agent,每30分钟)
|
||||
3. 小果 API 调用验证(发一条简单测试)
|
||||
4. 废弃旧 market.json + 旧 cron
|
||||
|
||||
### P1(本周)
|
||||
|
||||
5. stock_profiles.json 行业自动补全脚本
|
||||
6. 知微洞察 MVP(每日1条有价值洞察)
|
||||
7. 小果新闻情感分析接入
|
||||
|
||||
### P2(下周)
|
||||
|
||||
8. 潜力股挖掘 MVP
|
||||
9. 小果持续情报监控
|
||||
10. 行业数据刷新 Dashboard 展示
|
||||
|
||||
### P3(远期)
|
||||
|
||||
11. 行业资金流向可视化
|
||||
12. 行业轮动预警系统
|
||||
13. 小果自主情报Bot(主动推送)
|
||||
|
||||
---
|
||||
|
||||
## 八、关联文件规范
|
||||
|
||||
所有本需求涉及的组件,必须在以下文件中标注链接:
|
||||
|
||||
- `strategy-evaluation` skill 中标注 D2/D5 数据源为 market.json + 小果
|
||||
- `mofin-system-arch` skill(如有)中标注新模块
|
||||
- `collect_evaluation_data.py` 中标注加入行业数据合并
|
||||
- 本需求文档链接进所有相关 skill 的 references 部分
|
||||
|
||||
---
|
||||
|
||||
*本需求文档为权威需求,高于任何 skill/记忆/脚本中的描述。如有不一致,以本文档为准。*
|
||||
@@ -0,0 +1,187 @@
|
||||
# 全市场潜力股挖掘系统设计
|
||||
|
||||
## 目标
|
||||
|
||||
打破持仓和自选的局限,从全 A 股市场挖掘新投资标的,附带入场策略和动态星级评分。
|
||||
|
||||
## 整体架构(两层式)
|
||||
|
||||
```
|
||||
市场数据(market.json)
|
||||
│ 每30分更新
|
||||
▼
|
||||
┌──────────────────────────────────────┐
|
||||
│ 第一层:小果本地LLM · 高频低耗 │
|
||||
│ │
|
||||
│ 每轮1-2个板块,积少成多覆盖全市场 │
|
||||
│ → 分析板块趋势 │
|
||||
│ → 筛选成分股 │
|
||||
│ → 给出初步评分+策略 │
|
||||
│ → 写入候选池(candidate_pool.json) │
|
||||
└──────────────────┬───────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────┐
|
||||
│ 第二层:知微(主模型)· 低频高质 │
|
||||
│ │
|
||||
│ 每日收盘后 │
|
||||
│ → 读候选池 │
|
||||
│ → 用技术分析+策略引擎验证 │
|
||||
│ → 确认星级(5/4.5/4/3.5/3) │
|
||||
│ → 输出最终推荐+推送 │
|
||||
│ → 已推荐的标记 promoted │
|
||||
└──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 候选池设计
|
||||
|
||||
### candidate_pool.json 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"last_updated": "2026-06-19 15:30",
|
||||
"total_candidates": 12,
|
||||
"sectors_analyzed_today": ["半导体", "消费电子", "汽车零部件"],
|
||||
"candidates": [
|
||||
{
|
||||
"code": "600000",
|
||||
"name": "XX股份",
|
||||
"sector": "半导体",
|
||||
"added_at": "2026-06-19 10:30",
|
||||
"last_updated": "2026-06-19 15:30",
|
||||
"num_observations": 3,
|
||||
"xiaoguo_score": 8.2,
|
||||
"xiaoguo_reason": "放量突破前高,板块龙头",
|
||||
"xiaoguo_strategy": {
|
||||
"entry_range": "18.5~19.2",
|
||||
"stop_loss": "17.5",
|
||||
"target": "22.0"
|
||||
},
|
||||
"score_history": [
|
||||
{"date": "2026-06-19 10:30", "score": 7.5},
|
||||
{"date": "2026-06-19 11:00", "score": 8.0},
|
||||
{"date": "2026-06-19 15:30", "score": 8.2}
|
||||
],
|
||||
"zhiwei_star": null,
|
||||
"zhiwei_reviewed": false,
|
||||
"zhiwei_reviewed_at": null,
|
||||
"promoted": false,
|
||||
"promoted_at": null,
|
||||
"dropped": false,
|
||||
"drop_reason": null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 候选池治理规则
|
||||
|
||||
- 评分历程 >= 3 次且均分 < 5 → 自动淘汰
|
||||
- 连续 3 次评分下降 → 标记预警,下轮淘汰
|
||||
- 超过 7 天未评分 → 标记过期待重评
|
||||
- 已 promoted(确认推荐)→ 保留供回顾,不重复推
|
||||
|
||||
## 第一层:小果筛选(no_agent 脚本)
|
||||
|
||||
### 文件:market_screener.py
|
||||
|
||||
**触发频率:** 每 60 分钟(跟随 market_watch 节奏,间隔一次执行)
|
||||
|
||||
**每轮流程:**
|
||||
|
||||
1. 读 market.json → 取行业板块涨幅排名
|
||||
2. 选择本轮分析的板块:
|
||||
- 优先级:涨幅前 10 中「累计分析次数最少」的板块
|
||||
- 确保一周内覆盖所有活跃板块
|
||||
- 每轮分析 2 个板块
|
||||
3. 对每个板块:
|
||||
a. `ak.stock_board_industry_cons_ths()` → 取成分股
|
||||
b. 基础过滤:涨幅 > 0、价格 3~100 元、有成交量
|
||||
c. 取前 5~8 只候选
|
||||
d. 调小果 LLM API 分析 → 返回评分+策略
|
||||
4. 更新 candidate_pool.json(新增候选 + 刷新已有候选的评分)
|
||||
|
||||
**小果 LLM Prompt:**
|
||||
|
||||
```
|
||||
你是一位A股市场分析助手。分析以下板块和个股,筛选潜力候选股。
|
||||
|
||||
板块:{sector_name}
|
||||
板块涨幅:{change}%
|
||||
上涨/总家数:{up_count}/{total_count}
|
||||
资金净流入:{net_inflow}亿
|
||||
领涨股:{lead_stock} +{lead_stock_change}%
|
||||
|
||||
成分股(涨幅前8):
|
||||
代码 | 名称 | 现价 | 涨跌幅 | 换手率
|
||||
{a} | {b} | {c} | {d} | {e}
|
||||
|
||||
判断标准:
|
||||
1. 板块是真强势还是短期反弹?看量价配合和领涨股持续性
|
||||
2. 个股:量价配合好、趋势健康、不是单纯跟涨
|
||||
3. 给出 1-10 分(7分以上才值得关注)
|
||||
|
||||
输出JSON:
|
||||
{
|
||||
"sector_judgment": "强势|中性|弱势",
|
||||
"sector_reason": "一句话理由",
|
||||
"candidates": [
|
||||
{
|
||||
"code": "600xxx",
|
||||
"name": "名称",
|
||||
"score": 8.5,
|
||||
"reason": "选股理由含技术面特征",
|
||||
"entry_range": "18.5~19.2",
|
||||
"stop_loss": "17.5",
|
||||
"target": "22.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**代码注意事项:**
|
||||
- 小果 API 调用超时设 120s(27B 模型较慢)
|
||||
- 调用失败时跳过该板块,下次重试
|
||||
- 输出只写文件,不输出到 stdout(no_agent 静默模式)
|
||||
|
||||
## 第二层:知微精选(LLM cron)
|
||||
|
||||
**触发时间:** 每日 16:00(收盘后)
|
||||
|
||||
**流程:**
|
||||
1. 读 candidate_pool.json → 取未 reviewed 且评分 >= 7 的候选
|
||||
2. 对每个候选用我的技术分析工具验证
|
||||
3. 综合打分 → 星级(5/4.5/4/3.5/3)
|
||||
4. 输出最终 2-3 只推荐(含完整策略)
|
||||
5. 写入 market.json 的 potential_stocks 字段
|
||||
6. 标记 promoted
|
||||
|
||||
**星级标准:**
|
||||
- 5.0:强趋势+板块强势+技术面完美+入场时机佳
|
||||
- 4.5:趋势健康+板块向好+技术面良好+有安全边际
|
||||
- 4.0:板块和个股都OK,但缺明确催化剂
|
||||
- 3.5:有逻辑但需要等待更好入场点
|
||||
- 3.0以下:不推荐
|
||||
|
||||
## 时序与 cron 设计
|
||||
|
||||
| 时间 | 组件 | 类型 | 频率 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| 9:00~15:30 | market_watch | no_agent | 每30分 | 已有,采集板块数据 |
|
||||
| 9:30~15:30 | market_screener | no_agent | 每60分 | 新脚本,小果筛股 |
|
||||
| 16:00 | 市场精选推荐 | LLM | 每日 | 新cron,我出最终推荐 |
|
||||
|
||||
## 文件清单
|
||||
|
||||
| 文件 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| /home/hmo/web-dashboard/market_screener.py | 新脚本 | 小果筛选引擎 |
|
||||
| /home/hmo/web-dashboard/data/candidate_pool.json | 新数据 | 候选池 |
|
||||
| /home/hmo/web-dashboard/market_insight.py | 废弃 | 被替换 |
|
||||
| /home/hmo/web-dashboard/inject_xiaoguo_insight.py | 保留 | 仍需要注入情感到market.json |
|
||||
|
||||
## 关联修改
|
||||
|
||||
1. market_insight.py 停用(cron 改为新脚本)
|
||||
2. 新 cron job:市场精选推荐(LLM,16:00)
|
||||
3. 小果筛选 cron:market_screener.py(no_agent,每60分)
|
||||
@@ -0,0 +1,395 @@
|
||||
# MoFin 统一数据库架构设计
|
||||
|
||||
## 目标
|
||||
|
||||
将 MoFin 系统目前散落在各 JSON 文件中的数据统一纳入 SQLite 数据库,实现:
|
||||
- 数据关系化(板块 ↔ 个股 ↔ 持仓 ↔ 策略,SQL join 直连)
|
||||
- 历史可追溯(板块快照、价格序列、评分变更全部时序化)
|
||||
- 操作 no_agent 化(纯 SQL 即可完成大部分查询和分析)
|
||||
- 增量迁移(现有 JSON 不动,新数据双写,逐步切换)
|
||||
|
||||
---
|
||||
|
||||
## 一、数据库概览
|
||||
|
||||
```
|
||||
数据库文件: /home/hmo/web-dashboard/data/mofin.db
|
||||
引擎: SQLite 3
|
||||
```
|
||||
|
||||
### 逻辑分组
|
||||
|
||||
| 组 | 表 | 说明 |
|
||||
|----|-----|------|
|
||||
| 市场 | market_snapshots, sector_snapshots | 全市场板块快照(每30分) |
|
||||
| 个股 | stocks, stock_daily, stock_weekly, stock_monthly, stock_fundamentals | 个股K线+基本面 |
|
||||
| 板块成分 | stock_sectors | 个股所属板块映射 |
|
||||
| 持仓 | holdings, holding_strategies | 持仓股+策略参数 |
|
||||
| 自选 | watchlist_stocks | 自选股+买入区 |
|
||||
| 候选池 | candidates, candidate_score_history | 小果+知微潜力股推荐 |
|
||||
| 事件 | price_events, zone_breaches | 价格预警、区间触发 |
|
||||
| 策略评估 | strategy_evaluations | 策略重评记录 |
|
||||
|
||||
---
|
||||
|
||||
## 二、表结构详述
|
||||
|
||||
### 2.1 市场/板块快照
|
||||
|
||||
核心时间序列表。每次 market_watch 执行(每30分)写一条 snapshot,再把每个板块的数据写入 sector_snapshots。
|
||||
|
||||
```sql
|
||||
-- 每次采集的元信息
|
||||
CREATE TABLE market_snapshots (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
timestamp TEXT NOT NULL, -- '2026-06-19 15:30'
|
||||
source TEXT NOT NULL DEFAULT 'ths', -- ths / eastmoney
|
||||
up_ratio REAL, -- 上涨板块占比(%)
|
||||
mood TEXT, -- bullish / neutral / bearish
|
||||
created_at TEXT DEFAULT (datetime('now','localtime'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_snapshots_time ON market_snapshots(timestamp);
|
||||
|
||||
-- 每个板块在每次采集中的快照数据
|
||||
CREATE TABLE sector_snapshots (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
snapshot_id INTEGER NOT NULL REFERENCES market_snapshots(id),
|
||||
name TEXT NOT NULL, -- 板块名称(同花顺行业名)
|
||||
change_pct REAL, -- 涨跌幅(%)
|
||||
up_count INTEGER, -- 上涨家数
|
||||
down_count INTEGER, -- 下跌家数
|
||||
net_inflow REAL, -- 资金净流入(亿)
|
||||
lead_stock TEXT, -- 领涨股名
|
||||
lead_stock_change REAL, -- 领涨股涨跌幅(%)
|
||||
volume REAL, -- 成交量(万手)
|
||||
turnover REAL -- 成交额(亿)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sector_name ON sector_snapshots(name);
|
||||
CREATE INDEX idx_sector_snapshot ON sector_snapshots(snapshot_id);
|
||||
CREATE INDEX idx_sector_name_time ON sector_snapshots(name, snapshot_id);
|
||||
```
|
||||
|
||||
**典型查询:**
|
||||
```sql
|
||||
-- 半导体板块最近5天的涨跌幅趋势
|
||||
SELECT s.timestamp, ss.change_pct, ss.net_inflow
|
||||
FROM sector_snapshots ss
|
||||
JOIN market_snapshots s ON ss.snapshot_id = s.id
|
||||
WHERE ss.name = '半导体'
|
||||
ORDER BY s.timestamp DESC LIMIT 10;
|
||||
|
||||
-- 资金连续3天净流入的板块(最近3次采集)
|
||||
SELECT name, COUNT(*) as times, AVG(net_inflow) as avg_inflow
|
||||
FROM sector_snapshots ss
|
||||
JOIN market_snapshots s ON ss.snapshot_id = s.id
|
||||
WHERE s.timestamp >= date('now', '-3 days')
|
||||
AND net_inflow > 0
|
||||
GROUP BY name
|
||||
HAVING COUNT(*) >= 3
|
||||
ORDER BY avg_inflow DESC;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.2 个股K线 + 基本面
|
||||
|
||||
替代现有的 multi_tf_cache.json 和 data/stocks/*.json。
|
||||
|
||||
```sql
|
||||
CREATE TABLE stocks (
|
||||
code TEXT PRIMARY KEY, -- '688981'
|
||||
name TEXT NOT NULL, -- '中芯国际'
|
||||
exchange TEXT DEFAULT 'SH', -- SH / SZ / HK
|
||||
type TEXT DEFAULT 'A', -- A / H
|
||||
updated_at TEXT
|
||||
);
|
||||
|
||||
-- 日线数据(时间序列)
|
||||
CREATE TABLE stock_daily (
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
date TEXT NOT NULL, -- '2026-06-19'
|
||||
open REAL,
|
||||
close REAL,
|
||||
high REAL,
|
||||
low REAL,
|
||||
volume REAL, -- 成交量
|
||||
amount REAL, -- 成交额
|
||||
PRIMARY KEY (code, date)
|
||||
);
|
||||
|
||||
-- 周线数据
|
||||
CREATE TABLE stock_weekly (
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
date TEXT NOT NULL, -- 周结束日期
|
||||
open REAL, close REAL, high REAL, low REAL,
|
||||
volume REAL,
|
||||
PRIMARY KEY (code, date)
|
||||
);
|
||||
|
||||
-- 月线数据
|
||||
CREATE TABLE stock_monthly (
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
date TEXT NOT NULL, -- 月结束日期
|
||||
open REAL, close REAL, high REAL, low REAL,
|
||||
volume REAL,
|
||||
PRIMARY KEY (code, date)
|
||||
);
|
||||
|
||||
-- 基本面(最新,非时序)
|
||||
CREATE TABLE stock_fundamentals (
|
||||
code TEXT PRIMARY KEY REFERENCES stocks(code),
|
||||
pe REAL, -- 市盈率
|
||||
pb REAL, -- 市净率
|
||||
eps REAL, -- 每股收益
|
||||
mcap_total REAL, -- 总市值
|
||||
mcap_flow REAL, -- 流通市值
|
||||
updated_at TEXT
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.3 板块成分股映射
|
||||
|
||||
个股和板块的关系表。目前股票不知道自己在哪个板块,板块不知道有哪些成分股。这使 join 分析无法进行。
|
||||
|
||||
```sql
|
||||
CREATE TABLE stock_sectors (
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
sector_name TEXT NOT NULL, -- 板块名称(与 sector_snapshots.name 一致)
|
||||
source TEXT DEFAULT 'ths', -- 数据来源
|
||||
updated_at TEXT DEFAULT (datetime('now','localtime')),
|
||||
PRIMARY KEY (code, sector_name)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_stock_sector ON stock_sectors(sector_name);
|
||||
```
|
||||
|
||||
**典型查询:**
|
||||
```sql
|
||||
-- 我的持仓股所在的板块今天表现如何
|
||||
SELECT h.code, h.name, ss.change_pct, ss.net_inflow
|
||||
FROM holdings h
|
||||
JOIN stock_sectors ss_map ON h.code = ss_map.code
|
||||
JOIN sector_snapshots ss ON ss_map.sector_name = ss.name
|
||||
JOIN market_snapshots ms ON ss.snapshot_id = ms.id
|
||||
WHERE ms.timestamp = (SELECT MAX(timestamp) FROM market_snapshots)
|
||||
ORDER BY ss.change_pct DESC;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.4 持仓
|
||||
|
||||
```sql
|
||||
CREATE TABLE holdings (
|
||||
code TEXT PRIMARY KEY REFERENCES stocks(code),
|
||||
name TEXT NOT NULL,
|
||||
shares INTEGER NOT NULL, -- 持股数
|
||||
cost REAL, -- 成本价
|
||||
position_pct REAL, -- 仓位占比(%)
|
||||
added_at TEXT, -- 买入时间
|
||||
is_active INTEGER DEFAULT 1, -- 1=持仓中, 0=已卖出
|
||||
closed_at TEXT, -- 卖出时间
|
||||
close_pnl REAL -- 最终盈亏(%)
|
||||
);
|
||||
|
||||
-- 持仓策略参数(可重评,保留历史)
|
||||
CREATE TABLE holding_strategies (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
code TEXT NOT NULL REFERENCES holdings(code),
|
||||
version INTEGER DEFAULT 1, -- 策略版本号
|
||||
stop_loss REAL, -- 止损价
|
||||
take_profit REAL, -- 止盈价
|
||||
entry_low REAL, -- 买入区下沿
|
||||
entry_high REAL, -- 买入区上沿
|
||||
strategy_type TEXT DEFAULT 'holding', -- holding / watch
|
||||
source TEXT, -- reassess / manual / initial
|
||||
reason TEXT, -- 策略理由
|
||||
created_at TEXT DEFAULT (datetime('now','localtime')),
|
||||
superseded_at TEXT -- 被新版本替代的时间
|
||||
);
|
||||
|
||||
CREATE INDEX idx_strategy_code ON holding_strategies(code);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.5 自选股
|
||||
|
||||
```sql
|
||||
CREATE TABLE watchlist_stocks (
|
||||
code TEXT PRIMARY KEY REFERENCES stocks(code),
|
||||
name TEXT NOT NULL,
|
||||
added_at TEXT DEFAULT (datetime('now','localtime')),
|
||||
is_active INTEGER DEFAULT 1
|
||||
);
|
||||
|
||||
-- 自选股买入区策略(关联到 holding_strategies,共用策略表)
|
||||
```
|
||||
|
||||
说明:自选股的买入区策略直接使用 `holding_strategies` 表(`strategy_type='watch'`),不需要单独建表。
|
||||
|
||||
---
|
||||
|
||||
### 2.6 候选池
|
||||
|
||||
```sql
|
||||
CREATE TABLE candidates (
|
||||
code TEXT PRIMARY KEY REFERENCES stocks(code),
|
||||
name TEXT NOT NULL,
|
||||
sector TEXT, -- 所属板块
|
||||
reason TEXT, -- 推荐理由
|
||||
entry_range TEXT, -- '49.00-52.00'
|
||||
stop_loss REAL,
|
||||
target REAL,
|
||||
zhiwei_star REAL, -- 知微星级 5.0/4.5/4.0/3.5/3.0
|
||||
zhiwei_reviewed INTEGER DEFAULT 0,
|
||||
zhiwei_reviewed_at TEXT,
|
||||
promoted INTEGER DEFAULT 0, -- 是否已向老爸推荐过
|
||||
promoted_at TEXT,
|
||||
dropped INTEGER DEFAULT 0,
|
||||
drop_reason TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now','localtime'))
|
||||
);
|
||||
|
||||
-- 评分历史(每次小果/知微评分的记录)
|
||||
CREATE TABLE candidate_score_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
code TEXT NOT NULL REFERENCES candidates(code),
|
||||
score REAL NOT NULL, -- 评分 1-10
|
||||
source TEXT NOT NULL, -- xiaoguo / zhiwei
|
||||
reason TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now','localtime'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_candidate_history ON candidate_score_history(code, created_at);
|
||||
```
|
||||
|
||||
**典型查询:**
|
||||
```sql
|
||||
-- 候选池状态(活跃候选及其最新评分)
|
||||
SELECT c.code, c.name, c.sector, c.zhiwei_star, c.promoted,
|
||||
(SELECT score FROM candidate_score_history
|
||||
WHERE code = c.code ORDER BY created_at DESC LIMIT 1) as latest_score
|
||||
FROM candidates c
|
||||
WHERE c.dropped = 0
|
||||
ORDER BY c.zhiwei_star DESC NULLS LAST;
|
||||
|
||||
-- 某候选的评分趋势
|
||||
SELECT created_at, score, source
|
||||
FROM candidate_score_history
|
||||
WHERE code = '688981'
|
||||
ORDER BY created_at;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.7 价格事件
|
||||
|
||||
```sql
|
||||
CREATE TABLE price_events (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
name TEXT,
|
||||
event_type TEXT NOT NULL, -- entry_zone / stop_breach / take_profit / zone_warning
|
||||
price REAL, -- 触发时价格
|
||||
trigger_value TEXT, -- '15.36-16.49' 区间描述
|
||||
event_label TEXT, -- '买入区' / '止损预警'
|
||||
created_at TEXT DEFAULT (datetime('now','localtime')),
|
||||
date TEXT -- 触发日期
|
||||
);
|
||||
|
||||
CREATE INDEX idx_events_code ON price_events(code);
|
||||
CREATE INDEX idx_events_date ON price_events(date);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.8 策略评估记录
|
||||
|
||||
```sql
|
||||
CREATE TABLE strategy_evaluations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
code TEXT NOT NULL REFERENCES stocks(code),
|
||||
eval_type TEXT NOT NULL, -- daily / weekly / adhoc
|
||||
status TEXT DEFAULT 'pending', -- pending / completed / error
|
||||
old_stop_loss REAL,
|
||||
new_stop_loss REAL,
|
||||
old_tp REAL,
|
||||
new_tp REAL,
|
||||
reason TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now','localtime'))
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、与现有系统的关系
|
||||
|
||||
### 3.1 分步迁移计划
|
||||
|
||||
```
|
||||
阶段1:新库就位
|
||||
→ 创建 mofin.db + 所有表
|
||||
→ market_watch.py 改:写 market.json(保留兼容)+ 同时写 market_snapshots / sector_snapshots
|
||||
→ 验证:数据正常双写,旧管道不受影响
|
||||
|
||||
阶段2:个股数据迁移
|
||||
→ refresh_mtf_cache.py 改:写 multi_tf_cache.json + 同时写 stock_daily/weekly/monthly
|
||||
→ 新增 stock_sectors 填充(从 market.json 的板块数据提取成分股)
|
||||
→ 验证:K线数据在SQLite可查
|
||||
|
||||
阶段3:业务表迁移
|
||||
→ portfolio / watchlist / candidate_pool 逐步迁移
|
||||
→ 每个模块:先写JSON+SQLite双写,确认无问题后切到SQLite
|
||||
→ 淘汰对应JSON文件
|
||||
|
||||
阶段4:no_agent 化
|
||||
→ 通用查询脚本:mofin_query.py "SELECT ..." → 输出JSON/TEXT
|
||||
→ 定时报表:纯SQL生成,无需LLM
|
||||
→ 预警规则:SQL条件 → 推送通知
|
||||
```
|
||||
|
||||
### 3.2 JSON 文件保留策略
|
||||
|
||||
| 文件 | 阶段1 | 阶段2 | 阶段3 | 阶段4 |
|
||||
|------|-------|-------|-------|-------|
|
||||
| market.json | ✅ 双写 | ✅ 双写 | ❌ 淘汰 | — |
|
||||
| multi_tf_cache.json | — | ✅ 双写 | ❌ 淘汰 | — |
|
||||
| portfolio.json | — | — | ✅ 双写 | ❌ 淘汰 |
|
||||
| watchlist.json | — | — | ✅ 双写 | ❌ 淘汰 |
|
||||
| candidate_pool.json | — | — | ✅ 双写 | ❌ 淘汰 |
|
||||
| price_events.json | — | — | ✅ 双写 | ❌ 淘汰 |
|
||||
| decisions.json | — | — | ⚠️ 按需迁移 | — |
|
||||
|
||||
---
|
||||
|
||||
## 四、关键关联路径
|
||||
|
||||
以下是最有价值的跨表查询链:
|
||||
|
||||
```
|
||||
持仓股 → stock_sectors(查所属板块)→ sector_snapshots(板块最近表现)
|
||||
↓
|
||||
sector_snapshots 历史(板块趋势)
|
||||
↓
|
||||
stock_daily(个股K线与板块对比)
|
||||
↓
|
||||
candidate_score_history(候选评分变化)
|
||||
|
||||
事件触发 → stock_daily(看当日量价)→ holding_strategies(检查策略偏离)
|
||||
↓
|
||||
strategy_evaluations(策略重评记录)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、迁移风险控制
|
||||
|
||||
- 每条写操作先写 JSON(现有流程不受影响),再写 SQLite
|
||||
- SQLite 写失败时降级报警,不阻塞 JSON 写
|
||||
- 全部验证通过后才切掉 JSON
|
||||
- 所有变更通过 market_watch.py / refresh_mtf_cache.py 的 patch 实现,不重写
|
||||
@@ -0,0 +1,87 @@
|
||||
# MoFin 数据管道重构需求 — 给笑笑的接手说明
|
||||
|
||||
## 一句话
|
||||
|
||||
把 decisions.json + portfolio.json + watchlist.json 三个文件合并到 mofin.db,建成一个统一的数据核心。
|
||||
|
||||
## 为什么必须重构(现有 6 个问题)
|
||||
|
||||
### 1. 价格币种混存
|
||||
- `decisions.json` 的港股价格字段(price/stop_loss/take_profit/entry)存的是 **HKD 原值**
|
||||
- `portfolio.json` 的港股字段存的是 **CNY 折算值(×0.87)**
|
||||
- 所有分析脚本读完这个文件去比较另一个文件,币种不同 → 判断全错
|
||||
- 建滔积层板(01888)被误报止损触发 6+ 次,每次都是币种错配
|
||||
|
||||
### 2. 价格有多个入口,互不通信
|
||||
- `price_monitor.py` 每 2 分钟拉一次 Tencent API,写 `portfolio.json`
|
||||
- `per_stock_reassess.py` 自拉 Tencent API(可能加 ×0.87 转换),写 `decisions.json`
|
||||
- `stale_push_wlin.py` 自拉 Tencent API,自己做比较
|
||||
- 三个脚本各自拉价,各自写不同文件,相互覆盖,没有排它锁
|
||||
|
||||
### 3. 现金无系统化更新
|
||||
- 每次 Dad 买/卖后,现金数字靠他截图 → 人工解析 → 手动改 `portfolio.json`
|
||||
- 截图里的「冻结资金(T+2 未交收)」从来没被正确计入
|
||||
- 没有 changelog,改了不知道改之前是多少
|
||||
|
||||
### 4. 总资产计算不一致
|
||||
- 每个报告自己算:持仓市值(来自 portfolio.json 的多日前的价格)× 手数 + 现金
|
||||
- 结果:同一天出现 85 万 / 92 万 / 95 万 / 100 万 四个不同数字
|
||||
- 只应该有一个总资产字段随 price_monitor 实时价刷新
|
||||
|
||||
### 5. 没有唯一数据源
|
||||
- price_monitor 是最可信的价格源(每 2 分钟 Tencent API)
|
||||
- 但报告脚本(stale_detector / stale_push_wlin)经常自己直接拉 API 获取价格
|
||||
- 价格判断没有强制经过同一个入口
|
||||
|
||||
### 6. 策略和持仓分离在两个文件
|
||||
- `decisions.json`:策略(止损/止盈/买入区/RR/timing_signal),52 条
|
||||
- `portfolio.json`:持仓(股数/成本/现价/市值),19 持仓 + 现金
|
||||
- `watchlist.json`:自选股,19 条,但和 decisions 有重叠
|
||||
- 加一个策略要改三个文件,总是不同步
|
||||
|
||||
## 重构后的数据模型(建议)
|
||||
|
||||
```
|
||||
mofin.db 统一数据库
|
||||
├── holdings — 当前持仓(股数/成本/市价CNY/HKD/成本CNY/HKD)
|
||||
├── strategies — 所有策略(止损/止盈/买入区/RR/信号)
|
||||
│ 包含 currency: HKD/CNY 标记
|
||||
├── watchlist — 自选股列表(关联 strategies.id)
|
||||
├── cash_log — 现金变更记录(含冻结资金)
|
||||
├── price_cache — price_monitor 推入的最新价格
|
||||
└── total_assets — 唯一的总资产字段(每 2 分钟更新)
|
||||
```
|
||||
|
||||
## 现有文件清单(全部要合并或废除)
|
||||
|
||||
| 文件 | 大小 | 用途 | 去向 |
|
||||
|------|------|------|------|
|
||||
| data/decisions.json | 52条 | 策略+持仓分析 | → strategies 表 |
|
||||
| data/portfolio.json | 19持仓 | 持仓+现金+总资产 | → holdings + cash_log + total_assets |
|
||||
| data/watchlist.json | 19自选 | 自选列表 | → watchlist 表 |
|
||||
| data/mofin.db | (已有) | 市场数据+新闻+信号 | 不动,只加新表 |
|
||||
| data/multi_tf_cache.json | 1000+K线 | 多周期K线缓存 | 不动 |
|
||||
| data/live_prices.json | (无) | 计划中的统一价格缓存 | 如果做 → price_cache 表 |
|
||||
|
||||
## 不重构的痛苦指数
|
||||
|
||||
当前每个报告生成前要走的手动校验链(Dad 每 2~3 次报告就会发现一次严重数据错误):
|
||||
|
||||
1. 检查 decisions.json vs portfolio.json 价格是否一致 ← 经常不一致
|
||||
2. 检查港股价格是不是 HKD ← 可能被脚本误转 CNY
|
||||
3. 确认现金数字更新了 ← 可能还用昨天的
|
||||
4. 手动算总资产 ← 和报告不同就出问题
|
||||
|
||||
Dad 原话(2026-06-30):「我说怎么办?定一个靠谱的自检策略出来。」
|
||||
但自检策略只能发现错误,不能消除错误。根因是数据管道。
|
||||
|
||||
## 零乱改修复(如果不重构)
|
||||
|
||||
如果不做 DB 化重构,至少必须改这 4 处代码才能让系统稳定运行:
|
||||
|
||||
1. `price_monitor` 写 decisions.json 时同步所有文件的价格
|
||||
2. `per_stock_reassess` 写 decisions.json 时通知 price_monitor 刷新
|
||||
3. 现金变更从截图解析后强制写 changelog
|
||||
4. 所有 LLM cron prompt 加「价格以 XX 文件为准,币种看 currency 字段」
|
||||
|
||||
这些只是补丁,不是根治。数据结构不改,所有补丁最终都会引入新的一致性故障。
|
||||
@@ -0,0 +1,58 @@
|
||||
# MoFin 自愈循环系统设计
|
||||
|
||||
> 版本: v1.1 | 最后更新: 2026-06-24
|
||||
> 核心理念:三层自检 + TODO自动执行 + 失败升级LLM,形成无人值守的修复闭环。
|
||||
|
||||
## 一、三层自检架构
|
||||
|
||||
| 层级 | 脚本 | 频率 | 范围 |
|
||||
|------|------|------|------|
|
||||
| 盘中高频 | intraday_health_check.py | 每15分 9-15 | XMPP/Gateway/Scanner/价格/信号管道 |
|
||||
| 每日早检 | morning_health_check.py | 8:00 | 8类48项:基础设施/SENSE/RESPOND/ADAPT/IMPROVE/数据/管道/元自检 |
|
||||
| 每周深度 | 策略评估/建议对账/剪枝 | 周六 | 策略准确率/闭环/分支效率 |
|
||||
|
||||
## 二、自愈循环
|
||||
|
||||
```
|
||||
自检发现问题
|
||||
├─ auto_fix_issue() 当场能修 → 修完标记✅
|
||||
└─ 不能当场修 → 写TODO(带fix_action+原因)
|
||||
│
|
||||
self_todo_executor.py (每10分, no_agent)
|
||||
│
|
||||
┌─────┴──────┐
|
||||
│ │
|
||||
fix_action成功 fix_action失败
|
||||
│ │
|
||||
completed ✅ 调gateway API(localhost:8643)
|
||||
带完整上下文(问题+详情+失败原因)
|
||||
│
|
||||
知微(LLM)处理 → completed
|
||||
仍搞不定 → 在结果里说明
|
||||
```
|
||||
|
||||
## 三、核心文件
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `scripts/morning_health_check.py` | 每日早检(no_agent, 8:00) |
|
||||
| `scripts/intraday_health_check.py` | 盘中高频(no_agent, 每15分) |
|
||||
| `scripts/self_todo_executor.py` | TODO执行器(no_agent, 每10分) |
|
||||
| `scripts/xiaoguo_signal_consumer.py` | 小果信号消费(no_agent, 每30分) |
|
||||
| `data/health_checklist.json` | 检查清单(可自动扩展) |
|
||||
| `data/mofin.db → todos 表` | TODO数据库(替代旧todo.json) |
|
||||
|
||||
## 四、TODO生命周期
|
||||
|
||||
```
|
||||
创建(自检发现)→pending→in_progress→completed(修复成功)
|
||||
→pending(重试未到上限)
|
||||
→needs_llm→调gateway→completed
|
||||
→报告说明(LLM也搞不定)
|
||||
```
|
||||
|
||||
## 五、Fallback设计
|
||||
|
||||
- 小果LLM不可达 → scanner降级标记unknown,继续扫榜单搜新闻
|
||||
- 小果离线 → 盘中自检不报严重错误,核心功能不受影响
|
||||
- 任何fix_action失败 → 调gateway API让知微处理,不搁置
|
||||
@@ -0,0 +1,45 @@
|
||||
# Session 交接文档: 2026-06-29 → 06-30 MoFin 架构改革
|
||||
|
||||
> 执行人: 小小莫(架构改革) + 知微(自愈体系) | 详见 CHANGELOG.md
|
||||
|
||||
## 一、小小莫 — 架构改革
|
||||
|
||||
| 改动 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| 统一数据模型 | `mo_models.py` 新增 | total_assets/is_hk_stock/hk_rate 唯一入口,6个文件各自计算→收敛至此 |
|
||||
| DSA 数据源 | `mo_provider.py` 新增 | 包装 daily_stock_analysis 16 Fetcher,TDX优先→DSA自动fallback |
|
||||
| 配置单例 | `mo_config.py` 新增 | 替代10+文件中的硬编码路径 |
|
||||
| DSA 集成桥 | `mo_bridge.py` 新增 | 大盘复盘/新闻注入 MoFin 分析prompt |
|
||||
| 港股实时行情 | `price_monitor.py` 修改 | 从腾讯gtimg(15分钟延迟)切到东方财富push2(实时,免费),腾讯作fallback |
|
||||
| 总资产修正 | 6个文件修改 | frozen_cash 遗漏修复,实盘验证零误差 967712.85 |
|
||||
| 小果连接 | `mo_config.py` `/etc/hosts` | node122 = 192.168.1.122(LAN) / 10.144.144.2(EasyTier),不再硬编码IP |
|
||||
| market_watch/screener | cron 启用 | 交易日每30分钟跑(此前从未进过cron) |
|
||||
| DSA 服务 | `/home/hmo/daily-stock-analysis/` | Web UI http://192.168.1.246:8001,FastAPI + Swagger |
|
||||
|
||||
## 二、知微 — 自愈体系
|
||||
|
||||
| 组件 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| 每日早检 | `morning_health_check.py` 8:00 | 8类49项,自动修复+写TODO+管道注册表审计 |
|
||||
| 盘中自检 | `intraday_health_check.py` 每15分 | XMPP/Gateway/价格/信号/宏观风险 |
|
||||
| 自愈执行器 | `self_todo_executor.py` 每10分 | 执行TODO→失败调gateway升级LLM |
|
||||
| 策略复盘 | `strategy_review.py` 每日20:00 | 三层评估(信号/执行/综合),写accuracy_stats |
|
||||
| 数据治理 | `data_governance.py` 每周六 | holding_strategies归档+缺失策略检查 |
|
||||
| 记忆守卫 | `memory_guardian.py` 每日7:00 | 你已升级为LLM分类版,双profile自适应 |
|
||||
| 管道注册表 | `data/pipeline_registry.json` | 所有数据流登记+自动发现+体检审计 |
|
||||
|
||||
## 三、代码同步
|
||||
|
||||
MoFin ↔ profile 全部6个核心脚本一致:
|
||||
- `strategy_lifecycle.py` → mo_models集成
|
||||
- `price_monitor.py` → 东财港股实时+mo_models
|
||||
- `stale_push_wlin.py` → mo_models+统一HK rate
|
||||
- `stock_scorer.py` → mo_models.is_hk_stock
|
||||
- `xiaoguo_scanner.py` → node122地址
|
||||
- `xiaoguo_signal_consumer.py` → mo_models
|
||||
|
||||
## 四、待办
|
||||
|
||||
- `pipeline_registry.json` 中 verified=false 的条目需要确认数据流推断
|
||||
- 莫荷的 price_monitor 已禁用(缺HK汇率转换,与知微写同一portfolio.json冲突)
|
||||
- XMPP bot session: `xmpp-zhiwei-v2`,含完整对话历史
|
||||
@@ -0,0 +1,110 @@
|
||||
# 策略评估系统 — 需求文档
|
||||
|
||||
> 版本: v1.0 | 最后更新: 2026-06-18 | 状态: 生效
|
||||
> 来源: 老爸直接口述批注,最高优先级需求文档
|
||||
|
||||
---
|
||||
|
||||
## 一、评估的范围(管谁)
|
||||
|
||||
所有持仓股(position > 0 的)和所有自选股。每次评估全覆盖,不遗漏。
|
||||
A股和港股分开处理。
|
||||
|
||||
---
|
||||
|
||||
## 二、评估的频率和触发方式
|
||||
|
||||
三种触发方式:
|
||||
|
||||
1. **每日收盘后推送一次全面评估** — 21:00 定时,走 XMPP 推送
|
||||
2. **盘中异动触发** — 涨跌 >±5%、成交突然放大、有突发新闻
|
||||
3. **老爸主动问的时候** — 拉实时数据出六维评估
|
||||
|
||||
---
|
||||
|
||||
## 三、每个股票要评估的六个维度
|
||||
|
||||
### 维度1 — 宏观环境
|
||||
|
||||
大盘当天涨跌:
|
||||
- A股:上证指数 + 深证成指 + 富时A50
|
||||
- 港股:恒生指数 + 恒生科技指数
|
||||
|
||||
输出:当前是普涨还是普跌,系统性风险信号(有/无/一般)。
|
||||
|
||||
### 维度2 — 行业表现
|
||||
|
||||
- 该股所属行业当天涨跌幅
|
||||
- 相对大盘的强弱(跑赢/跑输/同步)
|
||||
- 行业内的横向对比(同行业其他自选股表现如何)
|
||||
|
||||
### 维度3 — 技术面(当前,不是历史快照)
|
||||
|
||||
- 当前支撑位和压力位(基于近期K线和今日数据)
|
||||
- K线形态
|
||||
- 量价关系
|
||||
- 趋势判断(向上/向下/震荡)
|
||||
|
||||
### 维度4 — 基本面
|
||||
|
||||
- PE、PB(如果能拿到)
|
||||
- 估值高低判断
|
||||
- 股价相比历史区间的位置
|
||||
|
||||
### 维度5 — 消息面
|
||||
|
||||
- 公司公告、业绩预警、行业政策变化、市场传闻
|
||||
- 上网搜索最近3天有无相关新闻
|
||||
|
||||
### 维度6 — 资金面
|
||||
|
||||
- 成交额和换手率
|
||||
- 当日资金流向(主动买入 vs 主动卖出)
|
||||
|
||||
---
|
||||
|
||||
## 四、策略评估逻辑(三个阶段的递进判断)
|
||||
|
||||
### 阶段一:原有策略是否正确
|
||||
|
||||
当初给的买入区、止损价、止盈价,股价是否到过这些价位?到了之后往哪个方向走了?
|
||||
如果策略是错的,错在哪里?
|
||||
|
||||
### 阶段二:当前是否还安全
|
||||
|
||||
止损价有没有被跌破的可能性?止盈价是否还合理?需要调整吗?
|
||||
|
||||
### 阶段三:现在该怎么做
|
||||
|
||||
**基于阶段一和阶段二的结论,确认当前的止损和止盈价格,并描述理由。**
|
||||
基于现价、R/R、持仓成本,给出确定的操作建议(加仓/减仓/持有/止损/调价)。
|
||||
不做选择题,只给唯一确定建议。
|
||||
|
||||
---
|
||||
|
||||
## 五、输出的呈现规则
|
||||
|
||||
- 优先排序:有紧急信号的放最前面,不用动的放最后
|
||||
- 每只股票最多6行六维概要,不限篇幅但信息要精炼
|
||||
- 必带具体价格(买入/卖出/止损/止盈都带数字)
|
||||
- 不允许"可关注""可考虑""择机"这类模糊词
|
||||
- 整个报告800字左右,快速评估版不超过500字
|
||||
- **所有股票都要给理由,不只是深套股**
|
||||
|
||||
---
|
||||
|
||||
## 六、与其他系统的关系
|
||||
|
||||
- 推送走 XMPP
|
||||
- 数据来源:腾讯行情API / 网络搜索(消息面)
|
||||
- 不依赖钉钉
|
||||
- daily cron 21:00 跑完整评估
|
||||
- 评估结果写入 decisions.json(评估记录持久化)
|
||||
|
||||
---
|
||||
|
||||
## 七、变更记录
|
||||
|
||||
| 日期 | 版本 | 变更内容 | 批准人 |
|
||||
|------|------|----------|--------|
|
||||
| 2026-06-18 | v1.0 | 初版,老爸口述批注整理 | 老爸 |
|
||||
Reference in New Issue
Block a user