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 表示排名停滞;为负表示相对位置在滑落。它天然剔除了大盘整体涨跌的影响,只保留板块之间的相对轮动信息。
计算实现:从日线数据到轮动强度序列
下面给出可直接运行的 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(走弱) | 12 | 8% | −0.6% |
| 0 ~ 1.5(平稳) | 38 | 25% | +0.2% |
| 1.5 ~ 3(加速) | 61 | 40% | +0.9% |
| ≥ 3(强加速) | 41 | 27% | −0.4% |
这张表本身就是本例要观察的“分布特征”:追高信号明显向加速区间聚集,说明轮动加速确实是追高行为的高发环境;但强加速区间的后续超额转负,提示“加速到极致”时追高的性价比下降。这正是后续案例要深入拆解的风险点,本例只负责把指标算出来、把信号筛出来、把分布看清楚。
rank 列是否恰好是 1 到板块数的排列;其二,取一个排名从第 20 名升到第 5 名的板块,手算 (20−5)/5 = 3,与代码输出比对。两项一致即可认为计算链无误。RSI_rot 噪声大;K 过大则平滑过度,加速信号滞后。建议先用 N=20、K=5 建立基线,再在后续案例中做参数敏感性对比,不要在同一份统计里混用不同参数。