Files
MoFin/docs/analyst-knowledge-log.md
T
知微 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

10 KiB
Raw Blame History

知微分析师知识日志

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 socketsys.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+ 秒走东财降级通道
  • 盘中健康检查下次运行时将看到新鲜数据,不再误报