Files
MoFin/docs/SYSTEM_ARCHITECTURE.md
T

225 lines
16 KiB
Markdown
Raw 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.
# MoFin 系统架构(3+1 Cron 层次 · 3+1 环节)
> 版本:2026-08-12 维护:小小莫(Sisyphus
> 定位:**系统架构权威文档**——3+1 cron 层次 + 3+1 环节 + cron 体系统一 + 开发原则。
> 区别于方法论(3+6+12 研究方法,见 docs/research/methodology.md):本文档管**系统怎么跑**,方法论管**策略怎么研究**。
---
## 一、3+1 Cron 层次(系统架构主干)
```
┌─────────────────────────────────────────────────────┐
│ L1 数据采集层(原始数据,不重复不缺失,各司其职) │
│ 外部 API/行情/新闻/基本面 → 原始表 │
├─────────────────────────────────────────────────────┤
│ L2 数据加工层(衍生数据,不采集不使用) │
│ 原始数据 → 技术指标/行业指数/分位/多周期 → 衍生表 │
├─────────────────────────────────────────────────────┤
│ L3 数据使用层(只读数据,不采集不现算) │
│ 衍生数据 → 扫描/重评/候选/推荐 → 业务结果 │
├─────────────────────────────────────────────────────┤
│ L4 监控运维层(健康/审计/备份/推送/自修复) │
│ 贯穿三层的健康监控与系统自愈 │
└─────────────────────────────────────────────────────┘
```
**核心规则**
- **能拉取的拉取(采集层),拉不了的才自己算(加工层)**——同一数据不重复来源
- **统一规范,不遗漏不重复**——指标单一权威算法,数据按层存储
- **使用层只使用数据,不采集数据**——扫描器/重评只读加工层预算值
## 二、3+1 环节(业务产出)
| 环节 | 本质 | 核心 cron(使用层) |
|------|------|---------------------|
| **选股**(入自选) | 扫描器选候选→过滤→提拔→入自选 | predictive_oversold_scanner(p_oversold) / mr_scanner(v_weak) / accumulation_scanner → candidate_filter → promote_candidates |
| **买入**(盘中重评→买入推荐) | 盘中根据策略区间触发重评,维持买入建议→发买入推荐 | stale_push_wlin*/30 盘中,自选买入区提醒+触发重评,2026-08-12 恢复注册) |
| **卖出**(盘中重评→卖出推荐) | 盘中根据策略区间触发重评,维持卖出建议→发卖出推荐 | **price_monitor**(*/2 盘中,止盈区间/止损区间/移动止损/v_combo 波段出场 swing_out/swing_re/破止损操作信号) |
| **每日重评**(盘后移除) | 盘后移除"不再具有近期投资价值"的票 | watchlist_auto_exit50 8 盘前自选退出,2026-08-12 迁移到 hermes / clean_watchlist5 9 开盘前清理) / premarket_full_review10 8 盘前全量,已修) / per_stock_reassess0 12,15 自选12维重评,已恢复) / stale_detector(周末批量) |
> **关键区分(老莫纠正 2026-08-12)**:买入和卖出**本质一样**——都是**盘中重评**(根据策略区间触发,维持操作建议→发买入或卖出推荐,stale_push_wlin 买入 + price_monitor 卖出/止损止盈一体)。**每日重评是盘后**(移除不再有价值的票,watchlist_auto_exit/clean_watchlist/premarket/per_stock/stale_detector)——盘后移除 ≠ 盘中卖出推荐。
## 三、环节 × 层次 Cron 映射(当前实际)
### L1 数据采集层
| cron | 调度 | 数据 |
|------|------|------|
| market_watch.py | `*/10 9-11,13-15 * * 1-5` | 板块快照 market_snapshots + 大盘 regime |
| price_monitor.py | `*/2 9-16 * * 1-5` | 实时价 live_pricesDB 唯一价格源) |
| capital_flow_collector.py | `1,31 9-15 * * 1-5` | 资金流 stock_capital_flow(⚠️ ERROR 待修) |
| macro_context_collector.py | `*/30 8-16 * * *` | 宏观新闻 macro_raw_news |
| refresh_macro_context.py | `*/30 9-15 * * 1-5` | 宏观上下文 macro_context_log |
| collect_evaluation_data.py | `30 20 * * 1-5` | 策略评估数据 |
| refresh_mtf_cache.py | `50 7,11,14 * * 1-5` | 多周期 mtf_cache(兼加工) |
| fundamentals_refresh.py | `52 7 * * 1-5` | 基本面 stock_fundamentals(早间,持仓/自选) |
| sector_enrich_cninfo.py | `50 7 * * 1-5` | 行业富集 sector_snapshots(早间) |
| **daily_kline_sh/sz.py** | `10/25 16 * * 1-5` | **全市场日K stock_daily**2026-08-12 新增) |
| **news_collector_full_b0-3.py** | `30-0 7-8 * * 1-5` | **全市场新闻 stock_news**(新增) |
| **fundamentals_full_refresh.py** | `35 16 * * 1-5` | **全市场基本面 stock_fundamentals**(新增) |
### L2 数据加工层
| cron | 调度 | 产物 |
|------|------|------|
| **factor_engine.py** | `5 17 * * 1-5` | **技术指标 stock_indicators(26项) + 大盘 market_indicators + mcap_q/pe_q 分位**(新增) |
| **sector_index_builder.py** | `0 17 * * 1-5` | **行业指数 sector_index_dailystock_sectors_em 聚合 307 行业)**(新增) |
| refresh_mtf_cache.py | `50 7,11,14 * * 1-5` | 多周期均线 mtf_cache |
### L3 数据使用层
| 环节 | cron | 调度 |
|------|------|------|
| 选股 | predictive_oversold_scanner.py | `35 9 * * 1-5` |
| 选股 | mr_scanner.py (v_weak) | `35 9 * * 1-5` |
| 选股 | accumulation_scanner.py | `*/10 9-15 * * 1-5` |
| 选股 | candidate_filter.py | `*/30 9-15 * * 1-5` |
| 选股 | promote_candidates.py | `*/30 9-15 * * 1-5` |
| **买入**(盘中重评→买入推荐) | **stale_push_wlin.py** | `*/30 9-15 * * 1-5`(自选买入区提醒+触发重评) |
| **卖出**(盘中重评→卖出推荐) | **price_monitor.py** | `*/2 9-16 * * 1-5`(止盈/止损/移动止损/波段出场/破止损信号) |
| 每日重评 | **watchlist_auto_exit.py** | `50 8 * * 1-5`(盘前自选退出) |
| 每日重评 | clean_watchlist.py | `5 9 * * 1-5`(开盘前自选清理) |
| 每日重评 | **premarket_full_review.py** | `10 8 * * 1-5`(盘前全量重评-自选退出,已修) |
| 每日重评 | **per_stock_reassess.py** | `0 12,15 * * 1-5`(自选 12 维重评+买入区提醒,已恢复) |
| 每日重评 | strategy-staleness-check.py | `0 9 * * 1-5` |
| 每日重评 | stale_detector.py | `30 10 * * 0,6`(周末批量) |
### L4 监控运维层
morning_health_check(0 8) / preflight_verify(30 8) / intraday_health_check(*/15) / mofin_health(*/15) / functional_health_check(*/15) / system_audit(30 17) / system_hygiene_audit(20 8) / hardcode_scanner(25 17) / verify_reassess_pipeline(*/30) / data_governance(0 10 周六) / memory_guardian(0 7) / meta_watchdog(5 * * * *) / self_repair(*/30) / agent_spiral_watchdog(*/10) / deploy_guard(*/15) / self_todo_executor_v2(*/10) / db_daily_backup(50 7) / vacuum_state_db(0 3 周六) / fix_gateway_port(10m) / cron_to_xmpp(*/5) / opening_brief(35 9) / closing_brief(10 16) / market_insight(35 15) / macro_signal_consumer / divergence_detector(*/30) / strategy_evaluator(0 21 周六) / advice_reconciliation(0 20 周六) / prepare_report_data(0 20 周四)
## 四、数据流(采集 → 加工 → 使用)
```
腾讯/东财/THS/akshare API
↓【L1 采集】
stock_daily(K线) / stock_news(新闻) / stock_fundamentals(基本面)
stock_capital_flow(资金流) / market_snapshots(板块) / sector_index_daily(行业)
↓【L2 加工】
stock_indicators(技术指标26项) / market_indicators(大盘) / sector_index_daily(行业指数)
mtf_cache(多周期) / mcap_q/pe_q(分位)
↓【L3 使用】
扫描器(p_oversold/v_weak/accumulation) → candidates
→ candidate_filter → promote_candidates → watchlist_stocks(自选)
重评(premarket/per_stock) → 更新策略 / 移除自选
↓【L4 监控】
mofin_health(健康采集) → F健康 Dashboard(三层架构健康 + cron来源标记)
```
## 五、Cron 体系统一(强制开发原则)
> 🚫 **自动任务必须部署在 hermesposition-analyst),严禁使用系统 crontab。**
- **唯一体系**hermes cron`/home/hmo/.hermes/profiles/position-analyst/cron/jobs.json`
- **禁止**:系统 crontab 部署 MoFin 自动任务(避免新旧一起跑、状态不可见、无单例守卫)
- **历史迁移**watchlist_auto_exit / kanban_xmpp_bridge / parallel_batch / live_data_collector 已于 2026-08-12 从系统 crontab 迁移到 hermesnews_collector(旧版) / agents_health_check(MoFin) 已停用(与 hermes 重复)
- **监控**:F 健康 cron 列表带**来源标记**(✅ hermes 合规 / ⚠️ 系统cron 违规红色警告),顶部横幅提示本原则
- **备份**:系统 crontab 备份在 `.backups/crontab_backup_*.txt`
## 五.5 温区自适应系统(2026-08-13 落地)
> **核心**:策略组合按当前市场温区(trend_up/choppy/trend_down)自动激活/休眠,选股/买入/卖出/每日重评四环节按温区感知执行。
### 温区三态判定
- **market_regime.py**:三态判定(trend_up=above_ma20+adx≥20 / choppy=adx<20 / trend_down=below_ma20+adx≥20),回填 10 年(2016-20262319 条)
- **regime_tracker.py**:滞回平滑(K=5 连续确认,数据选参:112周期/20.7天/无1天噪音),输出平滑温区 + regime_cycles 表
- **temp_band.py**:温度分档(panic/fear/neutral/greed/euphoriarsi 连续量),仓位乘数(恐慌重仓/亢奋减仓)
### 策略-温区表现记录
- **regime_perf.py**`strategy_regime_perf` 表(策略×温区×胜率/均盈/样本),全策略动态纳入(含历史策略)
- **发现**v_mr_sel trend_down 93%、v7.3 trend_up 94%、v6.2 82% 等被埋没的温区强者
### 策略动态路由
- **strategy_router.py v5**:动态策略库,当前温区实测胜率高者激活(>=50% 门槛剔除全负策略)
- 输出 `strategy_weights.json`(当前温区/温度/各策略权重/激活状态)
### 策略执行调度
- **strategy_executor.py**:温区策略调度器(*/30 盘中),按当前温区激活策略调度对应选股 scanner:
- v_weak/v_mr/v_mr_sel → mr_scanner.py
- v_oversold → predictive_oversold_scanner.py
- s2_panic → s2_scanner.py
- v_next4/v8.1/v_combo → leader_scanner.pytrend_up 适用)
- **停用独立 scanner cron**mr_scanner/predictive_oversold 已由调度器统一调度)
### 四环节温区感知
| 环节 | 温区接入 |
|------|---------|
| **选股** | strategy_executor 按温区激活策略调度 scanner;scanner 内部用平滑温区门控 |
| **买入** | stale_push_wlin 温区过滤(非激活策略不推买入)+ 信号溯源([策略][温区]+共振标记) |
| **卖出** | price_monitor 温区感知(非激活策略买入机会抑制,风控卖出/止盈仍推)+ 信号溯源 |
| **每日重评** | strategy_lifecycle 平滑温区(regime_gate)→ timing_signal 合成含市场阶段 |
### 信号溯源系统
- **signal_ledger.py**:记录每次推送(策略/版本/温区/原因),多策略同推检测共振标记(🔥加关注)
-`signal_ledger`code/strategy/regime/pushed_at/resonance_count 等)
### Cron 调度链(温区自适应)
| 时间 | 任务 | 作用 |
|------|------|------|
| 16:50 | market_thermometer.py | 市场测温(三态判定) |
| 16:52 | regime_tracker.py | 滞回平滑(K=5+ regime_cycles 周期记录 |
| 16:55 | strategy_router.py | 策略路由(strategy_weights.json |
| */30 盘中 | strategy_executor.py | 按激活策略调度选股 scanner |
| 周五 17:00 | strategy_alert.py | 三振出局失效预警(滚动胜率/盈亏比) |
## 五.6 港股接入(多市场支持,2026-08-14 落地)
参照 A 股全链路接入港股(港股通范围)。设计原则:**不另起炉灶**——复用 A 股代码结构,市场差异点收敛到市场抽象层;**币种统一**——个股存原币(港股 HKD),计算/汇总统一转 CNY。
### 市场抽象层(market_config.py,唯一事实源)
所有市场判断/符号映射收敛于此,替代原先散落 6 处的各自实现:
| 接口 | 作用 | 规则 |
|------|------|------|
| `market_for_code(code)` | 市场判断 | 5位0/1开头 → `hk`6位 → `a`(委托 mo_models.is_hk_stock |
| `kline_symbol(code)` | 行情/K线符号 | `600519`→sh、`000001`→sz、`00700`→hk |
| `MARKETS` dict | 市场配置 | index_code / currency / has_price_limit / trading_hours(港股含午休 12:00-13:00 |
| `is_trading_now(market)` | 交易时段 | A股 9:30-11:30/13:00-15:00,港股 9:30-12:00/13:00-16:00 |
| `get_regime_temp(code)` | 温区+温度溯源 | 按标的市场返回(A股=smoothed 顶层,港股=markets.hk |
### 数据层
- **港股通名单**hk_connect_list.py → hk_connect_stocks 表):东财 MK0146 板块(push2delay 镜像,主 host push2 对 246 封禁),620 只标的,支持调入/调出检测,周级刷新。**港股通名单本身是数据层定期采集数据**(老莫定)
- **股票池**`get_stock_pool(market='a'|'hk'|'all')` 参数化(默认 'a' 行为不变;'hk'=港股通名单+港股持仓/自选)
- **港股日K**daily_kline_collector hk 批(腾讯 hk 前缀,入 stock_daily,与 A 股同表靠 code 长度区分)
### 温区双市场
- **market_regime 表**(date, market) 联合主键,同日 A/港股各一条(迁移脚本 migrate_regime_market.py4 表加 market 列+备份)
- **温区判定**compute_regime 按市场用对应指数(A股 sh000001 / 港股 hkHSI 恒生指数)
- **温度/平滑/归因**temp_band、regime_tracker、regime_perf 全部 market 参数化
- **恒指历史**hkHSI 回填 12 年(2014 起,3005 条日K + 2975 条温区)
- **向后兼容**market_regime_smoothed.json 顶层键= A 股(既有消费方 regime_gate/strategy_router 不受影响),markets dict 含双市场详情
### 币种规范(v3 重申)
- **个股一律存原币**:港股 price/cost/mv 存 HKD 原值,A 股存 CNY
- **汇总统一折算**:市值/盈亏/总资产经 mo_models.to_cny/calc_total_mv 转 CNY
- **价格比较用原值**:止损止盈/目标价与行情源(HKD)单位一致,不折算
- **显示区分币种**:港股价格带 HKD/HK$ 标识
### 现状与边界
已落地:港股通名单采集、港股日K、温区双市场(A股 trend_down / 港股 trend_up 已验证相反)、温区感知买卖/重评、币种规范。
**待落地**(依赖港股策略):strategy_router 按市场激活、港股全市场选股(scanner 扫港股通池需先有港股策略)。
**不做**:港股资金流/板块 enrichmentcninfo/sina 不支持港股)、TDX relay(已归档)。
## 六、开发原则(自动任务强约束)
1. **单例守卫**:每个定时脚本必须 `_singleton_guard`fcntl flock /tmp/mofin_locks/),防重复实例并发写(2026-08-05 进程堆积事故后统一加装)
2. **600s 护栏**hermes child_timeout 内完成;超时任务分批(如 daily_kline 分 sh/sz、news_collector_full 分 4 批)
3. **幂等**:数据写入用 `INSERT OR REPLACE`(同 key 覆盖,重跑安全);候选扫描当日幂等(同股30日去重+当天已扫跳过)
4. **限速防封**:外部 API 请求间隔(腾讯/东财 0.05-0.5s),批量上限(腾讯 100 只/批)
5. **git 版本管理**:改动必须 commit 入库(deploy_guard 回滚机制);**脚本文件不删除**(保留作参考,停 cron 即可),crontab/cron 变更留备份
6. **统一 hermes**:自动任务只部署 hermes(见第五节)
7. **口径一致**:指标用 backtest_framework 权威算法(回测实盘同口径),使用层读加工层预算值,不现算
---
> 关联文档:方法论 docs/research/methodology.md3+6+12 研究方法)| 数据模型 portfolio-data-model.md 系统梳理 system-architecture-review-20260812.md(三层架构补缺过程)