Files
MoFin/docs/decisions-db-migration.md
T

160 lines
6.4 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.
# decisions.json → SQLite 数据库迁移需求
## 背景
当前系统所有策略数据存在 `/home/hmo/web-dashboard/data/decisions.json`,一个约 50~60 条策略的 JSON 文件。
## 现状痛点
| 问题 | 举例 |
|------|------|
| 没有写入锁,并发写会损坏 | price_monitor + per_stock_reassess 同时写,JSON 截断 |
| 币种字段不统一 | 港股 price 曾经存 HKD 也存过 CNY,修了几轮才用 currency 标记 |
| 缺乏 schema 校验 | 空字段、类型错误(str 写成了 int)无声失败 |
| 无 changelog 审计 | 谁在什么时候改了哪个字段,查不了 |
| 没有事务回滚 | 写一半 crash,整个文件废了 |
| 只能全量读 | 50 条策略每次全部加载,浪费 token |
| 各脚本自拉价格 | stale_detector 拉一次腾讯 APIper_stock_reassess 又拉一次 |
## 需求目标
**单线程写入 / 多线程安全读**
将 decisions.json 迁移到 `mofin.db`(已有该数据库),建 `strategies` 表。
## 表结构
```sql
CREATE TABLE strategies (
code TEXT PRIMARY KEY, -- 股票代码,如 "00700"
name TEXT NOT NULL, -- 股票名称
type TEXT DEFAULT '自选策略', -- 持仓策略 / 自选策略
status TEXT DEFAULT 'active', -- active / updated / stale
currency TEXT DEFAULT 'CNY', -- CNY / HKD。港股固定 HKD
-- 价格与仓位
price REAL, -- 最新价格(原始币种,港股=HKD,A股=CNY)
price_cny REAL, -- 折算为人民币的价格(统一口径用)
cost REAL, -- 持仓成本(有持仓时)
shares INTEGER, -- 持仓股数
share INTEGER, -- 同 shares,历史遗留字段
-- 策略参数
entry_low REAL, -- 买入区间下沿(原始币种)
entry_high REAL, -- 买入区间上沿(原始币种)
stop_loss REAL, -- 止损价
take_profit REAL, -- 止盈/目标价
stop_loss_cny REAL, -- 止损(人民币,统一口径用)
take_profit_cny REAL, -- 止盈(人民币)
rr_ratio REAL, -- 盈亏比
timing_signal TEXT, -- 短词信号:买入/加仓/持有/观望/冷却中
-- 来源与状态
trigger_reason TEXT, -- 策略生成原由
created_at TEXT, -- ISO时间
updated_at TEXT, -- 最后更新时间
reassessed_at TEXT, -- 最近一次重评时间
action TEXT, -- 最新操作摘要文本
-- JSON 嵌套字段(存为 TEXT,应用层 JSON parse
analysis TEXT, -- JSON: 分析详情
trigger TEXT, -- JSON: 触发条件
changelog TEXT, -- JSON: 变更历史数组
signal_factors TEXT, -- JSON: 因子列表
tech_snapshot TEXT, -- JSON: 技术面快照
action_note TEXT, -- 长文本动作说明
sector_context TEXT -- 行业上下文
);
```
### 为什么不全部展开成列
analysis 和 trigger 有嵌套结构且未来可能加字段。存 JSON 字符串,应用层 parse。查询止损/止盈用 `json_extract()`
## 读写接口需求
### 写操作(高频,每 2 分钟)
price_monitor 每轮更新所有持仓 + 自选的价格:
```sql
INSERT INTO strategies (code, price, price_cny, currency, updated_at)
VALUES (?, ?, ?, ?, ?)
ON CONFLICT(code) DO UPDATE SET
price = excluded.price,
price_cny = excluded.price_cny,
updated_at = excluded.updated_at;
```
价格更新不涉及其他字段。港股:price=HKDprice_cny=HKD×汇率。
A股:price=price_cny。
### 写操作(低频,策略重评时)
per_stock_reassess 跑完单股重评后更新全部策略参数:
```sql
UPDATE strategies SET
entry_low = ?, entry_high = ?, stop_loss = ?,
take_profit = ?, rr_ratio = ?, timing_signal = ?,
stop_loss_cny = ?, take_profit_cny = ?,
currency = ?,
analysis = ?,
trigger = ?,
reassessed_at = ?,
changelog = json_insert(changelog, '$[#]', ?)
WHERE code = ?;
```
### 读操作(各报告脚本)
所有 LLM cron、no_agent 脚本统一从 `strategies` 表读,不再拉腾讯 API
```sql
SELECT * FROM strategies WHERE status = 'active' ORDER BY code;
```
按币种过滤:
```sql
SELECT * FROM strategies WHERE currency = 'HKD';
```
读某只具体股票:
```sql
SELECT * FROM strategies WHERE code = '00700';
```
## 不变的输出
1. **保留 decisions.json 同步输出**(过渡期 2 周)。每次写 DB 后,同步写一份 decisions.json 给旧脚本兼容。
2. **输出格式不做大改**。JSON decode analysis/trigger 后保持现有字段名。
## 不允许的行为
1. ❌ 各脚本自行拉腾讯 API 获取价格。价格入口只有 price_monitor。
2. ❌ 直接写 decisions.json。全部走 DB。
3. ❌ 变更 decisions.json 的输出字段名/格式(过渡期兼容)。
## 验收标准
1. `strategies` 表有数据,decisions.json 和 `SELECT * FROM strategies` 内容一致
2. price_monitor 跑一轮后 DB 里的 price 更新正确(港股 HKDA 股 CNY)
3. per_stock_reassess 跑完单股后 DB 里对应股票策略更新
4. stale_detector 从 DB 读数据,输出和从 JSON 读一样
5. 并发读写(price_monitor 2min + stale_detector 同时跑)不损坏数据
6. 迁移后旧 decisions.json 仍同步更新
## 相关文件路径
| 文件 | 说明 |
|------|------|
| `/home/hmo/MoFin/price_monitor.py` | 价格监控,每2分钟写price |
| `/home/hmo/MoFin/scripts/strategy_lifecycle.py` | 策略生命周期,reassess_strategy() |
| `/home/hmo/MoFin/scripts/per_stock_reassess.py` | 单股重评入口 |
| `/home/hmo/MoFin/scripts/stale_push_wlin.py` | 自选买入提醒 |
| `/home/hmo/web-dashboard/data/decisions.json` | 当前JSON文件 |
| `/home/hmo/MoFin/data/mofin.db` | 目标数据库(已有market/trend等表) |
## 联系人
有问题问 hmo(老爸)。笑笑负责代码实现,测试完成后通知老爸验收。