Files
MoFin/docs/SELF_GROWTH_SYSTEM.md
知微 abd8d5c258 元自成长改为每日两次(12:45+00:45),半天内完成闭环
12:45: 上午盘发现问题→注入新规则→17:25审计就用新规则扫
00:45: 全天修复汇总→注册表更新→次日审计带新规则

Dad要求:用上午盘的发现提升下午盘,而不是等一周
2026-06-24 00:14:41 +08:00

368 lines
16 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-23
> 维护人:知微
> 原则:每增加一个系统机制,必须在此同步更新文档并签入 git
---
## 一、四层循环架构(Sense → Respond → Adapt → Improve
MoFin 不再是一个简单的价格监控 + 推送工具,而是一个**能够自我感知、自我决策、自我适应、自我成长**的循环系统。
```
┌──────────────────────────────────────┐
│ IMPROVE (自成长) │
│ 知识萃取 | 策略评估 | 分支剪枝 │
│ 硬编码审计 | 分析师复查 │
└────────────┬─────────────────────────┘
│ 每周/每日
┌────────────▼─────────────────────────┐
│ ADAPT (适应) │
│ 停损上移 | 仓位调整 | 分支触发记录 │
│ 情景切换 | 策略重评 | 缓存刷新 │
└────────────┬─────────────────────────┘
│ 盘中
┌────────────▼─────────────────────────┐
│ RESPOND (决策+推送) │
│ price_monitor→XMPP | 分支扫描→推荐 │
│ 开盘简报 | 收盘简报 | 自选买入提醒 │
└────────────┬─────────────────────────┘
│ 实时
┌────────────▼─────────────────────────┐
│ SENSE (感受) │
│ price_monitor | 宏观采集 | 小果扫描 │
│ 汇率刷新 | 趋势检测 | 多周期缓存 │
└──────────────────────────────────────┘
```
### 1.1 SENSE — 感受层
所有数据采集,不生成判断,只给数据。
| 组件 | 调度 | 输出 | 说明 |
|------|------|------|------|
| price_monitor.py | */2 9-16 交易日 | price_events.json, 分支触发 | 腾讯行情API,每2分钟扫全部持仓+自选 |
| macro_context_collector.py | 9:35, 12:00 交易日 | macro_context.json | A股大盘指数+情绪指标 |
| hk_rate.py | 每日首用刷新 | ~/.cache/hk_exchange_rate.json | HKD→CNY汇率,缓存24小时,API失效时用上次有效值 |
| xiaoguo_scanner.py | */5 9-15 交易日 | 热榜+新闻→数据库 | 独立扫描线(5分钟间隔),轮询东方财富/同花顺热度榜 |
| refresh_mtf_cache.py | 9:00 交易日 | MTF缓存 | 多周期均线/支撑阻力计算预热 |
| trend_detector | 每30分钟 | sector_signals | 板块资金异动/涨跌比反转(通过 market_watch 脚本) |
| stale_detector.py | 每日9:00 | strategy_staleness_report.json | 所有策略的价格偏离/过期检查 |
### 1.2 RESPOND — 决策+推送层
所有数据驱动判断,有触发才推送。
| 组件 | 调度 | 触发条件 | 推送目标 |
|------|------|---------|---------|
| price_monitor → 分支评估 | 每2分钟 | 价格触及买入区 ±1% | 私信(有触发才推) |
| price_monitor → 情景切换检测 | 每2分钟 | 情景ID变化 | 私信 |
| stale_push_wlin.py | 9:01, 9:31, ... 每30分 | 自选在买入区且RR≥1.5 | 私信(报推荐/重评) |
| branch_scanner.py | 9:15, 9:45 每30分 | 有分支操作推荐 | 私信 |
| 开盘简报 (LLM) | 9:35 | - | 私信 |
| 收盘简报 (LLM) | 16:10 | - | 私信 |
**推送必经链路:**
1. no_agent 脚本 → stdout → cron 调度器 → `deliver=local`
2. `deliver=local` 命中 `cron_to_xmpp.py` 管道→ XMPP bridge (5805) → 知微Bot → Dad 私信
3. LLM cron → 知微回复 → XMPP bridge → Dad 私信
### 1.3 ADAPT — 适应层
盘中触发的自动调整,不需要手动干预。
| 组件 | 调度 | 行为 |
|------|------|------|
| per_stock_reassess.py | 9:00, 12:00 | 所有自选重评 + 初始化分支树 |
| stale_push 在线重评 | 每30分钟检测到STALE时 | 串行等重评完再出报告 |
| 移动止损保护 | 持仓价跌破重评止损线时自动触发 | 停损线上移(不下移) |
| 分支触发记录 | 价格触发分支条件时 | trigger_count+1,记录在strategy_tree内 |
| 情景切换 | 价格监控每次扫描 | 比较当前情景与上次,变化则推送+重新排序分支 |
| MTF缓存刷新 | 9:00 | 多周期技术面指标预热 |
### 1.4 IMPROVE — 自成长层
系统自我诊断、自我修正的机制。
| 组件 | 调度 | 行为 |
|------|------|------|
| 知识萃取 (LLM) | 16:30 | 当日分析提炼→写入analyst-knowledge-log.md |
| 策略评估-每日 (LLM) | 21:00 | 六维度评估全部策略→推荐调整 |
| 策略评估-每周 (no_agent) | 周六21:00 | 宽度+深度评估 |
| 建议对账-每周 | 周六20:00 | 交易建议 vs 实际执行核对 |
| 分析师持仓复查 | 周四20:00 | 基本面+技术面持仓复查 |
| **硬编码审计** | **17:25** | **扫描所有.py中大额硬编码数字→告警** |
| 系统全局审计 (LLM) | 17:30 | 7维度系统健康检查 |
| **分支剪枝** | **周六6:00** | **trigger_count≥5且成功率<30%→归档** |
---
## 二、多分支策略树
### 2.1 为什么需要分支?
传统买入区+止损策略在单一市场情景下够用。但A股经常出现:
- 弱震荡时低吸 → 急跌需要割肉 → 反弹要追涨 → 轮动需切换
不同情景需要不同的策略响应。所以每个股票不再只有一个策略,而是一棵**决策树**。
### 2.2 结构
```json
{
"code": "000001",
"strategy_tree": {
"scenario": "weak_consolidation",
"last_scenario_check": "2026-06-23T14:30:00",
"branches": [
{
"id": "buy_dip",
"scenario": "weak_consolidation",
"condition": "price <= buy_low AND volume < avg_volume * 0.7",
"action": "买入",
"priority": 1,
"trigger_count": 3,
"success_rate": 0.67
},
{
"id": "stop_loss",
"scenario": "all",
"condition": "price <= stop_loss",
"action": "止损",
"priority": 0,
"trigger_count": 1,
"success_rate": null
}
],
"pruned_branches": []
}
}
```
### 2.3 分支生命周期
```
创建:per_stock_reassess 初始化时(init_default_branches
活跃:price_monitor 每2分钟检查(evaluate_branches
触发:价格符合条件 → record_branch_trigger → trigger_count++
剪枝:每周六 prune_low_performance_branches
条件:trigger_count ≥ 5 且 success_rate < 30%
动作:移入 pruned_branches(可追溯,不直接删除)
```
### 2.4 情景定义(strategy_tree.py
| 情景ID | 标签 | 触发条件 | 组合建议 |
|--------|------|---------|---------|
| sharp_decline | 急跌防御 | mood=bearish, sector_crash=True | 减仓至80%以下 |
| weak_consolidation | 弱势震荡 | mood=neutral, breadth=weak | 保持仓位90%以内 |
| sector_rotation | 板块轮动 | mood=neutral, rotation=True | 跟随板块切换 |
| bullish_recovery | 反弹上行 | mood=bullish | 加仓至95% |
---
## 三、自成长机制:硬编码审计
### 3.1 为什么?
2026-06-23 发现代码中存在3处硬编码现金/汇率值。这些值不会自己老化,必须通过自动化扫描。
### 3.2 hardcode_scanner.py
扫描规则:
- 所有 `.py` 文件中的赋值语句(=, return, default
- 数字 ≥ 4 位且不是明显的日期/时间阈值 → 标记
- 排除 `LIMIT 200`, `timeout=60`, `CACHE_TTL=86400` 等合法常量
- 输出 JSON 到 `/home/hmo/web-dashboard/data/hardcode_audit.json`
调度:每周一至周五 17:25(在系统审计 17:30 之前5分钟)
### 3.3 响应流程
```
硬编码审计发现问题
→ 知微在下次回复中主动告警
→ 判断是否真硬编码
→ 是:改为从 data/*.json 或 API 实时读取
→ 改完在回复中附上改动摘要
```
### 3.4 发现的已知问题(2026-06-23 修复)
| 位置 | 问题 | 修复 |
|------|------|------|
| stale_push_wlin.py | load_cash() 返146837硬编码 | 改为读 portfolio.json,读不到返0 |
| stale_push_wlin.py | lot_cost 汇率写死0.93 | 改为 hkd_to_cny() 动态 |
| stale_push_wlin.py | 港股每手默认500股 | 改为 Tencent API f[60] 字段实时 |
| hk_rate.py | FALLBACK = 0.87 硬编码 | 改为存最近一次有效汇率到缓存 |
| price_monitor.py | HK_RATE = 0.87 fallback | 最低层兜底,暂时保留(hk_rate全挂时用) |
---
## 四、Cron 清单
> 更新时间:2026-06-23
> 总 job 数:31(其中活跃:约22个交易日核心jobs)
### 4.1 盘中核心(交易日 9:00~16:10
| 名称 | 调度 | 类型 | 脚本 | 用途 |
|------|------|------|------|------|
| 价格监控-高频 | */2 9-16 | no_agent | price_monitor.py | 每2分钟扫价+分支评估+情景检测 |
| 分支扫描-盘中 | 15,45 9-15 | no_agent | branch_scanner.py | 全持仓分支状态扫描 |
| 自选买入区提醒 | 1,31 9-15 | no_agent | stale_push_wlin.py | 自选买入推荐+自动重评 |
| 小果独立扫描 | */5 9-15 | no_agent | xiaoguo_scanner.py | 热榜+新闻 |
| 自选买入区提醒-盘前+午间 | 0 9,12 | no_agent | per_stock_reassess.py | 全部自选重评 |
| 宏观采集-早盘 | 35 9 | no_agent | macro_context_collector.py | 早盘大盘状态 |
| 宏观采集-午间 | 0 12 | no_agent | macro_context_collector.py | 午间大盘状态 |
| 多周期缓存刷新 | 0 9 | no_agent | refresh_mtf_cache.py | 技术指标预热 |
| 开盘简报 | 35 9 | LLM | - | 生成开盘简报 |
| 收盘简报 | 10 16 | LLM | - | 生成收盘简报 |
| 芯碁微装-价格监控 | 0 10,14 | LLM | - | 单票专用监控(新策略期间临时) |
| 策略时效性检查 | 0 9 | LLM | strategy-staleness-check.py | 策略过期检查 |
### 4.2 盘后(交易日 16:00~21:00
| 名称 | 调度 | 类型 | 脚本/技能 | 用途 |
|------|------|------|----------|------|
| 小果情感分析 | 0 16 | LLM | xiaoguo情感分析 | 持仓+自选新闻情感 |
| 知识萃取-盘后 | 30 16 | LLM | finance/analyst-knowledge | 当日经验→知识库 |
| 硬编码扫描-每日 | 25 17 | no_agent | hardcode_scanner.py | 自成长审计 |
| 系统全局审计 | 30 17 | LLM | system_audit.py | 7维度健康检查 |
| 数据采集-策略评估前 | 30 20 | no_agent | collect_evaluation_data.py | 评估数据准备 |
| 策略评估-每日 | 0 21 | LLM | stale_detector.py | 策略六维评估 |
### 4.3 每周(周末)
| 名称 | 调度 | 类型 | 用途 |
|------|------|------|------|
| 分析师-持仓复查 | 周四20:00 | LLM | 基本面+技术面复查 |
| 建议对账-每周 | 周六20:00 | no_agent | 建议vs执行核对 |
| 策略评估-每周 | 周六21:00 | no_agent | 宽度+深度评估 |
| 分支剪枝-每周 | 周六6:00 | no_agent | 低效分支自动淘汰 |
### 4.4 暂停/不活跃
| 名称 | 状态 | 原因 |
|------|------|------|
| MoFin盘前中监控 | 暂停 | 被实时 price_monitor 替代 |
| MoFin午后监控 | 暂停 | 同上 |
| 区间维护 | 暂停 | 2026-06-03已暂停 |
| 市场数据采集 | 暂停 | 被小果扫描替代 |
| 知微洞察生成 | 暂停 | 被实时推送替代 |
| 小果市场筛选 | 暂停 | 被全市场管道替代 |
| 市场精选推荐 | 暂停 | 被实时分支扫描替代 |
---
## 五、关键数据文件
| 文件 | 路径 | 用途 |
|------|------|------|
| decisions.json | /home/hmo/web-dashboard/data/decisions.json | 所有股票策略(含分支树) |
| portfolio.json | /home/hmo/web-dashboard/data/portfolio.json | 持仓+现金 |
| price_events.json | /home/hmo/web-dashboard/data/price_events.json | 价格触发事件记录 |
| strategy_staleness_report.json | /home/hmo/web-dashboard/data/strategy_staleness_report.json | 策略过期报告 |
| macro_context.json | /home/hmo/web-dashboard/data/macro_context.json | 大盘宏观状态 |
| hardcode_audit.json | /home/hmo/web-dashboard/data/hardcode_audit.json | 硬编码扫描结果 |
| system_audit_report.json | /home/hmo/MoFin/data/system_audit_report.json | 系统审计报告 |
| ~/.cache/hk_exchange_rate.json | 用户目录 | HKD汇率缓存(含上次有效值) |
---
## 六、关键设计原则
1. **有触发才推** — 所有监控脚本默认静默,有操作信号才生成输出。no_agent + SILENT原则
2. **数据驱动** — 所有数字从文件/API读,禁止硬编码现金、汇率、手数
3. **先重评再出报告** — 自选提醒必须先等重评完成,再用重评后数据出报告
4. **no_agent 优于 LLM 用于纯数据管道** — 数据采集/转发用 no_agent 脚本(零token),判断/分析用 LLM
5. **分支可追溯** — 分支剪枝不直接删除,移入 pruned_branches 历史字段
6. **自成长必须自动化** — 能扫的不要等人发现,能修的不要等人报
---
## 七、元自成长层(Meta-Growth
### 7.1 为什么需要元层?
前三层的循环(Sense→Respond→Adapt→Improve)有一个根本局限:**Improve层本身不会成长。**
- hardcode_scanner 只扫当前定义的规则,不会自己发现"还需要扫什么"
- 分支剪枝只基于现有的成功/触发统计,不会自己引入新的评估维度
- 知识萃取只做分析经验积累,不会从修复模式中学习新的问题类型
**元层(meta-growth)的功能:定期审视所有自成长机制本身,基于近期修复模式自动扩展扫描类别。**
### 7.2 meta_growth.py
```
交易日 12:45 和 00:45 运行(自成长机制中的最高层)
12:45: 读取上午盘git log → 分析发现的新问题
→ 如果发现新模式 → 注入硬编码扫描规则
→ 下午盘的 hardcode 审计 17:25 就能用上新规则
00:45: 读取全天git log → 分析修复模式
→ 更新 growth_registry
→ 注入新规则(次日生效)
```
### 7.3 为什么每天两次?
| 调度 | 作用 |
|------|------|
| **12:45**(午间) | 上午盘中发现问题 → 注入新扫描规则 → **下午17:25的硬编码审计就能用上新规则**。例如知微上午修了一个"港股每手股数"问题,12:45 meta_growth 分析git log识别到新模式并注入,17:25自动扫出同类问题。半天内完成闭环。 |
| **00:45**(凌晨) | 全天修复汇总 → 注册表更新 → 下一天的所有审计带新规则运行。 |
### 7.4 问题类别注册表(growth_registry.json
路径:`/home/hmo/web-dashboard/data/growth_registry.json`
记录所有历史上的问题类别和对应的扫描规则:
- 已发现的类别
- 已添加的扫描规则
- 当前周期的新建议
- 自成长元层最近运行时间
### 7.5 扩展点机制
`hardcode_scanner.py` 中预置扩展点注释:
```python
# 扩展点 — meta_growth 在此追加新规则
```
`meta_growth.py` 检测到新模式后,直接在扩展点后插入新规则元组。下次 hardcode_scanner 运行时自动执行新规则。
### 7.6 自成长机制的迭代链路
```
第一周:
hardcode_scanner 扫出 cash 硬编码(手动发现的)
→ 修复
→ meta_growth 发现 "hardcode_cash"模式
→ 添加 asset硬编码扫描规则
第二周:
hardcode_scanner 自动运行新规则
→ 扫出下一个硬编码
→ 修复
→ meta_growth 发现新模式...
每一轮迭代,扫描规则自动扩展。
```
### 7.7 元层的自我审视
meta_growth 每次运行也会检查自成长系统本身的健康度:
- hardcode_scanner 是否存在
- 注册表是否可写
- 本周是否正常执行过
- 上次提出的建议是否已实施
如果发现某条自成长机制失效(如 hardcode_scanner 连续3周无输出、cron job 挂掉),meta_growth 会输出告警。