Files
tick-stock-panel/docs/market-phase.md
T
shy3130 697c27bb02 feat(v0.2): 市场阶段与主线识别 + 因子挖掘全链路 + 数据层完善
- 市场环境: 新增情绪周期6阶段(冰点/启动/主升/高潮/退潮/修复, 连板梯队驱动,
  EMA平滑+2日确认+弱档否决, 平均段长9.7天)与概念/行业主线排名(涨停梯队聚合,
  可配置宽基/风格标签过滤); 市场环境页重构, regime 透明加列, 与5档state并存
- 挖掘: 因子与策略挖掘全链路(API/worker/进程锁/候选库/前端工作台/文档),
  周度调度默认关闭且永不自动发布
- 回测: 财务快照因子(点时口径), 批量回测预计算共享下期收益,
  信号路径矩阵列依赖展开修复(consecutive_limit_ups 缺列报错)
- 数据/性能: enriched 生成与预热治理, 重任务限流, 行情/K线缓存复用, 时区修复
- 测试: 后端全量 914 通过; GUI 黑盒验证截图存证 gui-test-screenshots/
2026-08-16 23:39:07 +08:00

96 lines
7.6 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.
# 市场阶段(情绪周期)与主线识别
本文说明市场环境页的阶段体系与主线识别的口径、阈值来源、持久化设计、已知偏差与运行方式。它与原有的 5 档环境 state 并存,不替代任何既有消费方。
## 功能边界
阶段体系回答"市场处于情绪周期什么位置",主线识别回答"当前/某阶段内什么板块概念在领涨"。两者都只用本地已存储数据(`consecutive_limit_ups``amount`、概念映射快照),不依赖扩展数据源,2020-08 起全历史可回算。
明确不做的:
- 挖掘、回测环境过滤、因子 regime 统计仍用原 5 档 `state`,本期不切换到阶段体系。
- 概念成分是当前快照,不改成 timeseries 积累模式(见「快照回填偏差」)。
- 不生成任何交易信号;阶段与主线仅供研究分析。
## 与 5 档 state 的关系
| | `state`(原有) | `phase`(本期新增) |
|---|---|---|
| 驱动量 | 赚钱/投机/抗跌/趋势 4 维综合分 | 连板梯队:高度、宽度、晋级率、梯队完整度 |
| 档位 | 强势/偏强/震荡/偏弱/弱势(5 档) | 冰点/启动/主升/高潮/退潮/修复(6 阶段) |
| 消费方 | 回测环境过滤、挖掘、策略页 | 市场环境页分析与主线识别 |
| 持续性 | 日频打分,切换频繁(历史 76.6% 天数发生切换,平均段长 1.1-1.5 天) | EMA 平滑 + 2 日确认,平均段长 9.7 天 |
`state`/`score` 列原样保留,新列(`phase``first_board``ge2_count``ge3_count``ge5_count``ladder_completeness``promo_rate``promo_pool`)对既有消费方透明。
## 每日梯队指标
全部由已存储的 `consecutive_limit_ups` 列向量化派生,实现在 `backend/app/services/market_phase.py`
- `first_board`:首板(1 连板)家数。
- `ge2_count` / `ge3_count` / `ge5_count`N 板以上家数(宽度)。
- `promo_rate` 晋级率:昨日连板池今日继续封板的比例。昨日连板数用 `consec.shift(1).over("symbol")` 按个股前一日连接(跨批次边界也正确,`_compute_batch` 在 warmup 截断前计算);池不足 10 家记 `null`(小样本噪声),不填 0。
- `ladder_completeness` 梯队完整度:2..height 档位中非空档位占比;height < 3 时为 `null`
- 高度(`max_consecutive`)与封板率(`seal_rate`)沿用 regime 已有列。
## 阶段规则
词汇与优先级:`climax 高潮 > rally 主升 > ebb 退潮 > ignite 启动 > ice 冰点 > repair 修复(兜底)`。冰点排在退潮前判定——长期死市不应被标成"自高位退潮"。
阈值标定自 2020-08~2026-08 全市场 1454 个交易日的 p10/p60/p90 分位数,全部集中在模块顶部常量,调整只改那里:
| 阶段 | 核心条件(EMA 平滑后) |
|---|---|
| 高潮 climax | ge2 ≥ 50p90 的 2 倍)或首板 ≥ 220(p90 的 2.5 倍),历史占比 <2% |
| 主升 rally | 高度 ≥7 且 ge2 ≥15 且晋级率 ≥0.23(全中位以上);或晋级率 ≥0.30(p85+)配合高度 ≥5、ge2 ≥12 |
| 退潮 ebb | 晋级率 <0.15p20)且宽度自 5 日前高位(ge2>12 或高度>6)回落;或晋级率 <0.13 且封板率 <0.57 双弱 |
| 启动 ignite | 宽度/高度自低位扩张(ge2 较 5 日前 +3 且 ≥8,或高度抬升且 ≥5)且晋级率恢复到 ~0.19-0.20 |
| 冰点 ice | 高度 ≤4、ge2 ≤6、首板 ≤24 同时贴地(均 ~p10) |
| 修复 repair | 兜底 |
**持续性设计**:驱动量先做 EMA 平滑(alpha=1/3,约 5 日),原始标签出来后再做 2 日确认(切换需连续 2 日出现新标签才生效)。
**弱档否决**5 档 `state ∈ {weak, lean_weak}` 时,正向阶段(主升/高潮/启动)一律降为修复。这修复了一类错标:连板梯队强但大盘崩的交易日(如 2024-01 微盘流动性危机)会被梯队指标误判为主升/启动——涨停生态与大盘背离时,以大盘弱势为准。
**回填验收**(1454 天真实数据):平均段长 9.7 天(对比原 5 档的 1.1-1.5 天)。抽查:2024-09-24→10-08 为启动→主升→高潮(九二四行情);2024-01/02 微盘崩为退潮/冰点;高潮 6 年仅 2 段(2024-10-08、2024-10-31 ST 重组潮 17 板),均为真实极端期。
已知特性,如实说明:退潮/冰点天然是短段(平均 2.8/2.5 天)——恐慌释放本身快于趋势形成;修复是占比最高的兜底段(~74% 天数),A股大部分时间没有处于可辨认的周期位置。
## 主线识别
实现在 `backend/app/services/market_mainline.py`。复用 `rps_rotation` 的概念映射加载,窄扫描 `kline_daily_enriched` 的 symbol/date/consecutive_limit_ups/amount 四列,按 (date, 概念/行业) 聚合:
- `limit_up_count` 涨停家数、`ge2_count` 二板以上家数、`max_boards` 最高板、`boards_sum``rungs_filled` 梯队档位数、龙头股(按连板数、成交额排序取第一)。
- 主线分 = 当日截面 rank 归一后 `0.35*涨停数 + 0.25*最高板 + 0.25*梯队档位数 + 0.15*二板宽度`。这是"同板块涨停越多、梯队越完整越是主升主线"判据的直接量化。
- 每概念当日涨停 <3 家不参与排名;每日持久化 top30 到 `data/mainline_history/part.parquet`upsert 按 date+kind 整日替换)。
- 行业维度取前两级(如 `计算机-软件开发`),作为概念维度的交叉验证。
### 宽基/风格标签过滤
融资融券(~7700 家)、沪深股通(~3300 家)这类超大概念会垄断 top1,需要过滤。配置存于用户偏好(`preferences.json`),市场环境页「过滤」面板可改:
- 成员数上限:默认 600,超过视为宽基/风格标签不参与排名(夹取范围 50-5000)。保留华为概念(2006)、人工智能(2166)等真主题。
- 成员数下限:默认 4(夹取 1-200)。
- 名称黑名单:手动屏蔽任意概念,支持逗号/分号/空格分隔。
修改保存后自动触发全量主线重算(`POST /api/regime/mainline/recompute`,秒级)。API 层为 `PUT /api/preferences/mainline-filter`
### 快照回填偏差
概念成分为**当前快照回看历史**(本地自 2026-07 起留存,无历史版本)。新纳入指数或改名的个股会出现在旧时段、成分调整会错归属,因此早年主线存在归属漂移,越近越准。此口径限制以 `membership_note` 字段随 API 返回并在页面展示。若后续把 ext 概念同步改为按月累积快照,主线历史精度会逐月自然提升。
## API 与运行
- `GET /api/regime/phases?start&end`:连续阶段段列表(阶段、区间、天数、高度/宽度/晋级率/封板率均值、段内 top 主线)。
- `GET /api/regime/mainline?start&end&top&kind`:窗口内主线排行(top1 天数、日均分、最高板)与每日明细。
- `POST /api/regime/mainline/recompute`:过滤配置变更后的全量重算(两类维度)。
- `POST /api/regime/recompute`:扩展为重算 regime 后自动重标 phase 并回填主线。
- daily pipeline 在 regime 步骤后追加主线增量(复用 `pipeline_regime_enabled` 开关,软失败不阻塞)。
阶段标签由 `regime_builder.refresh_phase_labels` 在每次 regime upsert 后对全量历史重标(1454 行,开销可忽略)——因为 EMA 与 2 日确认依赖完整序列。
## 测试
- `backend/tests/test_market_phase.py`:梯队聚合、晋级率(池不足记 null)、梯队完整度、阶段序列规则、弱档否决、持续性(噪声下不出现 1 日翻转)、refresh 往返。
- `backend/tests/test_market_mainline.py`:概念/行业聚合、宽基过滤、黑名单、最少涨停家数、同日 upsert 替换、增量补齐、偏好读写与夹取。