From 9239ab40c07704543ee1577f0a00ff9974f56be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Mon, 13 Jul 2026 12:09:25 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0CHANGELOG=20+=20?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=9507/13?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - XMPP Bot非阻塞/本地XMPP/MUC修复 - price_monitor推送冷却持久化 - 深套股规则重构+换股规划swap-plan - 周月线技术分析增强 - 健康Tab写无读清零 - stale_push_wlin/per_stock_reassess/promote_candidates更新 - static/index.html + mofin_health.json + server.py同步 --- CHANGELOG.md | 43 +++ docs/analyst-knowledge-log.md | 81 +++- scripts/per_stock_reassess.py | 14 +- scripts/promote_candidates.py | 13 + scripts/stale_detector.py | 4 +- scripts/stale_push_wlin.py | 43 +-- server.py | 32 ++ static/index.html | 73 ++++ static/mofin_health.json | 700 +++++++++++++++++++--------------- 9 files changed, 645 insertions(+), 358 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 075e1840..91090456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -217,3 +217,46 @@ Dad 反馈我的 v4 手动分析(买入区3.62~3.72)与 13:01 cron 报告( - `per_stock_reassess 688981` → 输出 `[DB] holding_strategies 已更新: 688981` - DB holding_strategies 从 1 条 → 17 条 - web-dashboard PID 4003859 正常运行,API 通过 DB 读取 + +## 2026-07-10 — 知微XMPP Bot离线修复 + +### 根因 +Bot被bash包装器手动启动(非systemd),形成孤儿进程。systemd因PID文件冲突僵在`activating (auto-restart)`循环无法接管。孤儿bot在11:40:48断线后卡在重连循环中。 + +### 修复 +1. 杀死孤儿进程 PID 422464 +2. 清理 `/home/hmo/.hermes/zhiwei_bot.pid` 和 `/tmp/xmpp_zhiwei_bot.pid` +3. systemd RestartSec=10s 自动重启接管 +4. 验证:加入coregroup、XMPP就绪、presence available、bridge:5805正常、gateway正常 + +### 预防 +自愈系统新增检查项:systemd状态优先于进程检查——发现进程存在但非systemd管理时自动清理孤儿。 + +## 2026-07-13 — XMPP Bot非阻塞 + 深套规则重构 + 换股规划 + +### XMPP Bot修复 +- gateway调用改为 45s短超时 → "处理中"预回复 → 后台300s轮询,不再阻塞事件循环 +- 远程XMPP服务器不通,改为连本地 127.0.0.1:5222 代理 +- 注册 xep_0045 修复MUC崩溃 +- **涉及文件**: /home/hmo/xmpp_agent_core.py + +### price_monitor推送冷却持久化 +- _push_cooldown 从内存dict改为文件持久化,解决每2分钟重复推操作区间通知 +- **涉及文件**: scripts/price_monitor.py + +### 深套股规则重构 +- 删除全部 `is_deep_loss` 特殊处理(止损/止盈/买入区/质量检查6处guard + action_note覆盖) +- 回归客观判断,该加就加该割就割 +- **涉及文件**: scripts/strategy_lifecycle.py + +### 换股规划功能 +- `python3 strategy_lifecycle.py swap-plan [--need 金额]` +- 五维评分排序,自动计算释放资金方案 +- **涉及文件**: scripts/strategy_lifecycle.py + +### 技术分析增强 +- 周线/月线趋势/MA/支撑阻力注入mtf_context传递到LLM +- 健康Tab写无读警告 3→0 +- 每日汇总只发一次(16:35) +- 健康监控新增数据实体检查 +- **涉及文件**: technical_analysis.py, mofin_health.py, cron_to_xmpp.py, cron_health_monitor.py diff --git a/docs/analyst-knowledge-log.md b/docs/analyst-knowledge-log.md index a4d7afa9..01cddbc7 100644 --- a/docs/analyst-knowledge-log.md +++ b/docs/analyst-knowledge-log.md @@ -13,7 +13,27 @@ ### 系统架构变更 -**自选统一:** +## [2026-07-10 11:42] 知微XMPP Bot离线自愈修复 + +### 发现 +自愈执行器报告知微XMPP Bot离线。调查发现: +- Bot进程(PID 422464)被bash包装器手动启动,非systemd管理 +- systemd xmpp-zhiwei.service 因PID文件冲突僵在 `activating (auto-restart)` +- 孤儿bot在11:40:48断线后无法恢复连接 + +### 修复 +1. 杀死孤儿进程 `kill -TERM 422464` +2. 删除PID文件 `rm -f /home/hmo/.hermes/zhiwei_bot.pid /tmp/xmpp_zhiwei_bot.pid` +3. systemd自动重启,bot干净上线 +4. 验证:presence available、加入coregroup、bridge正常 + +### 教训 +bash包装器启动bot会绕开systemd管理,导致: +- systemd状态监测不准确(显示restarting而非running) +- 孤儿进程断开后无法被systemd接管 +- 已有 `xmpp-bot-infrastructure` skill 记录了孤儿进程陷阱,自愈系统可直接参考执行 + +自选统一:** - 自选数据统一存储在 `holding_strategies(decision_type='自选策略')` - `watchlist_stocks` 表已废弃(is_active=0) - `read_watchlist()` 改为从 `holding_strategies` 读取 @@ -66,10 +86,7 @@ - **调查**: 38条为 xiaoguo 来源信号,属4h时效内积压。当前已完成消费(xiaoguo_signal_consumer每30分运行),积压自愈 - **监控盲区发现**: intraday_health_check.py 和 system_audit.py 均只监控 `source LIKE 'xiaoguo%'`,忽略 divergence_watch(80)、trend(46) 等来源的126条未处理信号 - **修复**: 两处均增加全量未处理查询,区分 xiaoguo 和其他来源分别报告 -- **涉及文件**: - - `scripts/intraday_health_check.py` — check_signal_pipeline: 增加 total_unproc 查询和非xiaoguo预警 - - `scripts/system_audit.py` — audit_signals: 增加 total_unproc 查询和MEDIUM级别溢出预警 - - `CHANGELOG.md` — 追记监控盲区修复 +- **涉及文件**: scripts/intraday_health_check.py, scripts/system_audit.py, CHANGELOG.md ## [2026-07-09 14:xx] 自愈执行器升级:信号积压126条(divergence_watch/trend无consumer) @@ -78,3 +95,57 @@ - **修复**: divergence_detector.py — INSERT时加processed=1(归档性质不需要consumer)。DB — 80条divergence_watch + 46条trend历史标记为processed。同步cron目录MD5一致 - **效果**: signal_news 1077条全量已处理,健康检查PASS,后续不会再次积压 - **涉及文件**: scripts/divergence_detector.py, data/mofin.db, CHANGELOG.md + +## [2026-07-10 10:25] 自愈:知微XMPP Bot离线 — 孤儿进程阻塞systemd + +- **发现**: 盘中自检报警「知微XMPP Bot离线」,TODO 83 created(无fix_action,升级到LLM处理) +- **调查**: + - systemd `xmpp-zhiwei.service` 陷入无限重启循环(重启计数器110+) + - 根因:外部bash wrapper脚本在10:04启动了一个孤儿bot进程(PID 252975),该进程占用了`/tmp/xmpp_zhiwei_bot.pid`和端口5805 + - systemd每次尝试启动都因PID检查`xmpp_zhiwei_bot already running (PID 252975), exiting.`而退出 + - 实际上PID 252975的bot是正常运行的(已加入群聊coregroup,HTTP桥5805正常响应),只是不受systemd管理。wrapper触发源不明(可能自愈系统之前的升级操作) +- **修复**: + 1. `kill -TERM 252975` 杀掉孤儿进程 + 2. 清理旧PID文件 `/tmp/xmpp_zhiwei_bot.pid` 和 `/home/hmo/.hermes/zhiwei_bot.pid` + 3. systemd 10秒RestartSec后自动启动新实例 + 4. TODO 83 标记为completed +- **验证**: systemd active(running) since 10:25:43,bot加入群聊coregroup就绪,gateway health ok,HTTP桥5805正常 +- **效果**: systemd恢复管控bot,重启循环归零 +- **涉及文件**: /home/hmo/xmpp_zhiwei_bot.py (PID_FILE机制) + +## [2026-07-13] XMPP Bot非阻塞修复 + 深套股规则重构 + 换股规划 + +### XMPP Bot修复 +- **问题1**: bot调用gateway同步等600秒,阻塞事件循环 → XMPP心跳发不出 → 被踢下线 → 重试→turn堆积→更慢 +- **修复**: 45s短超时 + "处理中"预回复 + 后台300s轮询 + 不再阻塞心跳 +- **问题2**: 远程XMPP服务器(120.78.123.183:5222)网络不通,bot连不上 +- **修复**: bot.connect(host='127.0.0.1', port=5222) 改连本地XMPP代理 +- **问题3**: xep_0045 MUC插件未注册导致崩溃 +- **修复**: __init__加 self.register_plugin('xep_0045') +- **涉及文件**: /home/hmo/xmpp_agent_core.py + +### price_monitor通知噪音修复 +- **问题**: _push_cooldown 是内存dict,price_monitor每2分钟新进程运行 → cooldown每次重置 → 同股同区间反复推送 +- **修复**: cooldown持久化到 /home/hmo/.hermes/.price_push_cooldown.json +- **涉及文件**: scripts/price_monitor.py + +### 深套股规则重构(Dad铁律确认) +- **删除**: `is_deep_loss` 对止损/止盈/买入区/质量检查的全部6处guard +- **删除**: `action_note="深套持有"` 强制覆盖 +- **删除**: `position_advice="不补不割"` / `time_horizon="长期"` +- **保留**: `stock_category="深套"` 仅作标签 +- **原则**: 一切根据客观判断,该加就加该割就割 +- **涉及文件**: scripts/strategy_lifecycle.py + +### 换股规划功能 +- `python3 strategy_lifecycle.py swap-plan [--need 金额]` +- 五维评分: 亏损程度25% + 仓位20% + 技术趋势25% + 流动性15% + 前景15% +- 按评分排序输出可替换优先级,--need 参数自动计算卖几只够 +- **涉及文件**: scripts/strategy_lifecycle.py + +### 技术分析增强 +- weekly/monthly趋势/MA/支撑阻力注入mtf_context +- 健康Tab写无读警告从3个归零(stock_weekly/monthly/watchlist_log加manual_readers) +- 每日汇总只发一次(16:35 + sent标记防重复) +- cron_health_monitor新增数据实体完整性检查 +- 涉及文件: scripts/technical_analysis.py, scripts/strategy_lifecycle.py, scripts/mofin_health.py, scripts/cron_to_xmpp.py, scripts/cron_health_monitor.py diff --git a/scripts/per_stock_reassess.py b/scripts/per_stock_reassess.py index 59b80a7b..c5c1d172 100644 --- a/scripts/per_stock_reassess.py +++ b/scripts/per_stock_reassess.py @@ -229,11 +229,11 @@ def main(): continue entry = decisions_map.get(code) if not entry: - # 不在 decisions 中的自选股 → 从 DB watchlist_stocks 构建entry + # 不在 decisions 中的自选股 → 从 holding_strategies 构建entry import sqlite3 - _db = sqlite3.connect('/home/hmo/web-dashboard/data/mofin.db') + _db = sqlite3.connect('/home/hmo/MoFin/data/mofin.db') _db.row_factory = sqlite3.Row - _wl = _db.execute("SELECT * FROM watchlist_stocks WHERE code=? AND is_active=1", (code,)).fetchone() + _wl = _db.execute("SELECT * FROM holding_strategies WHERE code=? AND status='active' AND decision_type='自选策略'", (code,)).fetchone() _db.close() if _wl: entry = { @@ -299,7 +299,13 @@ def main(): skipped += 1 continue # 打印参数调试 - print(f" DEBUG: code={code} name={entry.get('name','')} price={price} cost={entry.get('cost')} shares={entry.get('shares')} action={entry.get('action','')[:30]} is_wl={entry.get('type','') in ('自选策略','watchlist')}", flush=True) + if entry is None: + print(f" DEBUG: code={code} ENTRY=NONE 跳过") + print(f" [SKIP] {code} 策略数据不存在") + skipped += 1 + continue + entry_action = str(entry.get('action') or '') + print(f" DEBUG: code={code} name={entry.get('name','')} price={price} cost={entry.get('cost')} shares={entry.get('shares')} action={entry_action[:30]} is_wl={entry.get('type','') in ('自选策略','watchlist')}", flush=True) result = reassess_strategy( code=code, name=entry.get("name", ""), diff --git a/scripts/promote_candidates.py b/scripts/promote_candidates.py index 33b8549d..83718d80 100644 --- a/scripts/promote_candidates.py +++ b/scripts/promote_candidates.py @@ -56,6 +56,19 @@ def main(): print(f" ⏭ {code} {name} 已在自选中,标记promoted") continue + # 验证实时价格:无有效价格的候选股不入自选(防假数据污染) + try: + import subprocess, json as _jj + _r = subprocess.run(["python3", "/home/hmo/.hermes/profiles/position-analyst/scripts/stock_quote.py", code], + capture_output=True, text=True, timeout=10) + _q = _jj.loads(_r.stdout) + if float(_q.get("price", 0)) <= 0: + print(f" ⏭ {code} {name} 无实时价格,跳过") + continue + except Exception as _e: + print(f" ⏭ {code} {name} 价格获取失败({_e}),跳过") + continue + # 构建策略 now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") timing_signal = "买入" if score >= 7 else "关注" diff --git a/scripts/stale_detector.py b/scripts/stale_detector.py index 4f71089b..93412551 100644 --- a/scripts/stale_detector.py +++ b/scripts/stale_detector.py @@ -136,7 +136,9 @@ def main(): if not cur_price or cur_price <= 0: continue drift = (cur_price / center - 1) * 100 - if abs(drift) > 15: + # 触发条件:价格偏离>15% 或 买入区明确错误(价格完全在区间外且偏离>50%) + price_outside = cur_price < wl_el or cur_price > wl_eh + if abs(drift) > 15 or (price_outside and abs(drift) > 50): reassess_scripts.append(code) print(f"[AUTO_REASSESS] {name}({code}) 价{cur_price:.2f}偏离买入区中心{center:.2f} {drift:+.0f}% → 触发重评") if reassess_scripts: diff --git a/scripts/stale_push_wlin.py b/scripts/stale_push_wlin.py index 4c76767b..86ac58f7 100644 --- a/scripts/stale_push_wlin.py +++ b/scripts/stale_push_wlin.py @@ -363,39 +363,6 @@ def main(): dec = read_decisions() for e in dec.get("decisions", []): code_data[e["code"]] = e - # 补充watchlist_stocks中不在holding_strategies的自选股 - import sqlite3 as _sq3 - _wl_db = _sq3.connect('/home/hmo/MoFin/data/mofin.db') - _wl_db.row_factory = _sq3.Row - _wl_rows = _wl_db.execute( - "SELECT code, name, entry_low, entry_high, stop_loss, analysis_json " - "FROM watchlist_stocks WHERE is_active=1 AND entry_low > 0" - ).fetchall() - _wl_db.close() - for _w in _wl_rows: - _c = str(_w["code"]) - if _c in code_data: - continue - _aj = json.loads(_w["analysis_json"]) if _w["analysis_json"] else {} - code_data[_c] = { - "code": _c, - "name": _w["name"] or "", - "price": 0, - "entry_low": _w["entry_low"], - "entry_high": _w["entry_high"], - "stop_loss": _w["stop_loss"] or 0, - "take_profit": _aj.get("take_profit", 0), - "rr_ratio": _aj.get("rr", 0), - "tech_snapshot": _aj.get("tech_snapshot", ""), - "timing_signal": _aj.get("action", ""), - "stock_category": "", - "sector_context": "", - "signal_factors": [], - "name": _w["name"] or "", - "shares": 0, - "cost": 0, - "price": 0, - } except Exception as _e: print(f"[DB_LOAD FAIL] {_e}", file=sys.stderr) @@ -498,8 +465,8 @@ def main(): eh = row[5] or 0 if price <= 0 or el <= 0 or eh <= 0: continue - # 价格必须在买入区内或略高于(不超过5%) - if price > eh * 1.05: + # 价格必须在买入区内(硬检查,拒绝偏离仍推买入) + if price < el or price > eh: continue name = row[1] or code all_candidates.append((name, code, price, el, eh, "", False)) @@ -573,6 +540,12 @@ def main(): # 信号必须含买入/加仓才推荐——其他非操作信号跳过 if not any(kw in sig for kw in ["买入", "加仓"]): continue + # 价格必须在买入区内(硬检查,拒绝价格偏离仍推买入) + buy_low, buy_high = s[3], s[4] + price_check = s[2] + if buy_low and buy_high and buy_low > 0: + if not (buy_low <= price_check <= buy_high): + continue # RR完整性检查:买入/加仓信号必须RR>0(策略数据要完整) cd = code_data.get(s[1], {}) rr = cd.get("rr_ratio", 0) or 0 diff --git a/server.py b/server.py index 6f70df04..9e17d844 100644 --- a/server.py +++ b/server.py @@ -83,6 +83,38 @@ def index(): return send_from_directory(app.static_folder, "index.html") +@app.route("/api/watch") +def get_watch(): + """盯盘:当前有操作建议的持仓+自选""" + import sqlite3 + conn = sqlite3.connect("/home/hmo/MoFin/data/mofin.db") + conn.row_factory = sqlite3.Row + # 持仓:所有买卖操作都进盯盘;自选:只有买入/加仓信号(没持仓不可能卖) + rows = conn.execute(""" + SELECT hs.code, hs.name, hs.decision_type, lp.price, lp.change_pct, + hs.entry_low, hs.entry_high, hs.stop_loss, hs.take_profit, + hs.rr_ratio, hs.timing_signal, hs.position_advice, hs.action, + hs.full_analysis + FROM holding_strategies hs + LEFT JOIN live_prices lp ON hs.code = lp.code + WHERE hs.status='active' + AND ( + (hs.decision_type='持仓策略' AND hs.timing_signal IN ('买入','可买入','可加仓','卖出','止盈')) + OR + (hs.decision_type='自选策略' AND hs.timing_signal IN ('买入','可买入','可加仓')) + ) + ORDER BY + CASE hs.timing_signal + WHEN '买入' THEN 1 WHEN '可买入' THEN 2 WHEN '可加仓' THEN 3 + WHEN '止盈' THEN 4 WHEN '卖出' THEN 5 + ELSE 9 + END, + lp.change_pct DESC + """).fetchall() + conn.close() + return json.dumps({"stocks": [dict(r) for r in rows], "count": len(rows)}, + ensure_ascii=False) + @app.route("/api/portfolio") def api_portfolio(): """持仓列表""" diff --git a/static/index.html b/static/index.html index 85b876f6..5947e33a 100644 --- a/static/index.html +++ b/static/index.html @@ -52,6 +52,7 @@ body { background: #0f0f13; color: #e2e8f0; } + 📸 上传 @@ -68,6 +69,13 @@ body { background: #0f0f13; color: #e2e8f0; } + @@ -151,6 +159,7 @@ function renderTab(name) { else if (name === 'prompts') renderPrompts(); else if (name === 'market') renderMarket(); else if (name === 'signals') renderSignals(); + else if (name === 'watch') renderWatch(); } // ── Data Fetching ── @@ -1266,6 +1275,70 @@ async function renderSignals() { el.innerHTML = `
加载失败: ${e.message}
`; } } + +// ── 盯盘 ── +let watchTimer = null; +async function renderWatch() { + const el = document.getElementById('watchContent'); + if (!el) return; + try { + // 清除旧定时器,切走时停 + if (watchTimer) clearInterval(watchTimer); + const data = await fetchJSON('/api/watch'); + const stocks = data.stocks || []; + document.getElementById('watchCount').textContent = stocks.length; + document.getElementById('watchRefreshTime').textContent = new Date().toLocaleTimeString(); + if (stocks.length === 0) { + el.innerHTML = '
暂无有效操作建议
'; + return; + } + let html = ''; + for (const s of stocks) { + const p = s.price || 0; + const cp = s.change_pct || 0; + const sig = s.timing_signal || ''; + const isBuy = sig.includes('买入') || sig.includes('加仓'); + const isSell = sig.includes('卖出') || sig.includes('止盈'); + const sigColor = isBuy ? 'bg-green-900/50 text-green-300' : isSell ? 'bg-red-900/50 text-red-300' : 'bg-yellow-900/50 text-yellow-300'; + const chgColor = cp >= 0 ? 'text-red-400' : 'text-green-400'; + const el_ = s.entry_low || 0; + const eh_ = s.entry_high || 0; + const sl_ = s.stop_loss || 0; + const tp_ = s.take_profit || 0; + const rr = s.rr_ratio || 0; + const inZone = (p && el_ && eh_ && p >= el_ && p <= eh_) ? '✅区内' : (p && eh_ && p > eh_) ? '⬆️超出' : '⬇️低于'; + html += ` +
+
+
+ ${s.code} + ${s.name || ''} + ${sig} + ${s.decision_type==='持仓策略'?'💼':'⭐'} +
+
+ ${p.toFixed(2)} + ${cp >= 0 ? '+' : ''}${cp.toFixed(2)}% + 区${el_.toFixed(1)}~${eh_.toFixed(1)} + ${inZone} + RR ${rr.toFixed(2)} + 损${sl_.toFixed(1)} 盈${tp_.toFixed(1)} +
+
+
+
仓位
+
${s.position_advice || '—'}
+
+
`; + } + el.innerHTML = html; + // 自动刷新:每30秒 + watchTimer = setInterval(renderWatch, 30000); + } catch(e) { + el.innerHTML = `
加载失败: ${e.message}
`; + watchTimer = setInterval(renderWatch, 60000); + } +} \ No newline at end of file diff --git a/static/mofin_health.json b/static/mofin_health.json index 5b37c292..30ba3fd2 100644 --- a/static/mofin_health.json +++ b/static/mofin_health.json @@ -1,5 +1,5 @@ { - "generated_at": "2026-07-10 01:02:34", + "generated_at": "2026-07-13 12:01:04", "feature_tree": { "label": "MoFin 系统", "status": "ok", @@ -18,7 +18,7 @@ "script": "market_watch.py", "schedule": "*/10 9-11,13-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:51", + "last_run": "2026-07-13T11:50", "type": "no_agent", "profile": "position-analyst" } @@ -38,8 +38,8 @@ "name": "价格监控-高频", "script": "price_monitor.py", "schedule": "*/2 9-16 * * 1-5", - "status": "ok", - "last_run": "2026-07-09T16:58", + "status": "error", + "last_run": "2026-07-13T12:00", "type": "no_agent", "profile": "position-analyst" } @@ -71,7 +71,7 @@ "script": "capital_flow_collector.py", "schedule": "1,31 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:31", + "last_run": "2026-07-13T11:31", "type": "no_agent", "profile": "position-analyst" } @@ -87,7 +87,7 @@ "script": "refresh_macro_context.py", "schedule": "*/30 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:30", + "last_run": "2026-07-13T11:30", "type": "no_agent", "profile": "position-analyst" } @@ -103,7 +103,7 @@ "script": "macro_context_collector.py", "schedule": "*/30 8-16 * * *", "status": "ok", - "last_run": "2026-07-09T16:30", + "last_run": "2026-07-13T11:30", "type": "no_agent", "profile": "position-analyst" } @@ -131,7 +131,7 @@ "script": "strategy-staleness-check.py", "schedule": "0 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:10", + "last_run": "2026-07-13T09:24", "type": "LLM", "profile": "position-analyst" } @@ -145,9 +145,9 @@ { "name": "自选买入区提醒-盘前午间尾盘", "script": "per_stock_reassess.py", - "schedule": "0 9,12,15 * * 1-5", + "schedule": "0 12,15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:01", + "last_run": "2026-07-10T15:01", "type": "no_agent", "profile": "position-analyst" }, @@ -155,8 +155,8 @@ "name": "自选买入区提醒", "script": "stale_push_wlin.py", "schedule": "1,31 9-15 * * 1-5", - "status": "ok", - "last_run": "2026-07-09T15:31", + "status": "error", + "last_run": "2026-07-10T11:03", "type": "no_agent", "profile": "position-analyst" } @@ -172,7 +172,7 @@ "script": "strategy_evaluator.py", "schedule": "0 21 * * 6", "status": "ok", - "last_run": "2026-07-08T22:55", + "last_run": "2026-07-11T21:00", "type": "no_agent", "profile": "position-analyst" }, @@ -181,7 +181,7 @@ "script": "stale_detector.py", "schedule": "0 21 * * 1-5", "status": "ok", - "last_run": "2026-07-09T21:16", + "last_run": "2026-07-10T21:13", "type": "LLM", "profile": "position-analyst" }, @@ -190,7 +190,7 @@ "script": "collect_evaluation_data.py", "schedule": "30 20 * * 1-5", "status": "ok", - "last_run": "2026-07-09T20:30", + "last_run": "2026-07-10T20:30", "type": "no_agent", "profile": "position-analyst" } @@ -206,7 +206,7 @@ "script": "branch_scanner.py", "schedule": "15,30,45,00 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:45", + "last_run": "2026-07-13T11:45", "type": "no_agent", "profile": "position-analyst" } @@ -222,7 +222,7 @@ "script": "meta_growth.py", "schedule": "45 0,12 * * 1-5", "status": "ok", - "last_run": "2026-07-10T00:45", + "last_run": "2026-07-13T00:45", "type": "no_agent", "profile": "position-analyst" } @@ -238,7 +238,7 @@ "script": "prune_branches.py", "schedule": "0 21 * * 1-5", "status": "ok", - "last_run": "2026-07-09T21:01", + "last_run": "2026-07-10T21:00", "type": "no_agent", "profile": "position-analyst" } @@ -247,14 +247,30 @@ { "label": "自选股自动重评-周末 (stale_detector.py)", "desc": "周末批量重评自选股策略", - "status": null, + "status": "ok", "pipes": [ { "name": "自选股自动重评-周末", "script": "stale_detector.py", "schedule": "30 10 * * 0,6", - "status": null, - "last_run": "", + "status": "ok", + "last_run": "2026-07-12T10:30", + "type": "no_agent", + "profile": "position-analyst" + } + ] + }, + { + "label": "盘前全量重评-自选退出 (premarket_full_review.py)", + "desc": "", + "status": "error", + "pipes": [ + { + "name": "盘前全量重评-自选退出", + "script": "premarket_full_review.py", + "schedule": "10 8 * * 1-5", + "status": "error", + "last_run": "2026-07-13T08:12", "type": "no_agent", "profile": "position-analyst" } @@ -309,7 +325,7 @@ "script": "cron_to_xmpp.py", "schedule": "*/5 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:55", + "last_run": "2026-07-13T11:55", "type": "no_agent", "profile": "position-analyst" } @@ -322,10 +338,10 @@ "pipes": [ { "name": "开盘简报", - "script": "generate_report.py opening_brief", + "script": "/home/hmo/MoFin/scripts/generate_report.py opening_brief", "schedule": "35 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:50", + "last_run": "2026-07-13T10:18", "type": "LLM", "profile": "position-analyst" } @@ -338,10 +354,10 @@ "pipes": [ { "name": "收盘简报", - "script": "generate_report.py closing_brief", + "script": "/home/hmo/MoFin/scripts/generate_report.py closing_brief", "schedule": "10 16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:14", + "last_run": "2026-07-10T16:19", "type": "LLM", "profile": "position-analyst" } @@ -357,7 +373,7 @@ "script": null, "schedule": "0 16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:10", + "last_run": "2026-07-10T16:12", "type": "LLM", "profile": "position-analyst" } @@ -373,7 +389,7 @@ "script": "system_health_check.py", "schedule": "0 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:46", + "last_run": "2026-07-13T09:27", "type": "LLM", "profile": "position-analyst" } @@ -389,7 +405,7 @@ "script": "morning_health_check.py", "schedule": "0 8 * * 1-5", "status": "ok", - "last_run": "2026-07-09T08:01", + "last_run": "2026-07-13T08:01", "type": "no_agent", "profile": "position-analyst" } @@ -398,14 +414,14 @@ { "label": "开盘前钉对钉验证 (preflight_verify.py)", "desc": "开盘前15项验证(脚本同步/DB完整性/资产公式)", - "status": "ok", + "status": "error", "pipes": [ { "name": "开盘前钉对钉验证", "script": "preflight_verify.py", "schedule": "30 8 * * 1-5", - "status": "ok", - "last_run": "2026-07-09T10:25", + "status": "error", + "last_run": "2026-07-13T08:30", "type": "no_agent", "profile": "position-analyst" } @@ -421,7 +437,7 @@ "script": "cron_to_xmpp.py", "schedule": "* 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:59", + "last_run": "2026-07-13T12:01", "type": "no_agent", "profile": "default" } @@ -444,7 +460,7 @@ "script": null, "schedule": "30 8 * * 1-5", "status": "ok", - "last_run": "2026-07-09T08:45", + "last_run": "2026-07-13T08:45", "type": "LLM", "profile": "position-analyst" }, @@ -453,7 +469,7 @@ "script": null, "schedule": "30 11 * * 1-5", "status": "ok", - "last_run": "2026-07-09T12:05", + "last_run": "2026-07-13T11:37", "type": "LLM", "profile": "position-analyst" }, @@ -461,8 +477,8 @@ "name": "宏观风险扫描-周末", "script": null, "schedule": "0 10 * * 0,6", - "status": "ok", - "last_run": "2026-07-05T10:09", + "status": "error", + "last_run": "2026-07-12T10:00", "type": "LLM", "profile": "position-analyst" } @@ -478,7 +494,7 @@ "script": "macro_signal_consumer.py", "schedule": "5,20,35,50 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:51", + "last_run": "2026-07-13T11:50", "type": "no_agent", "profile": "position-analyst" } @@ -494,7 +510,7 @@ "script": "divergence_detector.py", "schedule": "*/30 8-15 * * *", "status": "ok", - "last_run": "2026-07-09T15:30", + "last_run": "2026-07-13T11:30", "type": "no_agent", "profile": "position-analyst" }, @@ -503,7 +519,7 @@ "script": "divergence_detector.py", "schedule": "30 8-16/2 * * 0,6", "status": "ok", - "last_run": "2026-07-05T16:30", + "last_run": "2026-07-12T16:30", "type": "no_agent", "profile": "position-analyst" } @@ -526,7 +542,7 @@ "script": "system_audit.py", "schedule": "30 17 * * 1-5", "status": "ok", - "last_run": "2026-07-09T17:37", + "last_run": "2026-07-10T17:35", "type": "LLM", "profile": "position-analyst" } @@ -542,7 +558,7 @@ "script": "cron_health_monitor.py", "schedule": "*/10 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:50", + "last_run": "2026-07-13T11:51", "type": "no_agent", "profile": "position-analyst" } @@ -558,7 +574,7 @@ "script": "verify_reassess_pipeline.py", "schedule": "*/30 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:30", + "last_run": "2026-07-13T11:30", "type": "no_agent", "profile": "position-analyst" } @@ -574,7 +590,7 @@ "script": "mofin_health.py", "schedule": "*/15 9-16,20-22 * * 1-5", "status": "ok", - "last_run": "2026-07-09T22:45", + "last_run": "2026-07-13T11:45", "type": "no_agent", "profile": "position-analyst" } @@ -590,7 +606,7 @@ "script": "hardcode_scanner.py", "schedule": "25 17 * * 1-5", "status": "ok", - "last_run": "2026-07-09T17:26", + "last_run": "2026-07-10T17:25", "type": "no_agent", "profile": "position-analyst" } @@ -606,7 +622,7 @@ "script": "intraday_health_check.py", "schedule": "*/15 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:45", + "last_run": "2026-07-13T11:45", "type": "no_agent", "profile": "position-analyst" } @@ -622,7 +638,7 @@ "script": "data_governance.py", "schedule": "0 10 * * 6", "status": "ok", - "last_run": "2026-07-08T22:55", + "last_run": "2026-07-11T10:00", "type": "no_agent", "profile": "position-analyst" } @@ -638,7 +654,7 @@ "script": "memory_guardian.py", "schedule": "0 7 * * *", "status": "ok", - "last_run": "2026-07-09T07:01", + "last_run": "2026-07-13T07:01", "type": "no_agent", "profile": "position-analyst" } @@ -661,7 +677,7 @@ "script": "self_todo_executor.py", "schedule": "*/10 8-22 * * 1-5", "status": "ok", - "last_run": "2026-07-09T22:50", + "last_run": "2026-07-13T11:50", "type": "no_agent", "profile": "position-analyst" } @@ -677,7 +693,7 @@ "script": "review_needed_watchdog.py", "schedule": "0,30 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:30", + "last_run": "2026-07-13T12:01", "type": "no_agent", "profile": "position-analyst" } @@ -693,7 +709,7 @@ "script": "clean_watchlist.py", "schedule": "5 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:05", + "last_run": "2026-07-13T09:05", "type": "no_agent", "profile": "position-analyst" } @@ -709,7 +725,7 @@ "script": "advice_reconciliation.py", "schedule": "0 20 * * 6", "status": "ok", - "last_run": "2026-07-04T20:00", + "last_run": "2026-07-11T20:00", "type": "no_agent", "profile": "position-analyst" } @@ -748,7 +764,7 @@ "script": "strategy_review.py", "schedule": "0 20 * * 1-5", "status": "ok", - "last_run": "2026-07-09T20:00", + "last_run": "2026-07-10T20:01", "type": "no_agent", "profile": "position-analyst" } @@ -799,7 +815,7 @@ "script": "monitor_300308.py", "schedule": "*/2 13-14 * * 1-5", "status": "ok", - "last_run": "2026-07-09T14:58", + "last_run": "2026-07-10T14:58", "type": "no_agent", "profile": "position-analyst" } @@ -815,7 +831,7 @@ "script": "300308_monitor.py", "schedule": "*/2 13-14 * * 1-5", "status": "ok", - "last_run": "2026-07-09T14:58", + "last_run": "2026-07-10T14:58", "type": "no_agent", "profile": "position-analyst" } @@ -831,7 +847,7 @@ "script": "refresh_mtf_cache.py", "schedule": "0 9,11,14 * * 1-5", "status": "ok", - "last_run": "2026-07-09T14:00", + "last_run": "2026-07-13T11:00", "type": "no_agent", "profile": "position-analyst" } @@ -853,7 +869,7 @@ "script": "market_insight.py", "schedule": "35 15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:35", + "last_run": "2026-07-10T15:35", "type": "no_agent", "profile": "position-analyst" } @@ -869,7 +885,7 @@ "script": "market_screener.py", "schedule": "35 15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:35", + "last_run": "2026-07-10T15:35", "type": "no_agent", "profile": "position-analyst" } @@ -878,14 +894,14 @@ { "label": "候选股自动推广-盘中 (promote_candidates.py)", "desc": "", - "status": null, + "status": "ok", "pipes": [ { "name": "候选股自动推广-盘中", "script": "promote_candidates.py", "schedule": "0,30 9-15 * * 1-5", - "status": null, - "last_run": "", + "status": "ok", + "last_run": "2026-07-10T12:00", "type": "no_agent", "profile": "position-analyst" } @@ -894,14 +910,14 @@ { "label": "主力建仓扫描-每15分 (accumulation_scanner.py)", "desc": "", - "status": null, + "status": "ok", "pipes": [ { "name": "主力建仓扫描-每15分", "script": "accumulation_scanner.py", "schedule": "*/10 9-15 * * 1-5", - "status": null, - "last_run": "", + "status": "ok", + "last_run": "2026-07-13T11:50", "type": "no_agent", "profile": "position-analyst" } @@ -910,14 +926,14 @@ { "label": "候选股自动提拔-每30分 (promote_candidates.py)", "desc": "", - "status": null, + "status": "error", "pipes": [ { "name": "候选股自动提拔-每30分", "script": "promote_candidates.py", "schedule": "*/30 9-15 * * 1-5", - "status": null, - "last_run": "", + "status": "error", + "last_run": "2026-07-13T11:30", "type": "no_agent", "profile": "position-analyst" } @@ -926,14 +942,14 @@ { "label": "候选股过滤管道-每30分 (candidate_filter.py)", "desc": "", - "status": null, + "status": "ok", "pipes": [ { "name": "候选股过滤管道-每30分", "script": "candidate_filter.py", "schedule": "*/30 9-15 * * 1-5", - "status": null, - "last_run": "", + "status": "ok", + "last_run": "2026-07-13T11:30", "type": "no_agent", "profile": "position-analyst" } @@ -965,7 +981,7 @@ "script": "sync_dashboard.py", "schedule": "55 8 * * *", "status": "ok", - "last_run": "2026-07-09T08:55", + "last_run": "2026-07-13T08:55", "type": "no_agent", "profile": "default" } @@ -980,14 +996,14 @@ { "label": "state.db真空整理-每周 (vacuum_state_db.py)", "desc": "每周DB真空整理", - "status": null, + "status": "ok", "pipes": [ { "name": "state.db真空整理-每周", "script": "vacuum_state_db.py", "schedule": "0 3 * * 6", - "status": null, - "last_run": "", + "status": "ok", + "last_run": "2026-07-11T03:00", "type": "no_agent", "profile": "position-analyst" } @@ -1078,18 +1094,18 @@ { "name": "candidates", "desc": "潜力股候选池(小果扫描产出)", - "rows": 25, + "rows": 118, "readers": [ - "candidate_filter", - "mofin_db", "accumulation_scanner", - "promote_candidates" + "promote_candidates", + "candidate_filter", + "mofin_db" ], "writers": [ - "candidate_filter", - "market_scanner", "accumulation_scanner", - "promote_candidates" + "market_scanner", + "promote_candidates", + "candidate_filter" ], "has_input": true, "has_output": true, @@ -1110,8 +1126,10 @@ { "name": "capital_flow_cache", "desc": "资金流缓存", - "rows": 0, + "rows": 1, "readers": [ + "per_stock_reassess", + "batch_reassess", "mofin_db" ], "writers": [ @@ -1137,12 +1155,12 @@ "desc": "资金变动记录", "rows": 15, "readers": [ - "mofin_db", - "prepare_report_data" + "prepare_report_data", + "mofin_db" ], "writers": [ - "mofin_db", - "mo_data" + "mo_data", + "mofin_db" ], "has_input": true, "has_output": true, @@ -1164,7 +1182,7 @@ { "name": "health_check_log", "desc": "健康检查日志", - "rows": 13, + "rows": 15, "readers": [ "morning_health_check" ], @@ -1189,26 +1207,27 @@ { "name": "holding_strategies", "desc": "每只股票的完整策略参数", - "rows": 75, + "rows": 124, "readers": [ - "mofin_collect", - "run_all_tests", - "system_audit", - "accumulation_scanner", - "candidate_filter", + "watchlist_auto_exit", + "strategy_lifecycle", "system_health_check", - "promote_candidates", + "per_stock_reassess", + "batch_reassess", + "candidate_filter", "mofin_db", - "generate_report", - "verify_reassess_pipeline" + "accumulation_scanner", + "run_all_tests", + "system_audit" ], "writers": [ + "watchlist_auto_exit", "data_governance", + "mofin_db", "sync_decisions_to_db", - "batch_reassess", - "per_stock_reassess", "promote_candidates", - "mofin_db" + "per_stock_reassess", + "batch_reassess" ], "has_input": true, "has_output": true, @@ -1236,20 +1255,20 @@ "desc": "当前持仓(权威源)", "rows": 19, "readers": [ - "mofin_collect", - "run_all_tests", - "xiaoguo_scanner", - "system_audit", - "prepare_recommendation", - "accumulation_scanner", + "strategy_lifecycle", + "mo_alphasift_bridge", + "xiaoguo_signal_consumer", + "prepare_report_data", "import_holding_xls", - "candidate_filter", "system_health_check", - "mo_alphasift_bridge" + "per_stock_reassess", + "refresh_mtf_cache", + "candidate_filter", + "mofin_db" ], "writers": [ - "mofin_db", - "import_holding_xls" + "import_holding_xls", + "mofin_db" ], "has_input": true, "has_output": true, @@ -1275,19 +1294,21 @@ { "name": "live_prices", "desc": "所有持仓+自选最新实时价", - "rows": 72, + "rows": 129, "readers": [ - "candidate_filter", "mo_data", - "stale_push_wlin", + "candidate_filter", + "strategy_lifecycle", "mofin_db", + "verify_reassess_pipeline", + "generate_report", "cron_health_monitor", - "system_audit", - "verify_reassess_pipeline" + "stale_push_wlin", + "system_audit" ], "writers": [ - "mofin_db", - "mo_data" + "mo_data", + "mofin_db" ], "has_input": true, "has_output": true, @@ -1311,17 +1332,17 @@ { "name": "macro_context_log", "desc": "宏观上下文(大盘偏向/指数)", - "rows": 24, + "rows": 37, "readers": [ - "strategy_tree", - "batch_reassess", - "per_stock_reassess", - "stale_push_wlin", + "divergence_detector", "strategy_lifecycle", "system_audit", + "strategy_tree", "xiaoguo_signal_consumer", - "divergence_detector", - "stock_profile" + "stale_push_wlin", + "stock_profile", + "per_stock_reassess", + "batch_reassess" ], "writers": [ "refresh_macro_context" @@ -1347,7 +1368,7 @@ { "name": "macro_raw_news", "desc": "宏观新闻原始数据", - "rows": 9312, + "rows": 11788, "readers": [ "system_audit", "macro_context_collector" @@ -1374,15 +1395,15 @@ { "name": "market_snapshots", "desc": "大盘指数快照(每10分)", - "rows": 578, + "rows": 637, "readers": [ + "mofin_query", + "mofin_db", + "market_scanner", + "prepare_report_data", "trend_detector", "market_screener", - "prepare_report_data", - "mofin_db", - "system_audit", - "market_scanner", - "mofin_query" + "system_audit" ], "writers": [ "mofin_db" @@ -1408,11 +1429,11 @@ { "name": "mtf_cache", "desc": "多周期均线缓存", - "rows": 39, + "rows": 49, "readers": [ "multi_timeframe", - "mofin_db", - "technical_analysis" + "technical_analysis", + "mofin_db" ], "writers": [ "multi_timeframe", @@ -1441,16 +1462,16 @@ "desc": "总资产/现金/仓位汇总", "rows": 1, "readers": [ - "mo_data", - "price_monitor", "preflight_verify", - "prepare_report_data", + "mo_data", "mofin_db", - "import_holding_xls" + "prepare_report_data", + "import_holding_xls", + "price_monitor" ], "writers": [ - "mofin_db", - "import_holding_xls" + "import_holding_xls", + "mofin_db" ], "has_input": true, "has_output": true, @@ -1502,15 +1523,15 @@ "desc": "行业信号(趋势检测产出)", "rows": 653, "readers": [ - "xiaoguo_news_processor", - "mofin_news", "trend_detector", - "server" + "server", + "xiaoguo_news_processor", + "mofin_news" ], "writers": [ + "trend_detector", "xiaoguo_news_processor", - "mofin_news", - "trend_detector" + "mofin_news" ], "has_input": true, "has_output": true, @@ -1535,13 +1556,13 @@ { "name": "sector_snapshots", "desc": "行业板块数据", - "rows": 46570, + "rows": 51160, "readers": [ - "trend_detector", - "market_screener", - "mofin_db", "strategy_lifecycle", - "market_scanner" + "mofin_db", + "market_scanner", + "trend_detector", + "market_screener" ], "writers": [ "mofin_db" @@ -1567,23 +1588,24 @@ { "name": "signal_news", "desc": "信号相关新闻", - "rows": 1106, + "rows": 1160, "readers": [ - "macro_signal_consumer", "server", + "macro_signal_consumer", + "system_audit", + "xiaoguo_signal_consumer", "intraday_health_check", "per_stock_reassess", - "system_audit", - "xiaoguo_signal_consumer" + "batch_reassess" ], "writers": [ - "macro_signal_consumer", - "xiaoguo_news_processor", "xiaoguo_scanner", + "macro_signal_consumer", "macro_context_collector", - "mofin_news", "xiaoguo_signal_consumer", - "divergence_detector" + "xiaoguo_news_processor", + "divergence_detector", + "mofin_news" ], "has_input": true, "has_output": true, @@ -1638,7 +1660,7 @@ { "name": "stock_daily", "desc": "日线行情", - "rows": 7744, + "rows": 9161, "readers": [ "mofin_db" ], @@ -1677,17 +1699,34 @@ } } }, + { + "name": "stock_monthly", + "desc": "月线行情", + "rows": 712, + "readers": [ + "multi_timeframe" + ], + "writers": [ + "mofin_db" + ], + "has_input": true, + "has_output": true, + "orphan": false, + "flow_status": "healthy", + "warn": false, + "flow_detail": {} + }, { "name": "stock_sectors", "desc": "股票行业映射", "rows": 63, "readers": [ - "trend_detector", - "xiaoguo_news_processor", - "per_stock_reassess", + "strategy_lifecycle", "mofin_db", - "mofin_news", - "strategy_lifecycle" + "xiaoguo_news_processor", + "trend_detector", + "per_stock_reassess", + "mofin_news" ], "writers": [ "mofin_db" @@ -1710,21 +1749,38 @@ } } }, + { + "name": "stock_weekly", + "desc": "周线行情", + "rows": 1376, + "readers": [ + "multi_timeframe" + ], + "writers": [ + "mofin_db" + ], + "has_input": true, + "has_output": true, + "orphan": false, + "flow_status": "healthy", + "warn": false, + "flow_detail": {} + }, { "name": "stocks", "desc": "全量股票代码", "rows": 5572, "readers": [ - "trend_detector", - "xiaoguo_news_processor", "mofin_db", - "mofin_news", "accumulation_scanner", - "import_full_stocks" + "xiaoguo_news_processor", + "trend_detector", + "import_full_stocks", + "mofin_news" ], "writers": [ - "mofin_db", - "import_full_stocks" + "import_full_stocks", + "mofin_db" ], "has_input": true, "has_output": true, @@ -1749,9 +1805,9 @@ "desc": "策略重评历史记录", "rows": 217, "readers": [ - "mofin_db", + "verify_reassess_pipeline", "system_audit", - "verify_reassess_pipeline" + "mofin_db" ], "writers": [ "mofin_collect" @@ -1803,21 +1859,21 @@ { "name": "todos", "desc": "自愈任务队列", - "rows": 68, + "rows": 73, "readers": [ - "intraday_health_check", + "morning_health_check", "strategy-staleness-check", - "self_todo_executor", - "morning_health_check" + "intraday_health_check", + "self_todo_executor" ], "writers": [ - "strategy-staleness-check", - "mofin_collect", + "preflight_verify", "self_todo_executor", "morning_health_check", + "cron_health_monitor", + "strategy-staleness-check", "intraday_health_check", - "preflight_verify", - "cron_health_monitor" + "mofin_collect" ], "has_input": true, "has_output": true, @@ -1842,25 +1898,43 @@ } }, { - "name": "watchlist_stocks", - "desc": "自选股列表", - "rows": 43, + "name": "watchlist_log", + "desc": "", + "rows": 48, "readers": [ - "mofin_collect", - "trend_detector", - "mo_alphasift_bridge", - "run_all_tests", - "stale_detector", - "price_monitor", - "per_stock_reassess", - "refresh_mtf_cache", - "xiaoguo_scanner", - "stale_push_wlin" + "watchlist_auto_exit", + "mofin_db" ], "writers": [ + "watchlist_auto_exit" + ], + "has_input": true, + "has_output": true, + "orphan": false, + "flow_status": "healthy", + "warn": false, + "flow_detail": {} + }, + { + "name": "watchlist_stocks", + "desc": "自选股列表", + "rows": 63, + "readers": [ + "refresh_mtf_cache", "mofin_db", + "xiaoguo_scanner", + "stock_quote", + "mo_alphasift_bridge", + "run_all_tests", + "xiaoguo_signal_consumer", + "stale_push_wlin", + "trend_detector", "per_stock_reassess" ], + "writers": [ + "per_stock_reassess", + "mofin_db" + ], "has_input": true, "has_output": true, "orphan": false, @@ -1930,10 +2004,10 @@ { "name": "candidate_pool.json", "desc": "潜力股候选池完整数据", - "size_kb": 50.6, + "size_kb": 53.6, "readers": [], "writers": [], - "last_modified": "07-09 12:09", + "last_modified": "07-10 15:03", "warn": true }, { @@ -2000,21 +2074,30 @@ "warn": true }, { - "name": "growth_registry.json", + "name": "format_error_library.json", "desc": "", - "size_kb": 1.7, + "size_kb": 0.1, "readers": [], "writers": [], - "last_modified": "07-10 00:45", + "last_modified": "07-12 03:15", + "warn": true + }, + { + "name": "growth_registry.json", + "desc": "", + "size_kb": 1.3, + "readers": [], + "writers": [], + "last_modified": "07-10 12:45", "warn": true }, { "name": "hardcode_audit.json", "desc": "", - "size_kb": 3401.1, + "size_kb": 3428.2, "readers": [], "writers": [], - "last_modified": "07-09 17:26", + "last_modified": "07-10 17:25", "warn": true }, { @@ -2023,7 +2106,7 @@ "size_kb": 12.2, "readers": [], "writers": [], - "last_modified": "07-09 08:00", + "last_modified": "07-13 08:00", "warn": true }, { @@ -2056,19 +2139,19 @@ { "name": "macro_risk_state.json", "desc": "宏观风险状态(采集器写入)", - "size_kb": 0.9, + "size_kb": 0.8, "readers": [], "writers": [], - "last_modified": "07-09 16:00", + "last_modified": "07-13 12:01", "warn": true }, { "name": "mofin_health.json", "desc": "健康监控数据", - "size_kb": 85.5, + "size_kb": 87.0, "readers": [], "writers": [], - "last_modified": "07-10 01:01", + "last_modified": "07-13 11:45", "warn": true }, { @@ -2092,10 +2175,10 @@ { "name": "pipeline_registry.json", "desc": "", - "size_kb": 26.1, + "size_kb": 29.8, "readers": [], "writers": [], - "last_modified": "07-09 08:01", + "last_modified": "07-13 08:01", "warn": true }, { @@ -2104,34 +2187,34 @@ "size_kb": 2.2, "readers": [], "writers": [], - "last_modified": "07-09 10:26", + "last_modified": "07-13 08:30", "warn": true }, { "name": "price_events.json", "desc": "", - "size_kb": 121.8, + "size_kb": 380.3, "readers": [], "writers": [], - "last_modified": "07-09 15:02", + "last_modified": "07-13 12:01", "warn": true }, { "name": "price_history.json", "desc": "", - "size_kb": 8.3, + "size_kb": 12.0, "readers": [], "writers": [], - "last_modified": "07-09 22:52", + "last_modified": "07-13 12:01", "warn": true }, { "name": "push_cooldown.json", "desc": "", - "size_kb": 0.9, + "size_kb": 1.1, "readers": [], "writers": [], - "last_modified": "07-09 14:01", + "last_modified": "07-10 09:32", "warn": true }, { @@ -2140,7 +2223,7 @@ "size_kb": 0.1, "readers": [], "writers": [], - "last_modified": "07-09 15:45", + "last_modified": "07-13 12:01", "warn": true }, { @@ -2191,10 +2274,10 @@ { "name": "strategy_staleness_report.json", "desc": "策略过期报告", - "size_kb": 13.0, + "size_kb": 10.9, "readers": [], "writers": [], - "last_modified": "07-09 09:01", + "last_modified": "07-13 09:01", "warn": true }, { @@ -2209,10 +2292,10 @@ { "name": "system_audit_report.json", "desc": "", - "size_kb": 2.0, + "size_kb": 2.2, "readers": [], "writers": [], - "last_modified": "07-09 17:30", + "last_modified": "07-10 17:33", "warn": true }, { @@ -2259,7 +2342,7 @@ "script": "monitor_300308.py", "schedule": "*/2 13-14 * * 1-5", "status": "ok", - "last_run": "2026-07-09T14:58:29", + "last_run": "2026-07-10T14:58:53", "profile": "position-analyst" }, { @@ -2268,7 +2351,7 @@ "script": "300308_monitor.py", "schedule": "*/2 13-14 * * 1-5", "status": "ok", - "last_run": "2026-07-09T14:58:28", + "last_run": "2026-07-10T14:58:52", "profile": "position-analyst" }, { @@ -2277,7 +2360,7 @@ "script": "cron_watchdog.py", "schedule": "*/15 9-16 * * 1-5", "status": "error", - "last_run": "2026-07-09T16:45:15", + "last_run": "2026-07-13T12:01:03", "profile": "default" }, { @@ -2286,7 +2369,7 @@ "script": "morning_health_check.py", "schedule": "0 8 * * 1-5", "status": "ok", - "last_run": "2026-07-09T08:01:32", + "last_run": "2026-07-13T08:01:34", "profile": "position-analyst" }, { @@ -2295,7 +2378,7 @@ "script": "bot_monitor.sh", "schedule": "every 60m", "status": "ok", - "last_run": "2026-07-10T01:00:20", + "last_run": "2026-07-13T11:43:30", "profile": "default" }, { @@ -2304,7 +2387,7 @@ "script": "cron_to_xmpp.py", "schedule": "* 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:59:55", + "last_run": "2026-07-13T12:01:03", "profile": "default" }, { @@ -2313,7 +2396,7 @@ "script": "cron_to_xmpp.py", "schedule": "*/5 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:55:25", + "last_run": "2026-07-13T11:55:49", "profile": "position-analyst" }, { @@ -2322,7 +2405,7 @@ "script": null, "schedule": "0 * * * *", "status": "ok", - "last_run": "2026-07-10T00:12:46", + "last_run": "2026-07-13T04:02:42", "profile": "default" }, { @@ -2330,8 +2413,8 @@ "type": "no_agent", "script": "vacuum_state_db.py", "schedule": "0 3 * * 6", - "status": null, - "last_run": "None", + "status": "ok", + "last_run": "2026-07-11T03:00:22", "profile": "position-analyst" }, { @@ -2339,8 +2422,8 @@ "type": "LLM", "script": "wiki_health_aggregate.py", "schedule": "0 3 * * *", - "status": "ok", - "last_run": "2026-07-09T03:10:16", + "status": "error", + "last_run": "2026-07-12T03:04:31", "profile": "default" }, { @@ -2349,7 +2432,7 @@ "script": "xiaoguo_quick_scan.py", "schedule": "*/15 * * * *", "status": "ok", - "last_run": "2026-07-10T01:00:18", + "last_run": "2026-07-13T11:45:33", "profile": "default" }, { @@ -2357,8 +2440,8 @@ "type": "no_agent", "script": "xiaoguo_tunnel_watchdog.sh", "schedule": "*/5 * * * *", - "status": "error", - "last_run": "2026-07-10T01:02:18", + "status": "ok", + "last_run": "2026-07-13T11:55:14", "profile": "default" }, { @@ -2366,8 +2449,8 @@ "type": "no_agent", "script": "accumulation_scanner.py", "schedule": "*/10 9-15 * * 1-5", - "status": null, - "last_run": "None", + "status": "ok", + "last_run": "2026-07-13T11:50:56", "profile": "position-analyst" }, { @@ -2375,17 +2458,8 @@ "type": "no_agent", "script": "price_monitor.py", "schedule": "*/2 9-16 * * 1-5", - "status": "ok", - "last_run": "2026-07-09T16:58:30", - "profile": "position-analyst" - }, - { - "name": "候选股自动推广-盘中", - "type": "no_agent", - "script": "promote_candidates.py", - "schedule": "0,30 9-15 * * 1-5", - "status": null, - "last_run": "None", + "status": "error", + "last_run": "2026-07-13T12:00:54", "profile": "position-analyst" }, { @@ -2393,8 +2467,8 @@ "type": "no_agent", "script": "promote_candidates.py", "schedule": "*/30 9-15 * * 1-5", - "status": null, - "last_run": "None", + "status": "error", + "last_run": "2026-07-13T11:30:39", "profile": "position-analyst" }, { @@ -2402,8 +2476,8 @@ "type": "no_agent", "script": "candidate_filter.py", "schedule": "*/30 9-15 * * 1-5", - "status": null, - "last_run": "None", + "status": "ok", + "last_run": "2026-07-13T11:30:41", "profile": "position-analyst" }, { @@ -2412,7 +2486,7 @@ "script": "mofin_health.py", "schedule": "*/15 9-16,20-22 * * 1-5", "status": "ok", - "last_run": "2026-07-09T22:45:27", + "last_run": "2026-07-13T11:45:45", "profile": "position-analyst" }, { @@ -2421,7 +2495,7 @@ "script": "meta_growth.py", "schedule": "45 0,12 * * 1-5", "status": "ok", - "last_run": "2026-07-10T00:45:46", + "last_run": "2026-07-13T00:45:38", "profile": "position-analyst" }, { @@ -2430,7 +2504,7 @@ "script": "cron_health_monitor.py", "schedule": "*/10 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:50:53", + "last_run": "2026-07-13T11:51:10", "profile": "position-analyst" }, { @@ -2439,7 +2513,7 @@ "script": "prune_branches.py", "schedule": "0 21 * * 1-5", "status": "ok", - "last_run": "2026-07-09T21:01:03", + "last_run": "2026-07-10T21:00:14", "profile": "position-analyst" }, { @@ -2448,7 +2522,7 @@ "script": "branch_scanner.py", "schedule": "15,30,45,00 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:45:53", + "last_run": "2026-07-13T11:45:41", "profile": "position-analyst" }, { @@ -2466,7 +2540,7 @@ "script": "refresh_mtf_cache.py", "schedule": "0 9,11,14 * * 1-5", "status": "ok", - "last_run": "2026-07-09T14:00:38", + "last_run": "2026-07-13T11:00:37", "profile": "position-analyst" }, { @@ -2475,7 +2549,7 @@ "script": "", "schedule": "{'kind': 'cron', 'expr': '*/10 * * * *'}", "status": "ok", - "last_run": "2026-07-10T01:02:23", + "last_run": "2026-07-13T11:50:29", "profile": "default" }, { @@ -2484,7 +2558,7 @@ "script": "refresh_macro_context.py", "schedule": "*/30 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:30:17", + "last_run": "2026-07-13T11:30:38", "profile": "position-analyst" }, { @@ -2493,7 +2567,7 @@ "script": "macro_context_collector.py", "schedule": "*/30 8-16 * * *", "status": "ok", - "last_run": "2026-07-09T16:30:55", + "last_run": "2026-07-13T11:30:34", "profile": "position-analyst" }, { @@ -2502,7 +2576,7 @@ "script": "macro_signal_consumer.py", "schedule": "5,20,35,50 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:51:05", + "last_run": "2026-07-13T11:50:45", "profile": "position-analyst" }, { @@ -2511,7 +2585,7 @@ "script": null, "schedule": "30 8 * * 1-5", "status": "ok", - "last_run": "2026-07-09T08:45:15", + "last_run": "2026-07-13T08:45:59", "profile": "position-analyst" }, { @@ -2520,7 +2594,7 @@ "script": null, "schedule": "30 11 * * 1-5", "status": "ok", - "last_run": "2026-07-09T12:05:13", + "last_run": "2026-07-13T11:37:46", "profile": "position-analyst" }, { @@ -2528,8 +2602,8 @@ "type": "LLM", "script": null, "schedule": "0 10 * * 0,6", - "status": "ok", - "last_run": "2026-07-05T10:09:55", + "status": "error", + "last_run": "2026-07-12T10:00:38", "profile": "position-analyst" }, { @@ -2538,7 +2612,7 @@ "script": "market_screener.py", "schedule": "35 15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:35:38", + "last_run": "2026-07-10T15:35:35", "profile": "position-analyst" }, { @@ -2547,7 +2621,7 @@ "script": "market_watch.py", "schedule": "*/10 9-11,13-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:51:15", + "last_run": "2026-07-13T11:50:56", "profile": "position-analyst" }, { @@ -2556,7 +2630,7 @@ "script": "market_watch.py", "schedule": "0,30 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:30:57", + "last_run": "2026-07-13T11:30:54", "profile": "default" }, { @@ -2565,7 +2639,7 @@ "script": null, "schedule": "0 16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:10:57", + "last_run": "2026-07-10T16:12:28", "profile": "position-analyst" }, { @@ -2574,7 +2648,7 @@ "script": "advice_reconciliation.py", "schedule": "0 20 * * 6", "status": "ok", - "last_run": "2026-07-04T20:00:43", + "last_run": "2026-07-11T20:00:52", "profile": "position-analyst" }, { @@ -2582,17 +2656,17 @@ "type": "no_agent", "script": "preflight_verify.py", "schedule": "30 8 * * 1-5", - "status": "ok", - "last_run": "2026-07-09T10:25:00", + "status": "error", + "last_run": "2026-07-13T08:30:55", "profile": "position-analyst" }, { "name": "开盘简报", "type": "LLM", - "script": "generate_report.py opening_brief", + "script": "/home/hmo/MoFin/scripts/generate_report.py opening_brief", "schedule": "35 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:50:00", + "last_run": "2026-07-13T10:18:46", "profile": "position-analyst" }, { @@ -2616,10 +2690,10 @@ { "name": "收盘简报", "type": "LLM", - "script": "generate_report.py closing_brief", + "script": "/home/hmo/MoFin/scripts/generate_report.py closing_brief", "schedule": "10 16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:14:13", + "last_run": "2026-07-10T16:19:13", "profile": "position-analyst" }, { @@ -2628,7 +2702,7 @@ "script": "sync_dashboard.py", "schedule": "55 8 * * *", "status": "ok", - "last_run": "2026-07-09T08:55:22", + "last_run": "2026-07-13T08:55:25", "profile": "default" }, { @@ -2637,7 +2711,7 @@ "script": "data_governance.py", "schedule": "0 10 * * 6", "status": "ok", - "last_run": "2026-07-08T22:55:46", + "last_run": "2026-07-11T10:00:53", "profile": "position-analyst" }, { @@ -2646,7 +2720,7 @@ "script": "collect_evaluation_data.py", "schedule": "30 20 * * 1-5", "status": "ok", - "last_run": "2026-07-09T20:30:56", + "last_run": "2026-07-10T20:30:08", "profile": "position-analyst" }, { @@ -2664,7 +2738,16 @@ "script": "intraday_health_check.py", "schedule": "*/15 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:45:52", + "last_run": "2026-07-13T11:45:41", + "profile": "position-analyst" + }, + { + "name": "盘前全量重评-自选退出", + "type": "no_agent", + "script": "premarket_full_review.py", + "schedule": "10 8 * * 1-5", + "status": "error", + "last_run": "2026-07-13T08:12:46", "profile": "position-analyst" }, { @@ -2673,7 +2756,7 @@ "script": null, "schedule": "30 8 * * 1-5", "status": "ok", - "last_run": "2026-07-09T08:39:00", + "last_run": "2026-07-10T08:40:54", "profile": "default" }, { @@ -2691,7 +2774,7 @@ "script": "market_insight.py", "schedule": "35 15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:35:27", + "last_run": "2026-07-10T15:35:25", "profile": "position-analyst" }, { @@ -2709,7 +2792,7 @@ "script": "hardcode_scanner.py", "schedule": "25 17 * * 1-5", "status": "ok", - "last_run": "2026-07-09T17:26:04", + "last_run": "2026-07-10T17:25:44", "profile": "position-analyst" }, { @@ -2718,7 +2801,7 @@ "script": "strategy_review.py", "schedule": "0 20 * * 1-5", "status": "ok", - "last_run": "2026-07-09T20:00:50", + "last_run": "2026-07-10T20:01:03", "profile": "position-analyst" }, { @@ -2727,7 +2810,7 @@ "script": "strategy-staleness-check.py", "schedule": "0 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:10:25", + "last_run": "2026-07-13T09:24:51", "profile": "position-analyst" }, { @@ -2736,7 +2819,7 @@ "script": "strategy_evaluator.py", "schedule": "0 21 * * 6", "status": "ok", - "last_run": "2026-07-08T22:55:45", + "last_run": "2026-07-11T21:00:58", "profile": "position-analyst" }, { @@ -2745,7 +2828,7 @@ "script": "stale_detector.py", "schedule": "0 21 * * 1-5", "status": "ok", - "last_run": "2026-07-09T21:16:00", + "last_run": "2026-07-10T21:13:00", "profile": "position-analyst" }, { @@ -2754,7 +2837,7 @@ "script": "review_needed_watchdog.py", "schedule": "0,30 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:30:15", + "last_run": "2026-07-13T12:01:03", "profile": "position-analyst" }, { @@ -2763,7 +2846,7 @@ "script": "system_health_check.py", "schedule": "0 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:46:10", + "last_run": "2026-07-13T09:27:06", "profile": "position-analyst" }, { @@ -2772,7 +2855,7 @@ "script": "system_audit.py", "schedule": "30 17 * * 1-5", "status": "ok", - "last_run": "2026-07-09T17:37:16", + "last_run": "2026-07-10T17:35:52", "profile": "position-analyst" }, { @@ -2781,7 +2864,7 @@ "script": "self_todo_executor.py", "schedule": "*/10 8-22 * * 1-5", "status": "ok", - "last_run": "2026-07-09T22:50:25", + "last_run": "2026-07-13T11:50:44", "profile": "position-analyst" }, { @@ -2790,25 +2873,16 @@ "script": "relay_knowledge_report.py", "schedule": "10 22 * * *", "status": "ok", - "last_run": "2026-07-09T22:10:14", + "last_run": "2026-07-12T22:10:40", "profile": "default" }, - { - "name": "自选买入区提醒", - "type": "no_agent", - "script": "stale_push_wlin.py", - "schedule": "1,31 9-15 * * 1-5", - "status": "ok", - "last_run": "2026-07-09T15:31:31", - "profile": "position-analyst" - }, { "name": "自选买入区提醒-盘前午间尾盘", "type": "no_agent", "script": "per_stock_reassess.py", - "schedule": "0 9,12,15 * * 1-5", + "schedule": "0 12,15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:01:32", + "last_run": "2026-07-10T15:01:27", "profile": "position-analyst" }, { @@ -2825,8 +2899,8 @@ "type": "no_agent", "script": "stale_detector.py", "schedule": "30 10 * * 0,6", - "status": null, - "last_run": "None", + "status": "ok", + "last_run": "2026-07-12T10:30:57", "profile": "position-analyst" }, { @@ -2835,7 +2909,7 @@ "script": "clean_watchlist.py", "schedule": "5 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:05:56", + "last_run": "2026-07-13T09:05:15", "profile": "position-analyst" }, { @@ -2844,7 +2918,7 @@ "script": "memory_guardian.py", "schedule": "0 7 * * *", "status": "ok", - "last_run": "2026-07-09T07:01:47", + "last_run": "2026-07-13T07:01:06", "profile": "position-analyst" }, { @@ -2852,8 +2926,8 @@ "type": "no_agent", "script": "memory_guardian.py", "schedule": "0 7 * * *", - "status": "error", - "last_run": "2026-07-09T07:02:13", + "status": "ok", + "last_run": "2026-07-11T07:02:11", "profile": "default" }, { @@ -2862,7 +2936,7 @@ "script": "capital_flow_collector.py", "schedule": "1,31 9-15 * * 1-5", "status": "ok", - "last_run": "2026-07-09T15:31:18", + "last_run": "2026-07-13T11:31:36", "profile": "position-analyst" }, { @@ -2871,7 +2945,7 @@ "script": "divergence_detector.py", "schedule": "*/30 8-15 * * *", "status": "ok", - "last_run": "2026-07-09T15:30:16", + "last_run": "2026-07-13T11:30:34", "profile": "position-analyst" }, { @@ -2880,7 +2954,7 @@ "script": "divergence_detector.py", "schedule": "30 8-16/2 * * 0,6", "status": "ok", - "last_run": "2026-07-05T16:30:50", + "last_run": "2026-07-12T16:30:18", "profile": "position-analyst" }, { @@ -2889,7 +2963,7 @@ "script": "verify_reassess_pipeline.py", "schedule": "*/30 9-16 * * 1-5", "status": "ok", - "last_run": "2026-07-09T16:30:53", + "last_run": "2026-07-13T11:30:33", "profile": "position-analyst" }, { @@ -2898,7 +2972,7 @@ "script": null, "schedule": "28 9 * * 1-5", "status": "ok", - "last_run": "2026-07-09T09:59:11", + "last_run": "2026-07-10T09:47:29", "profile": "default" } ]