# 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 做）
