Files
MoFin/docs/portfolio-data-model.md
T

115 lines
3.3 KiB
Markdown
Raw 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 数据模型
> 数据已从 JSON 迁移到 SQLite。portfolio.json / decisions.json / watchlist.json 不再使用。
## 核心表
| 表 | 对应旧 JSON | 用途 |
|----|-----------|------|
| `holdings` + `portfolio_summary` | portfolio.json | 持仓 + 汇总 |
| `holding_strategies` | decisions.json | 策略/决策 |
| `watchlist_stocks` | watchlist.json | 自选股 |
| `live_prices` | live_prices.json | 实时价格快照 |
| `mtf_cache` | multi_tf_cache.json | 多周期缓存 |
| `market_snapshots` | market.json | 大盘数据 |
| `capital_flow_cache` | capital_flow_cache.json | 资金流缓存 |
| `cash_log` | 无 | 现金变更日志 |
## 总资产公式
**总资产 = 持仓总市值(CNY) + 可用现金 + 冻结资金**
`calc_total_assets()` (mo_models.py) 是唯一正确公式。
## 币种
### 个股层面
| 品种 | price | cost | currency | 说明 |
|------|-------|------|----------|------|
| 港股 | **HKD** | **HKD** | `HKD` | 跟股软显示一致,方便操作 |
| A股 | **CNY** | **CNY** | `CNY` | |
技术位(stop_loss / take_profit / entry_low / entry_high)与 price 同币种。
### 汇总层面
`calc_total_mv()` / `calc_total_assets()` 汇总时自动将港股 HKD × `HK_RATE`(实时 API)转为 CNY。
```python
# 个股 P&L:港股用 HKD 算,A股用 CNY 算
profit_pct = (price - cost) / cost * 100 # 同币种,无需转换
# 总资产:港股市值自动转 CNY
total_assets = calc_total_assets(pf) # 已处理 HKD→CNY
```
### 禁止
- ❌ 港股 price(HKD) 和 A 股 price(CNY) 直接比较/相加
- ❌ 港股 cost(HKD) 和 CNY price 混算 P&L
- ❌ 硬编码汇率(`calc_total_mv` 内部调 `get_hk_rate()` 走实时 API
## 数据流
```
price_monitor (cron: */2 9-16)
→ 东财/腾讯拉价格
→ write_holdings_batch() → holdings 表 (price 更新)
→ write_portfolio_summary() → portfolio_summary (total_mv/total_assets 重算)
regenerate_all (cron: 手动/定时)
→ batch_fetch_prices() → 从 DB 读价格
→ 技术分析 → 止损/止盈/买入区
→ write_holding_strategy() → holding_strategies 表
server.py API
→ 写端点: _save_portfolio / _save_decision / _save_watchlist → DB
→ 读端点: mo_data.read_*() → DB
```
## 现金
- `price_monitor` 只更新价格和汇总,不动现金
- 现金变更通过截图导入 / holding.xls 导入 / 手动调整
- `cash_log` 表记录每次变更(来源、before/after、备注)
## 常见错误
### ❌ 港股价格转 CNY 再存
```python
# WRONG — 港股个股存 CNY 后股软对不上
if is_hk_stock(code):
price = price * HK_RATE
# RIGHT — 存 HKD 原值,汇总时由 calc_total_assets 转 CNY
if is_hk_stock(code):
currency = 'HKD'
```
### ❌ 混币计算
```python
# WRONG — price 是 HKDcost 是 CNY,算出来没意义
pnl = (price_hkd - cost_cny) / cost_cny
# RIGHT — 同币种比较
pnl = (price_hkd - cost_hkd) / cost_hkd
```
### ❌ 硬编码汇率
```python
# WRONG
mv = shares * price * 0.87
# RIGHT — 用 calc_total_assets(内部调实时汇率)
mv = calc_total_mv(holdings)
```
## 版本
| 版本 | 日期 | 变更 |
|------|------|------|
| 3 | 2026-07-03 | JSON→DB 迁移完成。港股个股存 HKD,汇总时转 CNY。 |
| 2 | 2026-06-29 | 明确 cash/frozen_cash 字段含义 |
| 1 | - | 无规范 |