Files
MoFin/docs/analyst-knowledge-log.md
T

301 lines
17 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.
# analyst-knowledge-log.md
## [2026-07-09 22:00] 全市场主力建仓扫描 + 五级过滤 + LLM九维分析
### 新增组件
| 组件 | 功能 | 调度 |
|------|------|------|
| `accumulation_scanner.py` | 全市场5207只A股量价异常扫描(每10分钟13秒) | `*/10 9-15` |
| `candidate_filter.py` | 五级过滤管道(S2量价/S3技术/S4资金/S5基本面) | `*/30 9-15` |
| `promote_candidates.py` | 自动提拔高分候选入自选 | `*/30 9-15` |
| `batch_reassess.py` | 批量LLM九维分析补全(逐只处理间隔15秒) | 一次性 |
### 系统架构变更
## [2026-07-10 11:42] 知微XMPP Bot离线自愈修复
### 发现
自愈执行器报告知微XMPP Bot离线。调查发现:
- Bot进程(PID 422464)被bash包装器手动启动,非systemd管理
- systemd xmpp-zhiwei.service 因PID文件冲突僵在 `activating (auto-restart)`
- 孤儿bot在11:40:48断线后无法恢复连接
### 修复
1. 杀死孤儿进程 `kill -TERM 422464`
2. 删除PID文件 `rm -f /home/hmo/.hermes/zhiwei_bot.pid /tmp/xmpp_zhiwei_bot.pid`
3. systemd自动重启,bot干净上线
4. 验证:presence available、加入coregroup、bridge正常
### 教训
bash包装器启动bot会绕开systemd管理,导致:
- systemd状态监测不准确(显示restarting而非running
- 孤儿进程断开后无法被systemd接管
- 已有 `xmpp-bot-infrastructure` skill 记录了孤儿进程陷阱,自愈系统可直接参考执行
自选统一:**
- 自选数据统一存储在 `holding_strategies(decision_type='自选策略')`
- `watchlist_stocks` 表已废弃(is_active=0
- `read_watchlist()` 改为从 `holding_strategies` 读取
**DB统一:**
- `~/.hermes/profiles/position-analyst/data/mofin.db` → 软链接 → `/home/hmo/MoFin/data/mofin.db`
**去小果化:**
- `xiaoguo_scanner` / `xiaoguo情感分析` / `xiaoguo信号消费` 全部停用
- 替代为 `accumulation_scanner.py`(纯数据驱动,0 LLM成本)
### 九维分析
`per_stock_reassess.py` 重评时自动调用LLM(gateway API)生成完整九维分析:
- 数据源全部随需随拉(腾讯API实时价/PE/市值 + DB大盘/基本面/消息)
- LLM输出信号+买入区间+止损止盈+仓位百分比
- 超时自动降级为代码生成
### 冷却期机制
- `per_stock_reassess`: `reassessed_at`追踪,交易时段1小时/非交易24小时
- `price_monitor` zone breach: `_can_push()` 同股同区间30分钟冷却
### 仓位规则
- 仅「买入」信号输出仓位建议
- 仓位公式:RR×大盘调整×品种调整,范围5%~20%
- 关注/观望/卖出信号仓位为空
### 数据清理
- DROP TABLE: stock_weekly, stock_monthly(无人读取的死表)
- DROP TABLE: portfolio_state(无人读写的僵尸表)
- holdings: 清除shares=0的5只持仓
- watchlist_stocks: 全部标记is_active=0(已迁移)
- **发现**: candidates表有15条历史候选数据但promoted=0的都被手动标记了dropped=1(超7天未更新)。自动推广管道从未实现。
- **修改**: 新建 `scripts/promote_candidates.py` — 扫描 candidates(promoted=0+dropped=0) → stock_quote验价 → write_holding_strategy → 标记promoted
- **新建cron**: 候选股自动推广-盘中(e415846d4fb6) | 0,30 9-15 * * 1-5 | no_agent | 静默模式
- **效果预期**: 新候选股在30分钟内自动进入自选+带策略,不再依赖LLM prompt
## [2026-07-09 10:40] 自愈执行器升级处理:KOSDAQ-4.1% HIGH信号
- **发现**: 自愈执行器上报盘中自检发现宏观风险HIGH(KOSDAQ-4.1% + 中信证券研报)
- **判断**: 系统无故障,已知市场条件延续。KOSDAQ-4.1%是昨日KOSPI暴跌的延续,非新事件。中信证券研报是采集器误报(正常行业研报)。
- **数据验证**: 中国各指数全面脱钩改善(上证-1.26%→+0.02%,恒生-0.51%→+1.69%,科创50+0.28%→+0.62%)。持仓止损距均>3%。
- **操作**: 标记已知状态,无需新推送。08:30 LLM深度分析已覆盖并修正。
- **涉及文件**: macro_risk_state.json(已由consumer更新为processed
## [2026-07-09 14:xx] 自愈执行器升级:信号堆积38条
- **发现**: 盘中自检触发「信号堆积: 38条未处理(需<30)」告警,自愈执行器无自动修复方案,升级到LLM处理
- **调查**: 38条为 xiaoguo 来源信号,属4h时效内积压。当前已完成消费(xiaoguo_signal_consumer每30分运行),积压自愈
- **监控盲区发现**: intraday_health_check.py 和 system_audit.py 均只监控 `source LIKE 'xiaoguo%'`,忽略 divergence_watch(80)、trend(46) 等来源的126条未处理信号
- **修复**: 两处均增加全量未处理查询,区分 xiaoguo 和其他来源分别报告
- **涉及文件**: scripts/intraday_health_check.py, scripts/system_audit.py, CHANGELOG.md
## [2026-07-09 14:xx] 自愈执行器升级:信号积压126条(divergence_watch/trend无consumer
- **发现**: 自愈执行器上报「其它来源信号积压: 126条未处理(divergence_watch/trend等无consumer)」
- **调查**: divergence_watch 80条全部未处理 — divergence_detector.py写入signal_news但已自写macro_divergence_state.jsonsignal_news仅归档副本。trend 46条未处理 — 废弃系统的死数据,summary为空
- **修复**: divergence_detector.py — INSERT时加processed=1(归档性质不需要consumer)。DB — 80条divergence_watch + 46条trend历史标记为processed。同步cron目录MD5一致
- **效果**: signal_news 1077条全量已处理,健康检查PASS,后续不会再次积压
- **涉及文件**: scripts/divergence_detector.py, data/mofin.db, CHANGELOG.md
## [2026-07-10 10:25] 自愈:知微XMPP Bot离线 — 孤儿进程阻塞systemd
- **发现**: 盘中自检报警「知微XMPP Bot离线」,TODO 83 created(无fix_action,升级到LLM处理)
- **调查**:
- systemd `xmpp-zhiwei.service` 陷入无限重启循环(重启计数器110+)
- 根因:外部bash wrapper脚本在10:04启动了一个孤儿bot进程(PID 252975),该进程占用了`/tmp/xmpp_zhiwei_bot.pid`和端口5805
- systemd每次尝试启动都因PID检查`xmpp_zhiwei_bot already running (PID 252975), exiting.`而退出
- 实际上PID 252975的bot是正常运行的(已加入群聊coregroup,HTTP桥5805正常响应),只是不受systemd管理。wrapper触发源不明(可能自愈系统之前的升级操作)
- **修复**:
1. `kill -TERM 252975` 杀掉孤儿进程
2. 清理旧PID文件 `/tmp/xmpp_zhiwei_bot.pid``/home/hmo/.hermes/zhiwei_bot.pid`
3. systemd 10秒RestartSec后自动启动新实例
4. TODO 83 标记为completed
- **验证**: systemd active(running) since 10:25:43bot加入群聊coregroup就绪,gateway health okHTTP桥5805正常
- **效果**: systemd恢复管控bot,重启循环归零
- **涉及文件**: /home/hmo/xmpp_zhiwei_bot.py (PID_FILE机制)
## [2026-07-13] XMPP Bot非阻塞修复 + 深套股规则重构 + 换股规划
### XMPP Bot修复
- **问题1**: bot调用gateway同步等600秒,阻塞事件循环 → XMPP心跳发不出 → 被踢下线 → 重试→turn堆积→更慢
- **修复**: 45s短超时 + "处理中"预回复 + 后台300s轮询 + 不再阻塞心跳
- **问题2**: 远程XMPP服务器(120.78.123.183:5222)网络不通,bot连不上
- **修复**: bot.connect(host='127.0.0.1', port=5222) 改连本地XMPP代理
- **问题3**: xep_0045 MUC插件未注册导致崩溃
- **修复**: __init__加 self.register_plugin('xep_0045')
- **涉及文件**: /home/hmo/xmpp_agent_core.py
### price_monitor通知噪音修复
- **问题**: _push_cooldown 是内存dictprice_monitor每2分钟新进程运行 → cooldown每次重置 → 同股同区间反复推送
- **修复**: cooldown持久化到 /home/hmo/.hermes/.price_push_cooldown.json
- **涉及文件**: scripts/price_monitor.py
### 深套股规则重构(Dad铁律确认)
- **删除**: `is_deep_loss` 对止损/止盈/买入区/质量检查的全部6处guard
- **删除**: `action_note="深套持有"` 强制覆盖
- **删除**: `position_advice="不补不割"` / `time_horizon="长期"`
- **保留**: `stock_category="深套"` 仅作标签
- **原则**: 一切根据客观判断,该加就加该割就割
- **涉及文件**: scripts/strategy_lifecycle.py
### 换股规划功能
- `python3 strategy_lifecycle.py swap-plan [--need 金额]`
- 五维评分: 亏损程度25% + 仓位20% + 技术趋势25% + 流动性15% + 前景15%
- 按评分排序输出可替换优先级,--need 参数自动计算卖几只够
- **涉及文件**: scripts/strategy_lifecycle.py
### 技术分析增强
- weekly/monthly趋势/MA/支撑阻力注入mtf_context
- 健康Tab写无读警告从3个归零(stock_weekly/monthly/watchlist_log加manual_readers
- 每日汇总只发一次(16:35 + sent标记防重复)
- cron_health_monitor新增数据实体完整性检查
- 涉及文件: scripts/technical_analysis.py, scripts/strategy_lifecycle.py, scripts/mofin_health.py, scripts/cron_to_xmpp.py, scripts/cron_health_monitor.py
## 2026-07-14 — 系统检查:Dad未收到任何消息的诊断
### 发现问题
1. **cron_to_xmpp.py Bug**: body提取`content.split("## Response")``parts[1]`取到的是skill内容中的 ## Response(第一个),而不是agent实际回复的 ## Response(最后一个)。导致开盘简报等LLM报告的正文取错,被误判为[SILENT]静默拦截。
2. **price_monitor.py SQLite写锁死锁**: 多个cron脚本(price_monitor + mofin_health等)同时BEGIN IMMEDIATE写 mofin.db,进程卡在D状态,WAL文件膨胀到2.7MB,后续全部超时。
3. **mofin_db.py版本不同步**: cron版本和MoFin版本有差异(cron版本多了保留full_analysis/reassessed_at的代码)。
### 修改了什么
- `cron_to_xmpp.py` — 改 `parts[1]``parts[-1]`(取最后一个Response节)
- `mofin_db.py` (MoFin目录) — 同步cron版本的reassessed_at列处理和full_analysis保留逻辑
- `price_monitor.py` — 添加debug时序追踪,临时kill D状态进程+WAL checkpoint
- `.silent_daily_count.json` — 纠正静默计数(-1因为开盘简报被误拦)
### 文件
- Modified: /home/hmo/.hermes/profiles/position-analyst/scripts/cron_to_xmpp.py
- Modified: /home/hmo/MoFin/scripts/mofin_db.py
- Modified: /home/hmo/.hermes/profiles/position-analyst/scripts/price_monitor.py
## 2026-07-14 — price_monitor DB写锁死锁根治(跟进修复)
### 发现问题
上次诊断只做了临时修复(kill D状态进程 + WAL checkpoint),Dad要求直接根治。
### 修改了什么(三副本同步)
- **price_monitor.py** (profile/scripts): 统一 BEGIN IMMEDIATE 包裹所有写操作,替代调用 write_holdings_batch/write_portfolio_summary/write_live_prices。5次重试+指数退避(1s→2s→4s→8s→16s)。重试耗尽后自动 emergency WAL checkpoint。try/except 确保 conn 始终释放。
- **MoFin/scripts/price_monitor.py** — 同步修复
- **MoFin/price_monitor.py** — 同步修复(保留其 cash_log 优先的现金读取逻辑)
- **CHANGELOG.md** — 新增2026-07-14条目
### 文件
- Modified: /home/hmo/.hermes/profiles/position-analyst/scripts/price_monitor.py
- Modified: /home/hmo/MoFin/scripts/price_monitor.py
- Modified: /home/hmo/MoFin/price_monitor.py
- Modified: /home/hmo/MoFin/CHANGELOG.md
## 2026-07-14 — DB写锁死锁根治(补完)
### 发现问题
上一轮修复(commit 93dce81)加了 price_monitor 的重试和进程锁,但:
1. mofin_db.py 的 get_conn() 没有在连接时自动清理 WAL,被 kill 的进程残留 WAL 仍会卡死后续连接
2. 其他并发写脚本(market_watch, mofin_health 等)没有重试保护
3. price_monitor 的 os.nice 缺失,高优先级抢占 DB 锁
### 修改了什么
- mofin_db.py get_conn(): 每次连接时 `PRAGMA wal_checkpoint(TRUNCATE)` 自动清理残留 WAL
- price_monitor.py run_once(): 加 `os.nice(10)` 降低优先级
- 其他并发脚本:通过 get_conn() 的 WAL checkpoint 间接保护 + busy_timeout=30s 兜底
### 效果预期
- 任何进程被 kill 后,下一个连接的脚本自动 checkpoint 清理 WAL,不会卡死
- price_monitor 进程锁防止同一脚本并发
- priority 降低减少恶性抢占
## 2026-07-14 10:55 — DB死锁根治:盘中脚本统一get_conn()
### 发现问题
price_monitor.py的`refresh_data_prices()`已有完善的重试机制(5次+指数退避+WAL checkpoint),但其他盘中高频脚本仍然使用raw `sqlite3.connect()`,绕过`get_conn()`的WAL模式+busy_timeout=30s设置。
### 修改了什么
- `mofin_health.py` — get_db_stats()改get_conn()
- `cron_health_monitor.py` — price_monitor新鲜度查询改get_conn()
- `intraday_health_check.py` — 3处sqlite3.connect全部改get_conn()
- `self_todo_executor.py` — sqlite3.connect改get_conn()
- `mofin_db.py` — get_conn()每次新建连接时WAL checkpoint
### 测试结果
并发压力测试:3x price_monitor + 3x mofin_health同时运行 → 6/6通过,WAL仅32bytes
### 文件
- Modified: /home/hmo/MoFin/mofin_db.py
- Modified: /home/hmo/MoFin/scripts/cron_health_monitor.py
- Modified: /home/hmo/MoFin/scripts/intraday_health_check.py
- Modified: /home/hmo/MoFin/scripts/mofin_health.py
- Modified: /home/hmo/MoFin/scripts/self_todo_executor.py
- Modified: /home/hmo/.hermes/profiles/position-analyst/scripts/ (同上5文件)
- Commit: 59e94d1, pushed to origin/master
## 2026-07-14 10:55 — 知微XMPP Bot断线不重连修复
### 发现问题
自愈执行器发现知微XMPP Bot离线。调查发现:
1. Bot进程(3643320)由gateway产生,但无任何TCP连接(断线后slixmpp不会自动重连,因为`auto_reconnect`默认关闭)
2. systemd的xmpp-zhiwei.service有2276次失败重启记录(PID文件冲突)
3. Bot进程(3643320)始于04:28presence=unavailable,但HTTP桥(5805)仍活着
### 根因
slixmpp ClientXMPP的`auto_reconnect`属性默认为False。断线(connection_lost)发生后,bot进程保持运行(HTTP桥继续工作)但从不尝试重新连接XMPP。在main()中`await bot.ready.wait()`已通过,asyncio.gather继续运行,bot看起来活着但实际上无法接收/发送XMPP消息。
### 修改了什么
- `/home/hmo/xmpp_agent_core.py`:
1. AgentBot.__init__()加 `self.auto_reconnect = True`
2. 新增 `connection_watchdog()` 看门狗协程——每15秒检查连接状态,断线超过120秒执行`os._exit(1)`让gateway重新spawn
3. main()启动connection_watchdog作为独立任务
### 执行了什么
1. Kill旧bot(3643320) → gateway自动spawn新bot(114609) → 新bot连接XMPP成功但被ejabberd重启踢下线
2. Kill中间bot(114609) → gateway再spawn(122594) → 稳定连接
3. Kill 122594后gateway spawn新bot(131908)加载修复代码,自动重连生效
4. Stop systemd xmpp-zhiwei.service2276次失败重启,不再需要,由gateway管理bot)
5. 清理PID文件 /tmp/xmpp_zhiwei_bot.pid
### 效果预期
- 断线后slixmpp自动重连(最快5s,指数退避)
- 看门狗兜底:120秒未恢复则进程退出→gateway respawn
- systemd不再干扰(已stopgateway管理bot生命周期)
### 文件
- Modified: /home/hmo/xmpp_agent_core.py
- Stopped: systemctl stop xmpp-zhiwei.service (2276失败重启)
## [2026-07-14 11:00] divergence_detector 修复 — 改用新浪API直取指数数据
### 发现问题
- divergence_detector.py 的 `fetch_indices()` 使用 `mo_data.get_prices_batch()` 获取指数行情
-`mo_data` 仅支持个股代码,不支持指数代码(sh000001/hkHSI等)
- 导致 `get_prices_batch()` 返回空字典 → `fetch_indices()` return {} → main() 提前返回
- 后果:macro_divergence_state.json 自2026-07-08起连续6天未更新
### 修复内容
- **文件**: `scripts/divergence_detector.py` (MoFin + profile副本已同步)
- **修改**: 重写 `fetch_indices()`,从 mo_data 调用改为直接调用新浪API(hq.sinajs.cn)
- **细节**:
- 8个指数用sina_map映射到新浪API的代码格式
- A股指数解析 fields[3] 为 change_pct
- 港股指数解析 fields[8] 为 change_pct(之前写错了 index=7,误读为涨跌额)
- **清理**: 移除不再使用的 `from mo_data import get_price, get_prices_batch`
- **commit**: d972553
### 验证
- divergence_detector.py 手动运行正常输出
- macro_divergence_state.json 已更新到 2026-07-14 11:07,包含8个指数实时数据
- state 自动检测到科创50(-4.2%) vs 恒指(-0.7%) MEDIUM背离信号
## [2026-07-21 11:50] 小果误报清理——盘中自检脚本消除残留引用
### 发现问题
自愈执行器持续报"小果Gateway :8645 未监听"——小果已全线归档,此为残留引用导致的误报。
### 修改内容
- `/home/hmo/MoFin/scripts/intraday_health_check.py`: 用 deploy 版本的干净副本覆盖(移除 check_xiaoguo() 函数、xmpp-xiaoguo.service 检测、8645端口检测、xiaoguo信号堆积检测)
- DB中残留的TODO ID 125/126 已resolve为completed
### 根因
MoFin重构(2026-07-20)时 deploy/profile-scripts/ 已更新但 scripts/ 中源文件未同步,盘中自检写入了小果相关的TODO后,自愈执行器持续处理这些积压TODO。
### 验证
- 运行版本(profile-scripts/)与deploy版本一致,小果引用为零
- DB中小果相关pending/in_progress TODO已清空