Files
MoFin/docs/data-pipeline-diagnosis.md
知微 e1057bc747 docs: 数据管道诊断报告(交笑笑重构参考)
涵盖:系统数据架构总图、港股币种不统一问题、
总资产计算路径问题、现金管理缺失问题、
建议重构方向(单一日志数据源、统一价格写入路径、
现金 changelog 系统、币种感知比较)、
当前文件清单和 TODO
2026-06-30 09:34:59 +08:00

181 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MoFin 系统数据管道诊断报告(2026-06-29 交笑笑重构参考)
## 一、当前数据架构总图
```
腾讯实时行情API (qt.gtimg.cn / ifzq.gtimg.cn)
price_monitor.py (每2分钟 cron)
├──→ 写 portfolio.jsonCNY 价 + 总市值 + 总资产 + 现金)
│ ├── holdings[].price = CNY(港股 × HK_RATE
│ ├── total_mv = 持仓市值CNY之和
│ ├── cash_available + cash_frozen = 现金CNY
│ └── total_assets = total_mv + cash
├──→ 写 watchlist.jsonCNY 价,同上规则)
├──→ 写 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 ❌ | 策略生成时就是HKDprice_monitor曾试图转CNY又回退了 |
| watchlist.json | CNY ✅ | CNY (×0.87) ✅ | price_monitor转的 |
**出错场景:**
- LLM cron 报告读 portfolio.jsonCNY)←→ 又读 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_cnyCNY折算值,做总资产用)
├──→ portfolio.json.total_mvCNY
└──→ 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.jsonholdings + 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 做)