2. 板块轮动强度指标计算与追高信号初筛

轮动强度指标:用“滚动排名变化”刻画板块相对强弱

追高风险的核心前提是“板块正在被资金快速推高”。但单看板块涨幅无法区分“持续强势”与“短期加速”。本例用相对大盘超额收益的滚动排名变化构造轮动强度指标:先算每个板块相对基准指数的超额收益,再在横截面上做滚动排名,最后用排名的变化速度衡量轮动是否在加速。

指标定义(示例约定,方向统一为“数值越大越强”):

  • 超额收益:excess[t] = 板块日收益率[t] − 基准日收益率[t],基准取沪深300或中证全指,全篇保持一致。
  • 滚动累计超额:cum_excess[t] = Σ excess[t−N+1 … t],窗口 N 取 20 个交易日,代表近一个月的相对强弱。
  • 横截面排名:每日对所有板块按 cum_excess 降序排名,第 1 名为最强,记为 rank[t]。
  • 轮动强度:RSI_rot[t] = (rank[t−K] − rank[t]) / K,K 取 5 个交易日。排名从第 20 名升到第 5 名,则 RSI_rot = (20−5)/5 = 3,表示平均每日前进 3 名。

这样定义的好处是:RSI_rot 为正且数值越大,说明板块在横截面上的相对位置正在快速上移,属于“轮动加速”;接近 0 表示排名停滞;为负表示相对位置在滑落。它天然剔除了大盘整体涨跌的影响,只保留板块之间的相对轮动信息。

板块日线数据 收盘价 / 日收益率 约 30 个行业板块 基准指数 沪深300 日收益率 超额收益 excess = 板块 − 基准 逐日对齐 20日滚动累计 cum_excess 近一月相对强弱 横截面排名 每日按 cum_excess 降序 rank = 1 为最强 轮动强度 RSI_rot = (rank[t−5]−rank[t])/5 排名前进速度 初筛判定 RSI_rot ≥ 1.5 → 轮动加速 0 ≤ RSI_rot < 1.5 → 平稳 RSI_rot < 0 → 相对走弱 排名轨迹与轮动加速识别(示例数据,非实测) 第1名 第30名 交易日 t 板块A:排名快速前移 板块B:排名停滞 板块C:排名下滑 轮动加速区间

计算实现:从日线数据到轮动强度序列

下面给出可直接运行的 Python 实现。输入为宽表:行是交易日,列是板块名称,值为收盘价;基准为单独一列。代码不依赖前文,可独立执行。

import numpy as np
import pandas as pd

def rotation_strength(close_wide: pd.DataFrame,
                      bench_close: pd.Series,
                      N: int = 20,
                      K: int = 5) -> pd.DataFrame:
    """
    close_wide : 行=交易日, 列=板块, 值=收盘价
    bench_close: 基准指数收盘价, 与 close_wide 索引对齐
    返回: 每个板块每日的 RSI_rot
    """
    # 1) 日收益率
    ret = close_wide.pct_change()
    bench_ret = bench_close.pct_change()

    # 2) 超额收益(逐日对齐)
    excess = ret.sub(bench_ret, axis=0)

    # 3) 20日滚动累计超额
    cum_excess = excess.rolling(N).sum()

    # 4) 横截面排名:每日降序,第1名最强
    rank = cum_excess.rank(axis=1, ascending=False, method="min")

    # 5) 轮动强度:排名前进速度
    rsi_rot = (rank.shift(K) - rank) / K
    return rsi_rot

# ---- 示例调用(数据需自行准备,此处仅示意结构)----
# close_wide = pd.read_csv("sector_close.csv", index_col=0, parse_dates=True)
# bench_close = pd.read_csv("bench_close.csv", index_col=0, parse_dates=True).iloc[:, 0]
# rsi = rotation_strength(close_wide, bench_close, N=20, K=5)
# accel = rsi[rsi >= 1.5]   # 轮动加速初筛

几个实现细节值得注意:rank 使用 method="min" 处理并列,保证排名为整数;shift(K) 取的是 K 个交易日前的排名,因此前 K 行 RSI_rot 为 NaN,属于正常预热期;cum_excess 用滚动求和而非复利,便于横截面比较,若改用复利需保证各板块窗口一致。

初筛与信号分布观察

得到 RSI_rot 后,按阈值做初筛。示例阈值取 1.5,含义是“近 5 个交易日平均每日排名前进 1.5 名以上”。阈值不是固定真理,应结合板块数量调整:板块越多,排名跨度越大,同一阈值越容易触发。一个可操作的校准方式是取 RSI_rot 历史分布的 80% 分位数作为加速线。

初筛之后,把“追高信号”定义为:板块当日涨幅位于全市场前 10%,且 RSI_rot ≥ 1.5。然后按 RSI_rot 分箱统计追高信号的分布,观察信号是否集中在轮动加速期。示例统计表结构如下(数值为示例,需用真实数据重算):

RSI_rot 区间追高信号数占比信号后 5 日平均超额
< 0(走弱)128%−0.6%
0 ~ 1.5(平稳)3825%+0.2%
1.5 ~ 3(加速)6140%+0.9%
≥ 3(强加速)4127%−0.4%

这张表本身就是本例要观察的“分布特征”:追高信号明显向加速区间聚集,说明轮动加速确实是追高行为的高发环境;但强加速区间的后续超额转负,提示“加速到极致”时追高的性价比下降。这正是后续案例要深入拆解的风险点,本例只负责把指标算出来、把信号筛出来、把分布看清楚。

验证指标是否算对,可用两个自检:其一,任取一天,检查 rank 列是否恰好是 1 到板块数的排列;其二,取一个排名从第 20 名升到第 5 名的板块,手算 (20−5)/5 = 3,与代码输出比对。两项一致即可认为计算链无误。
滚动窗口 N 与排名步长 K 会显著改变指标灵敏度。N 过短会让排名频繁跳动,RSI_rot 噪声大;K 过大则平滑过度,加速信号滞后。建议先用 N=20、K=5 建立基线,再在后续案例中做参数敏感性对比,不要在同一份统计里混用不同参数。