# 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.json,signal_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:43,bot加入群聊coregroup就绪,gateway health ok,HTTP桥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 是内存dict,price_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:28,presence=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.service(2276次失败重启,不再需要,由gateway管理bot) 5. 清理PID文件 /tmp/xmpp_zhiwei_bot.pid ### 效果预期 - 断线后slixmpp自动重连(最快5s,指数退避) - 看门狗兜底:120秒未恢复则进程退出→gateway respawn - systemd不再干扰(已stop,gateway管理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已清空