fix: 批量修复76只自选rr_ratio改回candidates.rr(scanner定)——strategy_lifecycle重锚定覆盖的错值
This commit is contained in:
@@ -1,3 +1,38 @@
|
||||
## 2026-08-18 08:26 news_collector_full 并发版静默丢数据(8/15起全市场新闻零入库,已提单+补采)
|
||||
|
||||
**发现了什么:** 盘前全市场新闻采集 batch5 报"501/502 ok, fail=0, 新增 0 条",但实测东财 search-api 同参数返回今日新闻(000001/300750/002594 has_today=True)。数据库 stock_news 按 created_at:08-13=4189, 08-14=1253, 08-15=0, 08-16=0, 08-17=0(全市场部分),08-18=0。根因:`news_collector_full.py`(commit ff6bfe4f,08-14 11:31 部署并发版,deploy 与 profile 硬链接同 inode 41281)——`sqlite3.connect()` 默认 check_same_thread=True,`cur` 在主线程创建,ThreadPoolExecutor(3) worker 线程调 `cur.execute()` 必抛 ProgrammingError,被内层 `except Exception: pass` 吞掉 → n 恒 0、fail 不增、ok 照加 → 日志全绿但数据全丢。已用 /tmp/thread_test.py 复现(RESULT: [('throw','ProgrammingError',...)])。注意 pool_news_collector.py(串行)不受影响,08-17 池子 366 条正常入库。
|
||||
|
||||
**修改了什么(自愈 + 提单,未改 MoFin 代码):** ① 提单 t_1942eabb(assignee=xiaoxiao/小小莫,已通知 coregroup):建议最小修复 = sqlite3.connect(check_same_thread=False)+threading.Lock 包写库,或"抓取并发+主线程串行写"。② 自愈:内联脚本 /tmp/news_backfill.py(fetch 3线程并发 + 主线程单连接串行写,只存近3天,INSERT OR IGNORE 幂等)后台全量补采 4015 只;实测 200 只新增 189 条,写库路径验证有效。
|
||||
|
||||
**效果预期:** 补采完成后 08-15~08-18 全市场新闻缺口闭合,p_oversold news3 因子恢复。正式修复落地前,盘后 16:40-16:55 4 批 cron 仍会 0 新增(静默丢数据),属已知状态。
|
||||
|
||||
**经验:** 「ok 高 + fail=0 + 新增=0」≠ 正常——先看 DB 的 created_at 分布和 MAX(date) 是否推进,再实测数据源 API,不要被脚本自报的完成指纹骗过。并发版改 sqlite 必须处理线程归属(check_same_thread=False + lock 或每线程独立连接)或直接串行写。
|
||||
|
||||
## 2026-08-17 10:35 b_td1_v3_scanner 09:30 traceback(小小莫当日已修复 + 补跑验证)
|
||||
|
||||
**发现了什么:** 09:30 温区策略调度器执行 b_td1_v3_scanner.py 时 stderr 出现 Traceback(调度器只截 200 字符,根因需复现)。对照 git 时间线定位:09:33 commit `057fdd23`(小小莫)正是修「scanner all_stocks 纯code解包bug——b_td1_v3/s2_panic_v2 实盘扫描不再崩」,即 09:30 运行时用的是修复前版本(`for code, name in all_stocks` 对纯 code 列表解包 → ValueError),09:30 轮次 0 候选入库。09:50 commit `1163d0cc` 又修 mcap_quantile(stock_daily.amount 为 None 全返回 0.3 被池条件挡掉 → 0 候选根因,改 stock_fundamentals.mcap_total)。当前工作区 = git HEAD = 修复后版本(deploy 与 profile 硬链接同 inode 42036,diff IDENTICAL)。
|
||||
|
||||
**修改了什么(自愈,非 MoFin 代码):** 手动补跑 `python3 b_td1_v3_scanner.py`(修复后版本),扫描 4013 只完成,命中 5 只并写入 candidates(sector=b_td1_v3,10:33:28):300668(score57)/300836(57)/688089(57)/002514(47)/002856(47)。stock_fundamentals 数据可用(6154 行,07:52 更新)。下一轮调度 10:30 起会用修复版自动跑。
|
||||
|
||||
**经验:** ① 调度器 strategy_executor.run_scanner 不检查 returncode、stderr 只截 200 字符,scanner 崩溃时调度日志显示「✓ 完成」+ 截断 traceback,掩盖真因——查错时先看 git log 当日 commit(修复往往已经提交)。② 9:30 扫描崩 → 该轮候选缺失 → 手动补跑即可恢复当日数据,无需等下一轮。③ deploy_guard 07:30 曾回滚 b_td1_v3_scanner.py 未入库改动(当日多次 commit 已入库,回滚后与 HEAD 一致,无残留)。
|
||||
|
||||
## 2026-08-14 17:00 market_regime.py 路径解析导致 cron 连库失败(自愈 + 提单)
|
||||
|
||||
**发现了什么:** cron 任务 `market_thermometer_daily`(市场测温-每日)16:50 运行失败:
|
||||
`sqlite3.OperationalError: unable to open database file`(market_regime.py:119 compute_regime)。
|
||||
根因:market_regime.py L38-44 用 `__file__` 相对推导 `_MOFIN_ROOT = _SCRIPT_DIR.parent.parent`;
|
||||
cron 从 profile scripts 目录调用(`__file__ = ~/.hermes/profiles/position-analyst/scripts/market_regime.py`)时
|
||||
`_MOFIN_ROOT` 被算成 `~/.hermes` → DB_PATH=`~/.hermes/data/mofin.db`(不存在)→ 打不开。
|
||||
MoFin/deploy/profile-scripts 下同 inode 正本(inode 41228)路径解析正确,实测正常。
|
||||
|
||||
**修改了什么(自愈,非 MoFin 代码):**
|
||||
- 新增文件: `~/.hermes/profiles/position-analyst/scripts/market_regime_runner.sh`
|
||||
包装器 `exec python3 /home/hmo/MoFin/deploy/profile-scripts/market_regime.py "$@"`,让 `__file__` 解析为 MoFin 路径。
|
||||
- cron `market_thermometer_daily` script 字段: `market_regime.py` → `market_regime_runner.sh`(`hermes cron edit`,jobs.json 已更新)。
|
||||
- 已提单 t_70d95de2(assignee=xiaoxiao/小小莫):持久修复建议 market_regime.py 改用绝对路径 `/home/hmo/MoFin/data`(与 mofin_db.py 一致),并排查其余含 `parent.parent/data` 模式的脚本(advice_reconciliation / collect_evaluation_data / market_insight / market_watch / mofin_collect / stock_sector_enrich / strategy_evaluator / strategy_feedback / strategy_lifecycle / trend_detector)。
|
||||
|
||||
**效果预期:** 包装器实测输出 `[market_regime] 2026-08-14 → trend_up (above_ma20=True adx=22.95 slope=0.283 roc=2.473)`;下次 cron(08-17 16:50)不再报错。持久修复落地后包装器可保留(无害)或 cron 改回原 script 名。
|
||||
|
||||
## 2026-07-19 20:58 XMPP bot on_disconnect 递归重连修复
|
||||
|
||||
**发现了什么:** zhiwei XMPP bot 从 20:53:57 开始反复输出 "XMPP 断开" × 27次,最后 "重连失败: maximum recursion depth exceeded"。slixmpp 的 `reconnect()` 在连接失败时会再次触发 disconnect 事件,而 `on_disconnect` 无条件调用 `reconnect()`,形成无限递归。
|
||||
@@ -331,3 +366,141 @@ cron prompt for 系统健康检查-开盘前 (job_id: 37c02f4d7df9)
|
||||
1. KOSPI熔断+日韩暴跌传导至A股科技股,但上证/恒指未破位=非系统性+板块冲击。判断A股的不可一概而论。
|
||||
2. 比亚迪、腾讯在科技暴跌日逆势上涨,说明个股基本面>板块情绪。不能简单用"科技股暴跌"标签覆盖所有科技持仓。
|
||||
3. 自愈执行器重复报警的根本原因是state文件expired后未及时更新,导致管道认为这是未处理的新问题。修复措施:更新state文件。
|
||||
|
||||
## 2026-08-14 11:51 宏观风险HIGH 第十三实例(TODO#274)— OpenAI/美联储鹰鸽 误报
|
||||
|
||||
**发现了什么:**
|
||||
11:31 采集器写入 ID=1891 原始 HIGH(3条信号:OpenAI IPO前年化营收400亿美元 / 美联储内部鹰鸽对峙升级 / 华尔街大行分歧难消),11:45 盘中自检创建 TODO#274。11:51 收到执行器推送处理。
|
||||
|
||||
**处置证据链:**
|
||||
- ID=1891 3条信号逐条复核均为已知误报向量:①OpenAI营收=正面AI叙事(同8/11 medium先例,无下跌链路降info)②美联储鹰鸽/大行分歧=利率预期分歧类(同8/14 ID=1889→1890 先例判INFO)
|
||||
- state level=none expired=true(11:45 consumer 过期),divergence none bias=opportunity
|
||||
- 市场实况(Tencent 直连):上证3918.65/-0.21% 深成14300.46/+0.08% 恒指25164.70/-0.91%,无系统性下跌
|
||||
- 当日 unassessed 97条清扫:风险词 SQL 命中6条 → 3 medium(36167航母调动/36188美债/36200关税反制,真实传导链)+ 3 info + 91 bulk info,unassessed 清零(433 info/23 medium)
|
||||
- 修正覆盖 ID=1892 已写入 signal_news,TODO#274 SELECT 验证 status='completed'
|
||||
|
||||
**LLM评估cron连续第二日 provider 失败(确认同根因):**
|
||||
agent.log 显示 cron_7c23d51dd69f 今日 08:30:36 正常触发(cron_7c23d51dd69f_20260814_083036),但反复 `Stream stale for 180s — no chunks received` + `RemoteProtocolError (incomplete chunked read)`,provider=opencode.ai/zen/go/v1 (deepseek-v4-flash)。与 8/13、8/14 第十二实例完全同型。输出目录无当日宏观评估 .md。**判别:不是调度器缺失,是 provider 流式连接层连续两日不稳定。** 已用 agent 手动闭环兜底(ID=1892),连续多日失败需评估 provider 健康/备源(可考虑提单给小小莫)。
|
||||
|
||||
**萃取知识:**
|
||||
1. OpenAI 营收类正面 AI 叙事新闻命中 HIGH_PATTERNS 是持续误报源(8/14 已两次出现:ID=1888/1891)
|
||||
2. 美联储鹰鸽/利率预期分歧类新闻(无实质政策变化)统一判 INFO,与 CME 利率调查类同型
|
||||
3. 参考文档复用要点第8条再次验证:TODO note 含「调用知微失败」= 执行器重试变体;知识日志 ≠ DB 落库,必须先 SELECT 再 UPDATE 并验证
|
||||
4. 脚本内 f-string 含百分号+%d 混合格式化会 TypeError 导致 commit 前中断——批量 SQL 脚本先单独测格式化,或用 .format()/f-string 内嵌变量
|
||||
|
||||
## 2026-08-14 17:20 策略失效预警-每周 首次正式运行(strategy_alert_weekly)
|
||||
|
||||
**发现了什么:**
|
||||
strategy_alert.py 每周五 17:00 三振出局预警首次正式运行(cron 创建于 8/13,首跑 8/14)。结果与 8/13 决策文档实测一致:v_weak 红牌确认(滚动90日胜率 22.8% < 30%,698笔,盈亏比 1.70 尚可但胜率崩溃)→ weight=0 淘汰观察;v_oversold 数据不足无法评估(strategy_research 近90日窗口内 <5 笔)→ weight 保持 1.0。
|
||||
|
||||
**修改了什么:**
|
||||
无代码改动。strategy_alerts.json 已写入(SSOT 两份脚本一致)。仅记录解读要点。
|
||||
|
||||
**萃取知识:**
|
||||
1. 失效预警数据源 = strategy_research(滚动90日回测窗口),与 strategy_router 的 strategy_regime_perf(按温区聚合)是两套口径——v_weak 在 regime_perf 里 trend_down 胜率 47.5%(2750笔)看着正常,但滚动90日 22.8%(698笔)暴露近期崩溃。报告/解读时以滚动90日为准(更贴近当下)。
|
||||
2. v_oversold 近90日无交易 = 结构性牛市信号枯竭的正常表现(其最近回测交易 7/9),不是数据故障;router 里它仍 active(trend_down 60.4%胜率、106笔)。
|
||||
3. 机制确认:红牌只降权观察(weight=0 保留),不删除策略;胜率回升至 40%+ 自动恢复。符合「三振出局不是IC掉到负就删」原则。
|
||||
|
||||
## 2026-08-17 08:35 宏观早盘扫描-周一(macro-risk-scanner 08:30 slot)
|
||||
|
||||
**发现了什么:**
|
||||
周一早盘 08:30 slot 承接整个周末的采集器累积:清扫范围(上界=8/14 12:41 综合评估 ID=1893 之后)共 42 批次 1564 条 unassessed 新闻 + 24 条未消费采集器信号(20 HIGH + 4 MEDIUM)。
|
||||
|
||||
**修改了什么:**
|
||||
1. 批量修正 24 条采集器信号 → 5 MEDIUM + 19 INFO(未处理 HIGH=0)。核心判定:美联储 9 月维持利率不变概率 66.9-67.5% = P11 常规概率数据(非鹰派紧缩渠道,区别于 8/5 的加息概率>50% 场景);伊朗/胡塞/以色列地缘延续无新升级维度(伊美谅解备忘录+伊央行行长访伊+伊拉克原油出口创海峡封锁新高=降级锚);三川智慧华为/P4、OpenAI 高层震荡(公司级,P25 类但未上市无直接暴露)、阿富汗资产、巴西法官制裁均为误报/无关;厄尔尼诺+粮食危机=长期慢变量监控渠道(2027 时间尺度)。
|
||||
2. raw_news 全量三遍法清扫:info 优先 744 + medium 134 + bulk 686 = 1564 条,42 批次全部 unassessed=0,宽范围验证(-3 day)0 漏网,medium 后置抽查 0 误标。
|
||||
3. INSERT 综合评估 ID=1920(宏观-WATCH_MEDIUM,置信度 75%)。consumer 09:05 首轮消费后 state 保持 medium 且内容更新为综合评估。
|
||||
|
||||
**萃取知识:**
|
||||
1. 周末(8/15-8/16)采集器继续运行产信号——即使休市也保持 30 分钟一轮,周一早盘必然面对 20+ 条未处理信号,批量修正必须按「同主题保留首条 MEDIUM、重复并入 INFO」压缩信号总线,否则 consumer 聚合时 13 条 MEDIUM 噪声堆积。
|
||||
2. 美联储概率数据连续多日出现在采集器 HIGH 池(8/15 67.5%、8/17 66.9%)——「维持利率不变概率」是 P11 常规数据,只有「加息概率>50%+鹰派官员表态+美债收益率狂飙」组合才算真实紧缩渠道(8/5 先例),本次无该组合。
|
||||
3. 周末美股结构分化(博通-6.7% vs 闪迪+7%/Lumentum+8.6%)说明 AI 板块内部轮动而非系统性下跌——VIX 年内低位是重要锚定信号,避免被单只个股暴跌标题误导。
|
||||
|
||||
## 2026-08-17 11:15 strategy_executor 11:00 轮超时(b_td1_v3_scanner 孤儿化)
|
||||
|
||||
**发现了什么:**
|
||||
strategy_executor_30min 11:00 轮脚本 600s 超时被杀(cron 错误报告触发本次会话)。b_td1_v3_scanner.py 子进程未随父进程死亡,孤儿化继续运行 11 分钟(28% CPU),直至手动 kill。09:28/09:30 的崩溃(all_stocks 解包 bug)小小莫已修(057fdd23/1163d0cc),但修复版暴露运行时预算不匹配:全市场 4013 只**串行** fetch_tx_klines 实测 215ms/只 → 全量扫描 13-14 分钟 > executor 每扫描器 600s 超时 = cron harness 600s 总预算。10:33 补跑成功仅因直跑无超时;10:38 轮报告预判「下一轮自动 OK」不成立。同轮 mr_scanner/s2_panic_v2 排在 b_td1 之后均未执行(当前因 ADX/RSI 门控跳过,无功能损失)。
|
||||
|
||||
**修改了什么:**
|
||||
1. 手动 kill 孤儿进程 PID 3351899(无 DB 写入,无数据丢失)。
|
||||
2. kanban 提单 t_b27ad65f(指派 xiaoxiao):主修 b_td1_v3_scanner 并发化(ThreadPoolExecutor 16 线程,14min→~1.5min);辅修 strategy_executor.run_scanner 检查 returncode + 超时降为 480s 防孤儿 + 完整 stderr 落盘。
|
||||
3. 确认 b_td1_v3 今日候选 5 只在库(10:33:28 写入,已富化),当前无损失。
|
||||
|
||||
**萃取知识:**
|
||||
1. subprocess.run(timeout) 只保护子进程被**自己**清理;若外层 harness 先于内层超时杀父进程,子进程必然孤儿化。调度器每子任务超时必须 < 外层总预算(600s),且孤儿要能被 kill。
|
||||
2. 全市场串行网络抓取是定时器杀手的标准形态:4013 只 × 215ms = 14min,任何 600s 预算必爆。凡全市场扫描器必须并发化或走日K库,不能裸串行。
|
||||
3. 「崩溃修复」与「运行时预算」是两个独立故障层:09:33 修了解包崩溃,11:00 才暴露扫描时长超预算——修复后必须用真实全量跑验证耗时,不能只验证不崩。
|
||||
|
||||
## 2026-08-17 14:38 14:30 轮双扫描器写库 database is locked(整点并发锁竞争)
|
||||
|
||||
**发现了什么:**
|
||||
14:30 整点并发窗口(20+ job 同时启动)下,温区调度器内两个扫描器同时在**写库阶段**崩溃:
|
||||
- b_td1_v3_scanner.py:222 `sqlite3.OperationalError: database is locked`(rc=1,14:31:25,扫描已完成命中5只)
|
||||
- accumulation_scanner.py:233 同款 `database is locked`(job 2d18076b1fa6,rc=1,14:31:22,扫描已完成发现273只特征)
|
||||
|
||||
两者都是扫描**完成**后写 candidates 表时撞锁,不是扫描逻辑问题(新版本地预筛 28s 内跑完,性能达标)。根因是 DB 并发写竞争:MoFin/data/mofin.db 是 WAL 模式但 busy_timeout 未设,各脚本 conn 参数不一(accumulation_scanner.py:211/72 裸 connect 无 timeout;b_td1_v3_scanner.py:217 timeout=10 仍不够;candidate_filter/promote_candidates 用 timeout=30 相对安全)。14:30:56-14:33:37 窗口 20+ job 并发启动(candidate_filter/promote_candidates/market_collect/accumulation/b_td1/宏观/自检…),WAL 写-写互斥 + busy 等待到期 → OperationalError。
|
||||
|
||||
**修改了什么:**
|
||||
1. 14:38 手动补跑 b_td1_v3_scanner → 002395 落库 ✓(candidates 表 b_td1_v3 现有 15 条)
|
||||
2. 14:38 手动补跑 accumulation_scanner → 688798/688708/688697 reason 更新 ✓(ON CONFLICT 不刷 created_at,时间戳保留首次入库)
|
||||
3. kanban 提单 t_a44b6e16(指派 xiaoxiao):两个 scanner 写库 conn 统一加 timeout=30(或 PRAGMA busy_timeout=30000)+ 简单重试包装,参考 macro_signal_consumer.py 的 db_update 重试助手。属代码层修改,MoFin git 写权限已撤销,需小小莫落地。
|
||||
|
||||
**萃取知识:**
|
||||
1. **整点/半点是 SQLite 写锁事故高发窗口**(14:00/14:30/15:00 等 20+ job 同时启动,多 job 写同一张 candidates 表):凡写 MoFin/data/mofin.db 的扫描器,conn 必须显式 timeout=30+(或 DB 级 busy_timeout 持久化),裸 connect(默认 5s)在并发窗口必挂。WAL 模式只解决读写并发,写-写仍互斥。
|
||||
2. **「扫描完成但写库崩」的指纹**:scanner stdout 有完整扫描进度+命中列表,但无「✅ 新增 N 只候选」行,且 cron last_status=error 带 OperationalError: database is locked——此时重跑一次即可恢复(幂等 UPSERT),不必等下一轮调度。
|
||||
3. ON CONFLICT DO UPDATE 不更新 created_at 列:补跑后同一 code 的 created_at 保留首次入库时间,判断「是否补跑成功」要看 reason 是否更新,不能只看 created_at 新鲜度。
|
||||
|
||||
## 2026-08-17 15:15 15:00 轮 b_td1_v3_scanner 写库 database is locked(整点锁竞争复发)
|
||||
|
||||
**发现了什么:**
|
||||
15:00:59 温区调度轮 b_td1_v3_scanner.py 再次崩在写库阶段:`sqlite3.OperationalError: database is locked`(line 96 conn.execute INSERT INTO candidates,rc=1,15:01:09)。与 14:30 轮(陷阱31/whole-hour-write-lock-crash-20260817.md)同指纹:扫描已完成(SQL扫描命中 1 只 score降序前5)→ 缺「✅ 新增」收尾行。mr_scanner/s2_panic_v2 正常(ADX/RSI 门控跳过,非故障)。**与 14:30 轮不同的是锁窗口更长**:15:07 手动补跑仍失败(锁未释放),15:13 起 sqlite3 BEGIN IMMEDIATE 写测试连续 3 次通过,锁实际持续约 12 分钟(15:01~15:13)——比 14:30 轮(几分钟)更长,说明收盘后仍有长写事务持有者(pool_news_collector PID 3644847、price_monitor PID 3654869 均持有 mofin.db 句柄;lsof 未见 wal/shm 独立写者)。
|
||||
|
||||
**修改了什么(自愈,非 MoFin 代码):**
|
||||
1. 确认工单 t_a44b6e16(统一 conn timeout=30 + 写库重试)仍在途(ready, assignee=xiaoxiao),不重复建单。
|
||||
2. 15:13 锁释放后手动补跑 b_td1_v3_scanner → `✅ 新增 1 只 b_td1_v3 候选`:002395(价12.35 score=60 dist_lo20=8.33% bias60=-21.75% rsi=36.36)。reason 已更新(created_at 保留 14:34:28 首次入库,符合陷阱31验证规则)。
|
||||
3. b_td1_v3 候选现 15 只在库,当日数据完整。
|
||||
|
||||
**萃取知识:**
|
||||
1. 整点锁竞争复发是预期内(工单落地前每轮调度都可能再撞);但**锁窗口可达 10+ 分钟**,补跑失败≠补跑无效,应先验证写锁(sqlite3 BEGIN IMMEDIATE 测试)再重试补跑,锁释放后 30s 内可完成恢复。
|
||||
2. 补跑失败的场景下不必 panic:扫描器是幂等 UPSERT,锁释放后重跑即可,无需等下一轮调度。
|
||||
3. 持久修复(timeout=30/重试包装)已在 t_a44b6e16 工单在途,本条目与 14:38 条目合并为同一根因的两个复发实例。
|
||||
|
||||
## 2026-08-18 自愈执行器8个STRATEGY_STALE重评TODO全部失败:fix_action硬编码旧路径 scripts/per_stock_reassess.py
|
||||
|
||||
**发现了什么:**
|
||||
自愈执行器升级 TODO #279 [STRATEGY_STALE] 阿里健康(00241) 需重评,fix_action=`cd /home/hmo/MoFin && python3 scripts/per_stock_reassess.py 00241`,失败输出 `python3: can't open file '/home/hmo/MoFin/scripts/per_stock_reassess.py': No such file or directory`。共 8 个 STRATEGY_STALE TODO (#279-286: 阿里健康/金蝶国际/小米/理想/苏农银行/传音/道通/联影) 全部使用重构前的旧路径 scripts/,执行器全部失败升级。根因:2026-07-20 重构后 per_stock_reassess.py 从 scripts/ 移到 deploy/profile-scripts/,但生成 TODO fix_action 的代码 strategy-staleness-check.py:213 仍硬编码旧路径 `f"cd /home/hmo/MoFin && python3 scripts/per_stock_reassess.py {code}"`(profile-scripts 与 git 仓库硬链接同 inode 41335;skill 记载的 2026-07-27 修复未持久,疑似被 deploy_guard 回滚)。
|
||||
|
||||
**修改了什么(自愈,非 MoFin git 代码):**
|
||||
1. 存量数据修复:`UPDATE todos SET fix_action=REPLACE(fix_action,'python3 scripts/per_stock_reassess.py','python3 deploy/profile-scripts/per_stock_reassess.py')` 影响 27 行(含历史记录)。
|
||||
2. 8 个 STRATEGY_STALE TODO 标记 completed——核实这 8 只股票均已被 2026-08-18 09:03~09:04 的盘前全量重评覆盖(reassessed_at 已刷新),策略新鲜无需重复重评;用正确路径重跑 00241 时被冷却期正确跳过(09:03 重评过,交易时段冷却 1h)。
|
||||
3. TODO #287(宏观风险HIGH)标记 resolved——macro_risk_state.json 现为 level=medium,原 HIGH 信号 ID1933/1934/1935 已由 8/18 08:30 综合评估修正覆盖降级为 MEDIUM/INFO,无确认 HIGH,属「宏观风险自然过期」变体。
|
||||
4. kanban 提单 t_1310bbdb(assignee=xiaoxiao):修 strategy-staleness-check.py:213 硬编码旧路径。建议改为 `f"cd /home/hmo/MoFin && python3 deploy/profile-scripts/per_stock_reassess.py {code}"`(与 mofin_db.py:1746 参照一致)。因该文件被 git 跟踪+deploy_guard 保护,代码层修复须小小莫落地,否则下次 cron 周期仍生成错误路径 TODO。
|
||||
|
||||
**萃取知识:**
|
||||
1. 重构变更脚本路径时,必须审计「生成 TODO fix_action 的代码」+「已存储在 todos 表的存量 fix_action」两处(generator 代码 + DB 存量),只改一处会留半截。与 skill back-through-#174 一致。
|
||||
2. STRATEGY_STALE TODO 描述的是「某一时刻的策略过期快照」,可能已被更早的盘前全量重评覆盖——处理前先查 holding_strategies.reassessed_at 是否新鲜,新鲜则直接 completed(问题已自愈),不必重复跑重评。
|
||||
3. strategy-staleness-check.py:213 是「skill 记载已修复但代码未持久」的重复案例(2026-07-27 记载→实际回滚)——凡被 deploy_guard 保护的 git 文件,profile 直改无法持久,必须提单小小莫。
|
||||
|
||||
## 2026-08-18 09:30 b_td1_v3_scanner 写库崩溃(database is locked,整点并发窗口复发实例)
|
||||
|
||||
**发现了什么:** 09:30 温区调度器执行 b_td1_v3_scanner.py(v4 纯 SQL 版,2026-08-17 上线),SQL 扫描命中 5 只(score 降序前5),但在写 candidates 表时崩 `sqlite3.OperationalError: database is locked`(traceback line 98 撞在 INSERT 循环/commit 处)。同批 mr_scanner/s2_panic_v2 正常(regime=trend_down + 大盘RSI=51 非恐慌日,各自跳过,非故障)。09:30 并发窗口有 price_monitor.py 与 pool_news_collector.py 同时在跑,写-写在候选表互斥(WAL 只解读写并发)。崩溃后 b_td1_v3 当日候选缺失(此前最新是 08:12 的 7 只)。
|
||||
|
||||
**修改了什么(自愈,非 MoFin 代码):** 验证 write lock(`BEGIN IMMEDIATE; SELECT 'ok'; COMMIT;`)——09:32 前仍 locked(符合陷阱32 锁窗口可达10+分钟的规律),09:32 wal checkpoint 后 3 连测 ok 释放。手动补跑 `python3 b_td1_v3_scanner.py`,幂等 UPSERT 30s 内完成,落库 5 只(600262/603585/603811/003002/603105,score 60-74)。验证看 reason 字段被新值覆盖(非 created_at,因 ON CONFLICT 不更新 created_at)。
|
||||
|
||||
**经验:** 与 08-17 14:30/15:00 两轮同根因(t_a44b6e16 在途,不重复建单)。整点/半点并发窗口 scanner 写库崩 = 瞬时锁,补跑即恢复;锁窗口可能 >10 分钟,先验锁再重试,不要反复重跑制造写竞争。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## [2026-08-18 10:00] b_td1_v3_scanner 撞锁重试二次崩溃(NameError缺import time)
|
||||
|
||||
**发现了什么:** 整点(10:00)调度 b_td1_v3_scanner.py 崩溃(rc=1),两个连锁bug:
|
||||
1. SQL扫描命中5只后写 candidates 撞 `database is locked`(与 t_a44b6e16 / 08-17 同根因,整点并发窗口)
|
||||
2. **新增二次bug**:line 98-117 今天新加的重试退避代码,line 115 调 `time.sleep()` 但顶部 line 12 只 `import sys, sqlite3`,未 `import time` → `NameError: name 'time' is not defined` → 即使锁释放重试也永远崩溃,候选0产出。
|
||||
|
||||
**修改了什么(报备,未直接改 MoFin 代码):**
|
||||
- 新建 kanban 卡 `t_063136eb`(assignee=xiaoxiao),记录 NameError 根因+最小修复(顶部补 `import time`)
|
||||
- 在已有卡 `t_a44b6e16` 追加评论,标注该重试代码本身是坏的,busy_timeout+重试修复时必须一并补 time 导入
|
||||
- 关联文件:/home/hmo/MoFin/deploy/profile-scripts/b_td1_v3_scanner.py(硬链到 ~/.hermes/profiles/position-analyst/scripts/,inode 42196,git已跟踪)
|
||||
|
||||
**效果预期:** 小小莫修复时一次性处理锁(busy_timeout+重试)与缺失import两处,撞锁窗口不再因NameError二次崩溃。
|
||||
|
||||
Reference in New Issue
Block a user