记录知微对MoFin系统的缺陷修复和知识萃取项。 ## 2026-07-02 11:30 macro_context_collector.py Pattern 9 百分比阈值修复 + 跨句涨幅匹配修复 **发现了什么:** 自愈执行器报告false positive——"中概领涨"被标记为HIGH风险。追踪发现Pattern 9 `指数[^。]*?(?:跌幅|下跌)[^。]*?[2-9]%`有两个Bug: 1. 小数阈值Bug: `[2-9]%`在"0.3%"中提取"3%"匹配,误将<2%跌幅标为HIGH 2. 跨句匹配Bug: "指数集体下跌的背景下...中概收涨近3%"中,`[^。]*?`跨过整个句子把"下跌"和"3%"连起来,但"下跌"是指美股下跌,"3%"是指中概收涨——两个不同语境 **修改了什么:** - 文件: `/home/hmo/MoFin/scripts/macro_context_collector.py` - Pattern 9: `指数[^。]*?(?:跌幅|下跌)[^。]*?[2-9]%` → `指数[^。]*?(?:跌幅[^。]{0,20}(?:扩大至|达|至|超|为|逾)[^。]*?(?40% ## 2026-06-25 11:50 价格监控updated_at修复 **发现了什么:** 健康检查误报"价格数据649秒未更新(portfolio.json)" **根因链:** 1. `price_monitor.py` 写 portfolio.json 时仅在价格变化时写入,且不更新 `updated_at` 字段 2. 盘中价格稳定(如午盘横盘)→ portfolio.json 长时间不更新 → `updated_at` 停留在上次变动时间 3. `intraday_health_check.py` 检查 `updated_at` 是否超过10分钟无更新 → 触发误报 **修改了什么:** - 文件:`/home/hmo/MoFin/price_monitor.py`(同步到 profile scripts 副本) - 逻辑变更: - 价格变化写入时:同时更新 `pf['updated_at']` 为当前时间 - 价格无变化时:每10分钟强制刷新一次 `updated_at`,避免横盘期误报 **效果预期:** 价格稳定横盘时 portfolio.json 的 updated_at 仍每10分钟刷新一次,健康检查不再误报。 ## 2026-06-25 13:20 stale_push_wlin 流程修复:先重评后推送 **发现了什么:** 自选买入提醒中推送的策略数据可能滞后。例如13:11报告中德明利止盈810.78但现价882已超过。 **根因链:** 1. stale_push_wlin 只在 `[STRATEGY_STALE]` 标记的票触发重评,非stale的票直接推旧策略 2. 策略的止盈/止损/信号在推送前未刷新,可能出现推了止盈位但价格已超过的情况 3. Dad 指出正确流程应该是:推荐前先重评 → 重评确认有效再推 **修改了什么:** - 文件:`/home/hmo/.hermes/profiles/position-analyst/scripts/stale_push_wlin.py` - 逻辑变更: - 收集所有在买入区的自选(stale + 非stale),统一先调 trigger_regen_sync() 重评 - 重评完成后重新读取 decisions.json 获取最新策略数据 - 用重评后的 timing_signal 重新判断是否可推(不再用旧 is_stale 标记) - 同一次推送中可能有多只票,全部用新数据出报告 **效果预期:** 每次推送自选提醒前,所有预推票都经过最新一次策略重评,止盈/止损/信号不滞后。 ## 2026-06-25 14:00 三点联动修复 **发现了什么:** Dad反馈三个问题:(1) price_monitor的区进区出/重评告警太吵 (2) 现金只有total字段,没有区分可用/冻结,买力算错 (3) 德明利卖出后未及时更新止盈 **修改了什么:** **① price_monitor XMPP推送降噪** - 文件:`/home/hmo/MoFin/price_monitor.py` - 原:所有outputs(⚡进入买入区 🔄重评 📊新策略 ✅全量重评)全部推XMPP - 改:只推 ⚠️止损跌破 和 🌀情景切换,其余只local print不推 **② 现金三级结构** - 文件:`/home/hmo/MoFin/data/portfolio.json` - 新增 `cash_available`(可用买力)和 `cash_frozen`(冻结在途)字段 - stale_push_wlin.py:load_cash() 和 calc_position() 优先读 cash_available,fallback到 cash - 推荐中的买力计算现在用可用现金而非总现金 **③ 德明利自选策略重评** - 文件中:`/home/hmo/MoFin/data/decisions.json` - 原止盈810.78(已被涨停突破) - 新止损810.0 新止盈1153.26 新买入区873.18~908.82 | RR=3.24 - 已保证自选策略和其他自选一样走自动重评流程 **效果预期:** 系统不再推送区进出/重评噪音,推荐用可用现金算买力,德明利自选随时可重新入场。 ## 2026-06-25 14:50 price_monitor 自选止损止盈告警屏蔽 **发现了什么:** 德明利(001309)已清仓转自选,但 price_monitor 仍对其推送止盈警报("⚡ 德明利进入止盈区间"),数据无误但信号无意义,在Dad卖飞后伤口撒盐。 **根因:** get_trigger_zones() 对自选和持仓一视同仁返回止损/止盈区间,price_monitor检查所有active decision。 **修改了什么:** - 文件:`/home/hmo/MoFin/price_monitor.py` - 函数 `get_trigger_zones(d)`: - 买入区间:自选和持仓都监控(自选需要zone to trigger重评) - 止损+止盈:仅持仓(share>0)才监控,自选不生成止损/止盈zone **效果预期:** 已清仓的德明利/药明康德等自选不再推送止损止盈告警。买入区进出仍触发重评(内部不推送),保证策略持续更新。 ## 2026-06-27 三维分析框架固化(news-flow-analysis skill) **发现了什么:** 协鑫能科(002015)分析暴露三个系统性问题: 1. 之前分析脱离大盘环境看个股,给出孤立判断 2. 资金流数据只看单日暴量不看连续性,被6/24→6/25反向流误导 3. 没有离场预警框架,只关注买入机会不关注风险信号 **新设了什么:** - Skill: finance/news-flow-analysis — 新闻+资金流+大盘三维分析法 - 四个层面印证框架(消息面→技术面异常→资金流验证→资金性质追踪) - 反向框架(离场预警信号) - 六项报告输出规则(大盘→板块→个股异常→资金验证→资金性质→明确结论) **自检清单(所有报告产出必须检查):** □ 有没有考虑大盘环境? □ 有没有考虑板块背景? □ 逆势信号有没有识别? □ 资金流向有没有验证? □ 是单日暴量还是连续趋势? □ 有没有离场预警的反向思考? □ 结论有没有具体价格? □ RIP原则:数据是否已核实(非模拟伪造)? **效果预期:** 所有个股分析自动走三维印证流程,避免孤立判断。资金流分析看趋势不看单日。每份报告自带离场预警条件。 ## 2026-06-29 数据新鲜度铁律(数据准确零容忍 · 违反记录) **违反了什么:** 周一(6/29) 15:20 和 15:48 两次分析使用了 multi_tf_cache.json(周五 23:05 缓存的收盘价)作为价格依据,未拉取腾讯实时价。 **导致的错误:** 中芯国际 H 建议止损(实际+10%盈利)、建滔积层板建议止损(实际盈利+11%)、中国神华建议止损(实际反弹+15%)。完全错误的操作建议。 **根因:** LLM 分析时图方便读了本地缓存文件,没有执行「先拉实时价」这个基本动作。 **修复规则(永久写入):** - 任何分析、报告、回复,第一行代码必须是拉取腾讯实时报价 - 严禁从 multi_tf_cache.json / decisions.json 等缓存文件直接读取价格数据来推操作建议 - 唯一允许的价格源:腾讯实时 API(qt.gtimg.cn)或 price_monitor 刚写入的 events/state - 违反这条 → 自动回滚,追加到违规记录 ## 2026-07-02 10:00 盘中自检 NameError 修复 **发现了什么:** 自愈执行器报 `盘中自检: 价格数据新鲜度检查失败: name 'mo_data' is not defined` - 根因:`intraday_health_check.py` 第11行用 `from mo_data import read_portfolio`(直接导入函数),但第117行写的是 `mo_data.read_portfolio()`(当模块名调用) **修改了什么:** - 文件:`/home/hmo/MoFin/scripts/intraday_health_check.py` - 变更:`mo_data.read_portfolio()` → `read_portfolio()` **效果预期:** 盘中自检不再因这个 NameError 报异常,能正常检查 portfolio.json 数据新鲜度。 ## 2026-07-02 10:51 宏观风险HIGH升级应对 **发现了什么:** 自愈执行器上报当日第二次HIGH信号(科创50扩大至-5%、创业板-4%)。同时KOSPI从-7%收窄至-3%(改善方向信号)。 **修改了什么:** - 文件:`macro_risk_state.json` - 变更:升级模式更新state,分别标注恶化(科创50/创业板扩大跌幅)和改善(KOSPI收窄、恒指+1.3%)两个方向,避免笼统"附加新数据点" **萃取知识:** 1. B类板块冲击下,防御仓位(紫金+6.8%、黄金ETF+2%、神华+1.2%)当日有效对冲科技股损失,验证了组合构建合理性 2. 中芯国际A(688981)是当日最危险持仓(距止损2.14%),中芯国际AH走势分化(A-2.96% vs H-8.05%)值得关注——A股有溢价保护,H股更直接暴露于全球半导体卖压 3. 分歧检测bias=opportunity + A/H科技背离>5pp → 极端背离时不能简单看空,A股科技暴跌时港股科技反而上涨,资金在跨市场迁移而非逃离科技板块 ## 2026-07-02 盘中 价格数据新鲜度检查格式不兼容 **发现了什么:** 自愈执行器报 `盘中自检: 价格数据新鲜度检查失败: unconverted data remains: :06` **根因:** `intraday_health_check.py` 的 `datetime.strptime(pf_updated, "%Y-%m-%d %H:%M:%S")` 硬编码要求带秒格式,但 `price_monitor.py` 等写入 `updated_at` 用 `strftime('%Y-%m-%d %H:%M')` 无秒格式。当 `read_portfolio()` 回退到 JSON 冷备时读到无秒时间戳 → 解析失败。 **修改了什么:** - 文件:`/home/hmo/MoFin/scripts/intraday_health_check.py` - 变更:引入 `_parse_updated_at()` 函数,先试带秒格式 `%Y-%m-%d %H:%M:%S`,失败则回退无秒格式 `%Y-%m-%d %H:%M`;两次都失败时明确记录"格式无法解析"而非抛异常 **效果预期:** 无论 `updated_at` 是 `'2026-07-02 10:43'`(无秒)还是 `'2026-07-02 10:43:53'`(有秒),都能正确解析并计算新鲜度。 ## 2026-07-02 11:47 宏风险HIGH持续——系统无故障,已知市场事件延续 **发现了什么:** 自愈执行器报盘中自检→宏观风险HIGH。核实后发现该风险已在11:27向Dad推送过完整报告,且到损位均未触发。这不是系统故障,是已知市场状态(全球半导体抛售)的延续。 **附带的data issue:** portfolio.json的`currency`字段将所有港股(8只)标为CNY而非HKD。影响跨币种计算准确性。 - 根因追踪:`import_holding_xls.py`(line67)正确设HKD,但`strategy_lifecycle.py`(line2027)的`setdefault('currency','CNY')`在策略更新时覆盖了币种标记 - 修复计划:盘后(非交易时段)统一排查并修正currency字段在数据管道中的传播路径 **萃取知识:** 1. 自愈执行器对宏风险的报警是设计行为(health check标记risk=high→写TODO→升级处理),需要按"已知市场状态"处理而非"系统故障" | 腾讯(00700)距止损2.76%是所有持仓中最接近止损位的——本轮冲击前未被重点标记,暴露了"只关注风险最大的几个"忽略了中游风险 ## 2026-07-04 周末宏观风险评估(首次独立周末扫描) **发现了什么:** 采集器08:00输出2条HIGH信号,但经LLM深度分析确认为误报: 1. 「单一押注有色 百亿基金栽在盛达资源」→ LOW(基金级个股新闻,误报模式4:公司/基金事件误标为宏观风险) 2. 「北约领导人宣布伊朗不得拥核」→ MEDIUM(政治声明,但整体美伊趋势为降级降级谈判/石油恢复/海峡共管推进) **执行操作:** signal_news ID=760 修正覆盖(UPDATE) + ID=761 插入正确MEDIUM信号 **综合判定:** MEDIUM(新闻维度MEDIUM+组合高暴露MEDIUM→2个MEDIUM) **关键发现:** 周末数据采集(Curl东方财富首页+macro_raw_news 50条)确认一周来最大的系统性风险变化是——美伊冲突全面降级(OPEC产量恢复、伊朗洽售石油、多哈会谈推进),而这在signal_news历史HIGH信号中完全未体现。采集器只抓取了北约声明这个单独事件,忽略了整体趋势改善的上下文。**周末扫描的核心价值在于提供采集器无法做到的语境整合判断。** **萃取知识:** 1. 周末扫描的第一步(检查未评级新闻)如果为空,必须主动从curl数据中提取Fetched新事件INSERT入库——不能直接输出"无未评级新闻" 2. 背离检测器在非交易日持续运行,divergence_state的level=none+bias=opportunity为本次MEDIUM判定提供了关键支撑——无市场结构风险 3. 非农数据"弱于预期"是反向逻辑(鸽派利好),采集器关键词无法区分方向性语义,LLM修正时需特别注意误报模式11 ## 2026-07-08 09:59 全面审计修复(JSON违规 + 策略表空 + 潜力股管道中断) **发现了什么:** Dad质疑三个问题:(1)重点操作只关注持仓 (2)看不到新自选潜力股 (3)系统到底正不正常。全面审计后发现了系统性漏洞: **问题1 — JSON违规(最严重):** 6个脚本仍直接读写portfolio.json/decisions.json/watchlist.json,违反Dad 2026-07-06铁律。根因:6月DB迁移后未审计所有引用文件。 修复:price_monitor.py、price_data_inject.py、market_insight.py、inspect_decisions.py、strategy_summary.py、fix_portfolio_prices.py、pre-flight-check.py 全部改为DB API(mo_data.read_* / mofin_db.write_*)。同步清理4处误导性注释。 **问题2 — holding_strategies表空(策略丢失):** 19条策略全丢失,read_decisions()返回0条。根因不明(可能是regenerate_all覆盖或手动误操作)。 修复:从decisions.json重建holding_strategies表(INSERT 19条)。 **问题3 — 候选→自选提拔管道断裂:** market_insight.py存在UnboundLocalError(market_path变量未定义),知微洞察生成cron自6/19起报错停摆。另portfolio.json直读违规也在此文件中。 修复:market_path前置定义+改为DB读持仓。 **问题4 — 开盘race condition误报:** intraday_health_check在09:01检查价格新鲜度,price_monitor刚启动未完成首次更新。 修复:加09:00-09:10 grace period跳过检查。 **问题5 — 健康检查prompt检查JSON文件:** 「系统健康检查-开盘前」LLM cron prompt指示检查JSON文件是否存在,缺失时自动生成watchlist.json。 修复:prompt改为从DB检查数据完整性,明确禁止检查或修复JSON文件。 **涉及文件:** scripts/price_monitor.py, price_data_inject.py, market_insight.py, inspect_decisions.py, strategy_summary.py, fix_portfolio_prices.py, pre-flight-check.py, intraday_health_check.py cron prompt for 系统健康检查-开盘前 (job_id: 37c02f4d7df9) |analyst-knowledge-log.md (本文件) ## 2026-07-09 stale_push_wlin.py — 按Dad确认流程重构推送逻辑 **发现了什么:** - 推送流程没有重评冷却 — 每30分钟cron都调用per_stock_reassess重评同一批在买入区的股票 - Zone notes(进区间但不可操作的说明消息)冷却只有30分钟 → 太短 - 第582行 `if not actionable: return 0` 导致zone_notes为空时也早退,有区间说明时静默不发 - 标题和格式没有正确区分"有推荐操作"和"仅有区间说明" **修改了什么:** - 文件: `scripts/stale_push_wlin.py` - 加 `REASSESS_COOLDOWN_HOURS = 4` + `get_last_reassess_time()` / `is_due_for_reassess()` — 查DB holding_strategies.updated_at 决定是否跳过重评 - 重评调用前过滤:只对冷却期外的股票调 trigger_regen_sync() - Zone notes 冷却30分钟→4小时(匹配重评冷却) - 早退bug修复:`if not actionable and not zone_notes: return 0` - 标题自适应:有推荐→【知微】自选买入提醒 | 仅区间→【知微】操作区间提醒 |- 操作建议标题只在有可操作项时显示(`if actionable:`) ## 2026-07-09 xiaoguo_signal_consumer — 信号堆积修复 **发现了什么:** - 小果信号管道堆积33条未处理(阈值30),自愈系统报警 - 根因:xiaoguo_signal_consumer 的SQL用 `date(created_at)=today` 过滤,旧信号永远不被消费 - `SIGNAL_MAX_AGE_HOURS=4` 已定义但未被使用 - `mo_data.get_price` 导入在 cron 环境下失败(root mo_data.py 无 get_price,scripts/mo_data.py 有) **修改了什么:** - 文件: `scripts/xiaoguo_signal_consumer.py`, `scripts/intraday_health_check.py`, `scripts/system_audit.py`, `system_audit.py` 1. consumer: date(today) → created_at > -4h 年龄过滤(使用 SIGNAL_MAX_AGE_HOURS 常量) 2. consumer: 无时效内信号时自动标记过期信号为已处理(防堆积) 3. consumer: 修复 import 冲突 — 移除 mo_data.get_price,改用腾讯API直连 fallback 4. health_check/system_audit: 堆积检查也限定4h内 **效果预期:** - 过期信号不再堆积 → 健康检查正常 - 消费者只处理时效内信号 → 最新信号优先 - 无信号时自动清理过期堆积 → 不积压 - 区间说明格式改为: "→ 进入操作区间,但重评结果: {reason}"