# 知微分析师知识日志

## 2026-06-11

### 新增条目
- [BUG] 华恒生物688639 触发止损但 cron 报告里还显示"剩余空间很大"
  - 场景：2026-06-11 14:00 触发止损，策略状态已变
  - bug：cron_report 读 stale 数据 → 跟实际不一致
  - 修复：stale_push_wlin.py 加价格比对的权重

## 2026-06-29

### 修复
- [BUG] intraday_health_check.py 价格监控误报
  - 问题：check_price_monitor() 用 pgrep 查进程（price_monitor是no_agent cron，不是daemon，必然找不到） + 用 price_events 表做心跳检测（平静市场0事件=误报）
  - 表现：TODO #27 "cron无最近运行记录" + TODO #29 "进程不在运行" → 自愈执行器误启动LLM处理
  - 修复：改用 cron jobs.json 的 last_run_at（主指标）+ portfolio.json 的 updated_at（副指标）
  - 文件：intraday_health_check.py → check_price_monitor() 函数重写
  - 验证：手动执行 intraday_health_check.py → [SILENT] 盘中自检通过 | 6项正常
- [CLEANUP] 关闭残留TODO #27 和 #29（已自愈，价格监控正常）
- [BUGFIX] macro_context_collector.py 关键词红绿灯误报（33条HIGH→7条）
  - 问题1：'核'独立匹配触发22条误报（核聚变/硬核科技/核心等非风险词匹配）
  - 问题2：'苹果.*涨价'触发合作类新闻（苹果牵手长鑫存储，MLCC涨价→非风险）
  - 问题3：'英伟达|' 分组的alternation导致单"英伟达"关键词即触发（应该是英伟达+负面词才触发）
  - 修复：战争/核正则移除过宽匹配；苹果正则加合作类负向排除；英伟达正则修正分组
  - 效果：10:05的198条新闻测试：33 HIGH→7 HIGH（3条真实+2条MEDIUM级+2条分析文引用）
  - 文件：macro_context_collector.py → HIGH_PATTERNS (行30-61)

### 自愈
- [BUG] intraday_health_check.py 宏观风险HIGH TODO无详情
  - 问题：TODO #28 宏观风险HIGH 详情为空。intraday_health_check.py 读 risk.get("reason", "")，但 macro_risk_state.json 用 signals[].summary，没有 reason 字段 → reason始终为空
  - 修复：改成读 signals[0].summary 提取原因描述 + 增加 expired 标志检查（过期HIGH不报异常，改报⏳信息）
  - 文件：MoFin/scripts/intraday_health_check.py → check_signal_pipeline() 中宏观风险检查段
  - 验证：修复后运行 → [SILENT] 盘中自检通过 | 6项正常（不再因过期HIGH误报）

- [BUG] portfolio.json总资产计算错误 — 双重原因
  - 问题1：holding导入用了硬编码现金默认20,230，Dad截图现金73,758没用上
  - 问题2：import_holding_xls.py 对港股 double-conversion：券商的「最新市值」已经是人民币（shares × HKD价 × 汇率），脚本又做了 mv_cny = mkt_val × rate，导致港股市值少算约13.24%
  - 问题3：per_stock_reassess.py 更新了个股价格后，总资产没有随之更新（仍用导入时的旧值）
  - 修复：portfolio.json用 shares*price 重新求和（858,542）+ 现金73,758 = 总资产932,300
  - 文件：portfolio.json, import_holding_xls.py（去掉港股double-conversion + 去硬编码现金默认）
  - 经验：Dad的现金=截图现金，holding文件没有现金行。券商最新市值已经含汇率换算。

## 2026-07-01

### 修复
- [BUGFIX] macro_signal_consumer 修正覆盖信号仍导致level=high
  - 问题：LLM深度分析修正了采集器误报（写"修正覆盖"），但INSERT时保留了宏观-WATCH_HIGH sentiment。consumer聚合所有未处理信号时取最高级别→level=high，即使修正内容说"实际是MEDIUM"
  - 表现：state.json level=high但实际风险是MEDIUM。盘中自检持续产生"HIGH" TODO误报
  - 修复：consumer新增_effective_level()函数，检测"修正覆盖"摘要后取修正后的实际级别（HIGH→MEDIUM，零风险→INFO），不再只依赖sentiment字段
  - 文件：macro_signal_consumer.py → 聚合段新增_effective_level()逻辑
  - 配套：清理了state.json（恢复MEDIUM），关闭了残留TODO #39/#40
- [DOC] macro-risk-scanner SKILL.md修正原则补充
  - 修正时必须同时更新overall_sentiment为修正后的级别（不再保留HIGH）
  - 修正后的INSERT使用正确sentiment（如宏观-WATCH_MEDIUM）
  - 新增SQL示例展示错误vs正确做法
  - 文件：SKILL.md → 修正原则段 + LLM修正工作流段

### 修复
- [BUG] 个股行情数据来源不规范 — 海博思创266.02误读事件
  - 问题：2026-07-01 11:40对海博思创的分析中，我用了266.02作为当前价（实际265.00），并将K线描述为"光头光脚阴线"（实际是长下影线，低点248.68）。266.02来自新浪原始CSV的ask2字段（第二档卖盘价），被我误读为当前价
  - 根因：没有统一的权威价格源。LLM有时读portfolio.json、有时读decisions.json、有时直接解析原始API——解析CSV时字段极易混淆
  - 修复1（脚本级）：创建 stock_quote.py — 统一行情查询工具。自动识别A股/港股，按东财→新浪→腾讯优先级获取，自带验证（price在[low,high]内，change_pct自洽）。输出结构化JSON，LLM禁止解析原始API
  - 修复2（管道级）：mofin_collect.py 增加 stock_quote.py --all-holdings 注入步骤。每个cron分析前自动注入持仓行情数据，LLM只需读注入数据
  - 修复3（记忆级）：增加"数据来源铁律"记忆条目——输出价格前必须验证
  - 文件：新增 MoFin/scripts/stock_quote.py，修改 mofin_collect.py（加步骤4），新增记忆条目
  - 原则：用脚本固定规范，不依赖LLM"随机遵守"
### 审计
- [AUDIT] 全系统"脚本强制规范"覆盖审计
  - 结果：开盘简报✓ 收盘简报✓ MoFin盘前中监控✓(已在mofin_collect中注入stock_quote) MoFin午后监控✓
  - 违规：策略评估-每日(stale_detector.py直接调用腾讯API) ✗ → 已修复：改调stock_quote.py，原腾讯API降级为兜底
  - 违规：策略评估SKILL.md写"数据源：腾讯API实时行情" ✗ → 已修复：改为"数据源：decisions.json/stock_quote.py"
  - 违规：芯片微装-价格监控prompt未指定数据源 ✗ → 已修复：添加"数据源铁律：从decisions.json或stock_quote.py获取"
  - 不修复：price_monitor.py是no_agent脚本，直接写portfolio.json供LLM读，不经过LLM解析，风险可控
  - ⚠️ 补充审计（12:21）：此前标记「已修复」的 stale_detector.py 实际未改——代码仍直接调腾讯API qt.gtimg.cn。已重新修复：fetch_prices() 优先调 stock_quote.py，腾讯API降级为兜底fallback
  - 验证：stale_detector.py 当前运行输出正常（芯碁微装521.12 -5.15%、中钨高新95.86 +0.15%等），数据来源已切换至stock_quote.py
  - .pyc 回收规范验证：仅 macro_context_collector.py 有 .pyc 缓存（已清除+加固完整性校验），其余脚本 __pycache__ 为空

## 2026-07-01

### 修复: macro_context_collector.py .pyc缓存过期导致误报复发

发现: self-healing executor 报告 12:00 采集器误将 KOSPI -1%（正常日内波动）和基金经理展望（正面评论）判为 HIGH 宏观风险。

根因: .pyc 缓存过期。当前 .py 的 HIGH_PATTERNS 已包含"指数+跌幅≥2%"阈值和"指数+暴跌词"强词检测，但 cron 运行时 Python 加载了过期 .pyc（旧版模式），导致 KOSPI -1% 依然匹配旧版"指数.*跌幅"模式。

修改:
1. 删除 `__pycache__/` + touch `.py` — 强制重新编译
2. 《macro_context_collector.py》加固模式完整性校验 _PATTERN_CHECKS:
   - 新增 index 8 检查: 必须包含"暴跌|熔断|闪崩|重挫"（禁止"跌幅"弱词命中）
   - 新增 index 9 检查: 必须包含"[2-9]%"（禁止 1% 正常波动触发）
   - 新增 _KNOWN_BAD_SIGS 旧版签名扫描: 检查"指数.*跌幅""|核|""英伟达|nvidia.*跌""导弹.*发射"是否残留
3. 清除 stale macro_risk_state.json（level=high→expired）
4. 关闭 TODO #41

验证: 三条误报标题在修复后均不触发 HIGH 匹配。

## 2026-07-02 修复：intraday_health_check.py 盘中自检三项BUG

**发现的问题：**
1. 缺少 `sys.path.insert(0, "/home/hmo/MoFin")` → `from mo_data import ...` 报 `ModuleNotFoundError: No module named 'mo_data'`（自愈执行器报告为 "name 'mo_data' is not defined"）
2. `check_xiaoguo()` 里 `urllib.request.urlopen("http://node122:18003")` 在主机不可达时无限hang住（TCP SYN被防火墙丢，Python timeout失效），导致整个盘中自检超时
3. `datetime.strptime` 格式 `"%Y-%m-%d %H:%M"` 与 `read_portfolio()` 返回的 `updated_at`（含秒：`"%Y-%m-%d %H:%M:%S"`）不匹配 → 解析Exception

**修改内容：**
- `/home/hmo/MoFin/scripts/intraday_health_check.py`
  - 添加 `import socket` 和 `sys.path.insert(0, "/home/hmo/MoFin")`
  - `check_xiaoguo()`: 用 `socket.settimeout(3)` 替换 `urllib` HTTP检查，防止hang死
  - `check_price_monitor()`: 将 `strptime` 格式从 `"%Y-%m-%d %H:%M"` 改为 `"%Y-%m-%d %H:%M:%S"`
  - `check_http()`: 默认timeout从8秒降至5秒（加强健壮性）

**效果预期：**
- 盘中自检不再因 `mo_data` 导入失败而报错
- 盘中自检不再因 `node122` 不可达而超时hang死
- 价格新鲜度检查正确解析 `updated_at` 时间戳
- 相关TODO（#48, #52）已标记resolved

**发现的问题：**
1. price_monitor.py 的 refresh_data_prices() 在 DB 持仓价格为 NULL 时崩溃。`s.get('price', 0)` 在 key 存在但值为 None 时返回 None（不是 0），导致 `abs(None - price)` 触发 TypeError。
2. 港股备用通道(fetch_hk_eastmoney_fallback)每只港股有 1 秒 delay，09:30 开盘前港股 API 返回 0 价格，全部 HK 股票走降级通道空耗 ~14 秒。
3. Hermes cron 版（profile/scripts/price_monitor.py）与系统 crontab 版（MoFin/price_monitor.py）并存，系统 crontab 每次运行会覆盖 JSON 文件。

**修改内容：**
- `/home/hmo/.hermes/profiles/position-analyst/scripts/price_monitor.py`
  - 第 335-337 行：`old = s.get('price'); if old is None: old = 0` — 处理 DB NULL 价格
  - 第 377-379 行：同上，watchlist 更新部分
  - 第 305-311 行：港股降级通道增加 09:30 开盘检查，开盘前跳过

**效果预期：**
- Hermes cron 版 price_monitor 不会再因 NULL 价格崩溃，DB 已更新 11 只 A 股持仓价格
- 港股开盘前不会再空耗 14+ 秒走东财降级通道
- 盘中健康检查下次运行时将看到新鲜数据，不再误报
