Files
MoFin/docs/cron-architecture-review-20260811.md
T

14 KiB
Raw Blame History

MoFin Cron 架构深度审查与重构设计

创建:2026-08-11 | 审查人:小小莫 | 状态: 审查完成 + P0/P1 已执行 背景:新策略(预测超跌反弹 p_oversold)引入前,必须清理 cron 架构的 重复调度、代码分叉、职责混乱问题,让架构清晰可维护。


执行记录(2026-08-11

P0 已执行(消除代码多版本)

动作 commit
根目录 market_watch.py(旧版分叉)→ archive/20260811-cron-cleanup/ refactor: P0清理
deploy/get_realtime_prices.py(死代码)→ archive 同上
promote_candidates.py 备份残留删除 同上
硬链接同步(110 scripts 已验证

P1 已执行(策略扫描器独立调度)

动作 结果
market_watch.py 移除 mr/s2 嵌入(-42 行) 已 push + 246 pull,守卫不再回滚
mr_scanner 独立 jobv_weak扫描-独立,9:35 交易日) hermes cron list 确认
s2_scanner 独立 jobS2恐慌买扫描-独立,9:35 交易日) hermes cron list 确认
market_watch 验证(90 板块 + regime,无 mr/s2 输出) snapshot_id=1548

顶层 jobs 残留处理

  • 16 个 default profile job(调度器 7/23 已死)→ 全部停用
  • 备份:~/.hermes/cron/jobs.json.bak_20260811_top_level_disabled
  • position-analyst65 jobs/ mohe2 jobs)未受影响

P2 已执行(午间重复采集判断)

job 判断 处理
行业富集-cninfo-午间 只补缺失行业映射(幂等去重,早间已补全)→ 冗余 已停用(备份 jobs.json.bak_20260811_sector_noon
基本面刷新-午间 拉实时 PE/PB(随价格变动)→ 有意义 保留

嵌入调用全面扫描

  • 11 个脚本有 subprocess 嵌入调用
  • 仅 market_watch→mr/s2 是架构问题(已修复);其余均为合理工具/流程调用
  • 确认:generate_report(按需触发重评)/ sync_dashboard(包装工具)均职责清晰

工具函数抽取(import 级解耦,2026-08-11

问题s2_scanner import mr_scanner 的工具函数(fetch_tx_klines/calc_ma/calc_rsi/get_stock_pool ——策略扫描器互相 import 是坏味道,新策略会越引越乱。

重构

新模块 内容 来源
indicators.py calc_ma/calc_rsi/calc_atr/calc_obv mr_scanner 抽取
market_data.py fetch_tx_klines/get_stock_pool mr_scanner 抽取

验证:mr/s2 均改为从公共模块 import,语法 OK,运行正常(trend_up/非恐慌日正确跳过),s2 不再 import mr_scanner0 处)。 收益p_oversold 扫描器直接 import indicators/market_data,不依赖任何策略扫描器。

指标函数重复实现扫描(2026-08-11)

模块 函数 判断
market_regime.py calc_ma 🔴 与 indicators.calc_ma 完全相同(纯重复,建议后续统一)
multi_timeframe.py calc_moving_averages ⚠️ 增强版(多窗口 dict 返回),非纯重复
strategy_lifecycle.py calc_atr ⚠️ 不同实现(带 code 拉港股数据),非纯重复

注:market_regime.calc_ma 是唯一纯重复,但改动它需回归 market_regime(运行中), 收益小风险中——记录为后续优化项,不在本次强制重构。核心目标(p_oversold 用公共模块)已达成。

守卫教训(重要)

  • deploy_guard 每 15 分钟回滚 CODE_PATHS 未提交改动(07:00 实测回滚 market_watch
  • 正确流程:本地改 → commit+push → 246 pull(守卫看到 git 干净 → 不回滚)

一、现状全景

1.1 调度系统

调度系统 任务数 说明
hermes 顶层 jobs.json 16 ⚠️ 7/23 起调度器停摆(残留)
hermes position-analyst 63 主调度(活跃)
hermes mohe 2 少量
系统 crontab ~33 ⚠️ 部分与 hermes 重复

1.2 脚本总数

  • deploy/profile-scripts/~100 个 py
  • hermes scripts/:硬链接(sync_profile_scripts.sh 维护)
  • MoFin 根目录:库文件 + 残留

二、核心架构问题

问题 1:策略扫描器嵌入数据采集器(违反单一职责)

现状

market_watch.py(行业板块采集,*/10)
  ├─ 1. 板块数据采集(EM→THS)→ market_snapshots
  ├─ 2. market_regime 计算 → market_regime 表
  ├─ 3. subprocess 调 mr_scanner.pyv_weaktimeout=1500s
  └─ 4. subprocess 调 s2_scanner.pyS2 恐慌买,timeout=1500s

问题

  • market_watch 职责 = 数据采集 + 市场阶段 + 2 个策略扫描,四合一
  • mr_scanner/s2_scanner 无独立调度,只能被 market_watch 触发
  • timeout=1500s(25分钟)嵌入采集器,若超时影响采集
  • 新策略 p_oversold 替换时无处安放(要改 market_watch 还是新建?)

重构方案:策略扫描器独立调度

market_watch.py(纯板块采集,*/10
mr_scanner.pyv_weak,独立 cron 0 9 * * 1-5 或并入扫描调度)
s2_scanner.pyS2 恐慌买,独立 cron
predictive_oversold_scanner.py(新策略,独立 cron
  • 每个扫描器独立 job、独立日志、独立幂等
  • market_watch 只做采集(单一职责)

问题 2:同一脚本多个调度入口

脚本 入口 建议
market_watch.py 顶层(0,30 9-16) + position(*/10) 停顶层(调度器已死)
stale_detector.py 策略评估-每日(21:00) + 周末重评(30 10 0,6) 保留(两用途不同)
memory_guardian.py 顶层 + position 停顶层
cron_to_xmpp.py 顶层(* 9-16) + position(*/5) 停顶层(已停 crontab
divergence_detector.py 工作日(*/30 8-15) + 周末(30 8-16/2) 保留(两用途合理)

问题 3:一份代码多版本(分叉)

文件 副本 状态
market_watch.py MoFin根(旧) vs deploy(新) 分叉,根目录残留
promote_candidates.py docs/backup 残留 备份未清理
self_todo_executor.py deploy vs hermes vs AgentsMeeting ⚠️ 新旧版并存
agents_health_check.py MoFin/AgentsMeeting/self-growing ⚠️ 三项目各自维护

原则(红线)

  • 一份代码只存在于一个 canonical 位置(MoFin git 仓库)
  • deploy/profile-scripts ↔ hermes scripts 用硬链接(已规范)
  • 其他位置(根目录/backup/其他项目)不得有副本

问题 4:健康检查体系过度层级化

现状 8 个健康类脚本

L0: agents_health_checkTier15min
L1: morning_health_check8:00 体检)+ intraday_health_check15min
L1: functional_health_checkL1 功能检查,15min
L1: mofin_healthdashboard 数据,15min
L2: system_hygiene_audit(卫生审计)
L3: self_repairLLM 修复)
L4: meta_watchdog(检查检查的检查)
+ system_audit(全局审计 17:30

问题:8 个脚本职责重叠,互相引用,排查复杂 建议:保留核心 4 层(Tier1/morning+intraday/functional/self_repair),合并冗余


三、逐任务设计文档(分类)

3.1 候选管道(核心链路)

accumulation_scanner*/10)→ candidates(sector=accumulation)
  → candidate_filter*/306阶段评分)
  → promote_candidates*/30RR>=2 + 容量60
  → per_stock_reassess12维重评)→ holding_strategies
盘前: premarket_full_review8:10)→ regenerate_all
脚本 职责 调度 数据流 问题
accumulation_scanner 主力建仓扫描 */10 行情→candidates 与新策略无关,保留
candidate_filter 6阶段过滤 */30 candidates→评分 耦合 accumulation 设计
promote_candidates 候选提拔 */30 candidates→自选 RR>=2 门槛需适配
premarket_full_review 盘前重评 8:10 全量重评 依赖缓存预热

3.2 策略扫描器(问题 1 核心)

脚本 职责 当前入口 重构后
mr_scanner.py v_weak 弱市扫描 嵌入 market_watch 独立 cron
s2_scanner.py S2 恐慌买 嵌入 market_watch 独立 cron
predictive_oversold_scanner 新策略(待建) 独立 cron

3.3 数据采集

脚本 职责 调度 问题
price_monitor 价格(A+港股) hermes */2 9-16 已统一
market_watch 板块 hermes */10 ⚠️ 待拆策略扫描
capital_flow_collector 资金流 1,31 9-15 已修锁
refresh_mtf_cache 多周期缓存 50 7,11,14 已修 flush
fundamentals_refresh 基本面 早/午两次 ⚠️ 午间可停?
sector_enrich_cninfo 行业富集 早/午两次 ⚠️ 午间可停?
macro_context_collector 宏观新闻 */30
refresh_macro_context 宏观上下文 */30
news_collector 新闻 crontab 30 9,13,17
divergence_detector 跨市场背离 */30+周末

3.4 健康自检(问题 4

脚本 职责 调度 保留
agents_health_check Tier1 4服务 */5
morning_health_check 每日体检 8类40项 8:00
intraday_health_check 盘中自检 */15
functional_health_check L1 功能 */15
mofin_health dashboard 数据 */15
self_repair L3 LLM 修复 */30
meta_watchdog L4 元监控 5min
system_hygiene_audit 卫生审计 8:20 ⚠️ 与 system_audit 重叠
system_audit 全局审计 17:30 ⚠️ 与 hygiene 重叠
system_health_check 传统检查 已停 可归档

3.5 报告简报

脚本 职责 调度 备注
opening_brief/closing_brief 开/收盘简报 9:35/16:10
market_insight 知微洞察 15:35
strategy_review 策略复盘 20:00
strategy_evaluator 策略评估 每周/每日 ⚠️ 每日版可停
collect_evaluation_data 评估数据 20:30
prepare_report_data 报告数据 周四

3.6 自成长

脚本 职责 调度 备注
branch_scanner 分支自成长 15min
prune_branches 分支剪枝 21:00
meta_growth 元自成长 0:45/12:45
hardcode_scanner 硬编码扫描 17:25

3.7 系统维护

脚本 职责 调度 备注
deploy_guard 部署守卫 */15 核心
fix_gateway_port gateway 看门狗 10min 核心
agent_spiral_watchdog 螺旋监控 */10
db_daily_backup DB 备份 7:50
vacuum_state_db state.db 整理 周六
system_audit 全局审计 17:30

四、重构方案(待老莫批准)

4.1 立即执行(低风险)

  1. 停顶层 jobs.json 残留(16个 job 调度器已死)——enabled=False 或确认清理
  2. 清理 market_watch.py 根目录分叉(旧版移 archive
  3. 清理 promote_candidates.py backup 残留
  4. 统一 agents_health_check(确认三项目各自维护是否必要)

4.2 重构(中等风险,需测试)

  1. 拆 market_watch 策略扫描mr_scanner/s2_scanner 独立调度
  2. fundamentals/sector_enrich 午间版停用(早间足够)
  3. 评估每日版停用(每周版足够)

4.3 为 p_oversold 准备

  1. 新建 predictive_oversold_scanner.py(独立 cron,对齐 accumulation_scanner 模式)
  2. 候选管道适配p_oversold 走专属评估,绕过 RR>=2

4.4 红线(杜绝多版本)

  • 一份代码一个 canonical 位置(MoFin git
  • deploy↔hermes 硬链接(已规范)
  • 根目录不留脚本副本(库文件除外,且必须与 deploy 硬链)
  • 备份不进仓库

五、执行优先级

优先级 动作 风险
P0 停顶层 jobs 残留 + 清 market_watch 分叉
P1 拆策略扫描器独立调度
P2 停午间重复采集
P3 建 p_oversold 扫描器

待老莫确认后分批执行。


六、补充发现(第二轮审查 2026-08-11)

6.1 JSON 引用问题

  • 20 个脚本引用 decisions.json/portfolio.json/watchlist.json,但多数通过 mo_data 兼容层read_decisions/read_portfolio 读 DB)——docstring 是旧注释,实际正常
  • 🔴 get_realtime_prices.py 直接 open('data/decisions.json') —— decisions.json 已删除,运行必报错。死代码(无调度无 import),归档
  • 🔴 import_holding_xls.py 有注释掉的旧 JSON 写操作(无影响)

6.2 死代码/残留清单

文件 状态
get_realtime_prices.py 死代码(读已删JSON),归档
market_watch.pyMoFin根) 旧版分叉,归档
promote_candidates.pydocs/backup 备份残留,清理
system_health_check.py 已暂停,被替代,归档
session_to_cron_bridge.py 已停 crontab(顶层cron停摆)
cron_to_xmpp.py crontab版 已停(hermes版保留)

6.3 自成长类确认

脚本 职责 状态
branch_scanner 分支数据采集 活跃(15min
branch_evaluator 分支适用性评估 读 DBmo_data
prune_branches 剪枝 活跃(21:00
meta_growth 元层自成长 活跃(0:45/12:45
hardcode_scanner 硬编码扫描 活跃(17:25

6.4 报告简报类确认

脚本 职责 状态
opening/closing_brief 开/收盘简报 wrapper
generate_report 模板报告生成器
market_insight 知微洞察
strategy_review 三层复盘
strategy_evaluator 双维度评估 ⚠️ 每日版可停
collect_evaluation_data 评估数据采集
prepare_report_data 报告参数
advice_reconciliation 建议对账 读DB