Files
MoFin/docs/analyst-knowledge-log.md
知微 7c0e85af28 硬性策略质量门禁 validate_strategy()
新增 STRATEGY_QUALITY_GATES 检查清单(9条红线):
CRITICAL: 止损/止盈存在+>0, 买入区下沿<上沿
HIGH: 止损≤买入区, 买入推荐含RR≥1.5, 港股标currency=HKD
MEDIUM: signal短词, tech_snapshot含技术位

enforce_strategy_quality() 插在写入链的两处:
1. reassess_with_context() return前 → 单只重评必过
2. regenerate_all() for d in decisions: 写DB前 → 批量重评必过

不过的:status=review_needed, signal降级→信号不充分
不会写进DB/JSON,除非修复了CRITICAL问题
2026-07-02 13:46:53 +08:00

133 lines
10 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.
# 知微分析师知识日志
## 2026-06-11
### 新增条目
- [BUG] 华恒生物688639 触发止损但 cron 报告里还显示"剩余空间很大"
- 场景:2026-06-11 14:00 触发止损,策略状态已变
- bugcron_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 HIGH3条真实+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没用上
- 问题2import_holding_xls.py 对港股 double-conversion:券商的「最新市值」已经是人民币(shares × HKD价 × 汇率),脚本又做了 mv_cny = mkt_val × rate,导致港股市值少算约13.24%
- 问题3per_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自洽)。输出结构化JSONLLM禁止解析原始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.jsonlevel=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 秒 delay09: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+ 秒走东财降级通道
- 盘中健康检查下次运行时将看到新鲜数据,不再误报