斜率动量指标详解
一、什么是斜率动量指标?
斜率动量指标(Slope Momentum)是一种量化投资中常用的趋势强度指标,通过线性回归分析价格走势的"斜率"来评估资产的动量。相比简单的价格涨跌幅,斜率指标能更科学地捕捉趋势的
方向
、
速度
和
稳定性
。
核心思想
将资产价格走势看作一条"趋势线",通过以下两个维度评估:
斜率(Slope)
:反映价格上涨或下跌的速度(趋势方向和强度)
拟合优度(R²)
:反映价格走势与趋势线的贴合程度(趋势稳定性)
最终的斜率动量得分 =
年化收益率
×
R²
,既考虑了收益率,又考虑了趋势的确定性。
二、计算步骤详解
第一步:数据准备
python
# 获取指定周期的收盘价数据
close_prices
=
df[
'close'
].values[
-
momentum_period:]
说明
:提取最近 N 天(
momentum_period
)的收盘价数据,确保按时间顺序排列(最旧→最新)。
第二步:对数转换
python
y
=
np.log(close_prices)
x
=
np.arange(
len
(y))
为什么使用对数?
对数收益率具有
时间可加性
:连续多天的对数收益率可以直接相加
对数转换能更好地处理
复利效应
,让价格变化更符合正态分布
例如:价格从 100 → 110 → 121,对数收益率分别为 9.53% 和 9.53%,直接相加得到总收益
坐标系构建
:
x
:时间序列,[0, 1, 2, ..., N-1]
y
:对数价格,[ln(P₀), ln(P₁), ..., ln(Pₙ₋₁)]
第三步:线性回归拟合
有两种回归方式:
3.1 等权回归
python
slope, intercept
=
np.polyfit(x, y,
1
)
所有数据点的权重相同,平等对待历史和近期数据。
3.2 加权回归
python
weights
=
np.linspace(
1
,
2
,
len
(y))
slope, intercept
=
np.polyfit(x, y,
1
,
w
=
weights)
权重设计
:从 1 线性增长到 2
最旧的数据权重 = 1.0
最新的数据权重 = 2.0
中间数据权重线性插值
加权的意义
:
更重视
近期趋势
,认为最新数据更能代表当前动量
减少远期噪音对趋势判断的影响
适合快速变化的市场环境
回归结果
:
slope
(斜率):每单位时间(天)的对数收益率
intercept
(截距):趋势线的起始点
第四步:计算年化收益率
python
annualized_returns
=
math.exp(slope
*
250
)
-
1
计算逻辑
:
slope
是每天的对数收益率
slope * 250
是一年(250个交易日)的对数收益率
exp(slope * 250) - 1
将对数收益率转换为实际收益率
举例
:
如果
slope = 0.002
(每天0.2%的对数增长)
年化收益率 = exp(0.002 × 250) - 1 = exp(0.5) - 1 ≈ 64.87%
第五步:计算R²(拟合优度)
python
y_pred
=
slope
*
x
+
intercept
# 残差平方和
ss_residual
=
np.sum((y
-
y_pred)
**
2
)
# 总平方和
ss_total
=
np.sum((y
-
np.mean(y))
**
2
)
# R²
r_squared
=
1
-
(ss_residual
/
ss_total)
R² 的含义
:
范围:0 ~ 1
R² = 1
:所有数据点完美落在趋势线上(完美趋势)
R² = 0.8
:80%的价格变化能被趋势解释(强趋势)
R² = 0.3
:仅30%能被解释(弱趋势或震荡)
加权R²
:如果使用加权回归,R²计算也要加权,确保评估标准一致。
第六步:综合评分
python
slope_momentum
=
annualized_returns
*
r_squared
最终得分 = 年化收益率 × R²
举例对比
:
资产
年化收益率
R²
斜率动量得分
特征
A
50%
0.9
0.45
稳定上涨 ✅
B
80%
0.4
0.32
高收益但波动大
C
20%
0.95
0.19
稳定但增速慢
结论
:资产A得分最高,因为它既有不错的收益率,又有很高的趋势稳定性。
三、加权斜率的两个版本:V1 与 V2
平台目前对"加权斜率"(含分时版)提供两个可选版本:下拉框里不带后缀的
加权斜率 / 加权斜率(分时版)
(沿用早期实现,下文称 V1)和带后缀的
加权斜率-V2 / 加权斜率(分时版)-V2
(修正版)。两者的年化收益率计算完全一致,差异仅在
R² 的计算方式
上,但这个差异会直接影响最终得分的正负号,因此有必要单独说明。
3.1 V1 的问题:回归权重与 R² 权重不一致
回顾第三步的加权线性回归:从 1 到 2 线性增长的权重序列
weights
,理论上应该在
整条计算链路
(回归拟合、残差平方和、总平方和、均值)中保持同一套权重口径,才能让 R² 真实反映"加权回归"的拟合优度。
V1 的历史实现中,加权最小二乘回归实际使用的有效权重是线性权重的
平方
(
weights²
),但计算 R² 时的残差平方和、总平方和却直接使用了
未平方
的线性权重,并且用来计算离差的均值
mean(y)
还是
普通算术平均
,并未按权重加权:
python
# V1:回归用 weights²,但 R² 用未平方的 weights,且均值不加权
slope, intercept
=
weighted_polyfit(x, y,
w
=
weights
**
2
)
# 回归:有效权重 = weights²
y_pred
=
slope
*
x
+
intercept
mean_y
=
np.mean(y)
# 均值:未加权(问题点)
ss_residual
=
np.sum(weights
*
(y
-
y_pred)
**
2
)
# R²:权重 = weights(问题点)
ss_total
=
np.sum(weights
*
(y
-
mean_y)
**
2
)
# R²:权重 = weights(问题点)
r_squared
=
1
-
ss_residual
/
ss_total
后果
:回归线是在"
weights²
加权"的意义下拟合出的最优解,但 R² 却是在另一套(
weights
+ 未加权均值)标准下计算的拟合优度,两者不是同一套评价体系。在某些价格走势下,这种口径错位会导致
ss_residual > ss_total
,使
R² 出现负值
。
由于最终得分 = 年化收益率 × R²,一旦 R² 变成负数:
本来处于
稳定上涨
(年化收益率为正)的资产,反而被打出
负分
,在排名中被错误地排到后面
少数
下跌
趋势的资产反而可能因为这种符号错位被打出正分
这就是设计文档中所说的"
动量符号翻转
"问题——不是数值大小的偏差,而是评分方向性的错误,对轮动策略的选股排序有实质影响。
3.2 V2 的修正:统一权重口径
V2 把回归拟合、残差平方和、总平方和、均值这四处计算全部
统一为同一套权重
(
weights²
),包括把均值也改为加权均值:
python
# V2:回归、均值、R² 全部统一使用 weights² 作为权重
w
=
weights
**
2
slope, intercept
=
weighted_polyfit(x, y,
w
=
w)
y_pred
=
slope
*
x
+
intercept
mean_y
=
np.sum(w
*
y)
/
np.sum(w)
# 均值:改为加权均值
ss_residual
=
np.sum(w
*
(y
-
y_pred)
**
2
)
# R²:权重与回归一致
ss_total
=
np.sum(w
*
(y
-
mean_y)
**
2
)
# R²:权重与回归一致
r_squared
=
1
-
ss_residual
/
ss_total
统一口径后,R² 是在与回归拟合
完全相同
的加权标准下计算的拟合优度,不会再出现因权重错位导致的负值和评分符号翻转问题,最终得分更可靠地反映"趋势方向 × 趋势稳定性"。
3.3 如何选择
新建策略
:下拉框中"加权斜率""加权斜率(分时版)"对应 V1(历史实现,为兼容存量策略保留);"加权斜率-V2""加权斜率(分时版)-V2"对应上述修正版。
建议新建策略优先选择 V2
。
已有策略
:已保存策略的动量计算方式、历史回测/实盘表现均不受影响,V1、V2 是两个独立的类型选项,不存在自动升级或覆盖。
两者可同时回测对比
:由于计算逻辑存在差异,同一 ETF 池、同一周期下 V1 与 V2 的净值曲线、收益指标通常会不同,属于预期内的差异,可通过回测直观比较两者表现。
四、等权 vs 加权回归的选择
等权回归
优点
:
全面考虑整个周期的趋势
不容易被短期波动误导
适合识别
中长期趋势
适用场景
:
市场相对平稳
周期较长(如60天、120天)
追求稳健的趋势判断
加权回归
优点
:
对市场变化反应更灵敏
能快速捕捉
趋势转折
更符合"动量延续"的短期特性
适用场景
:
市场快速变化
周期较短(如20天、30天)
需要快速响应趋势变化
实战建议
:
短周期(≤30天):建议使用加权回归
长周期(≥60天):等权回归更稳健
可同时计算两种,构建多维度评分体系
五、在ETF轮动策略中的应用价值
4.1 核心作用:资产排序与筛选
ETF轮动策略的关键是
定期选出最强势的资产
持有。斜率动量指标提供了科学的排序依据:
python
# 计算所有ETF的斜率动量
etf_scores
=
[]
for
etf
in
etf_pool:
score
=
calculate_slope_momentum(etf.data,
period
=
60
)
etf_scores.append({
'etf'
: etf.name,
'score'
: score})
# 按得分排序,选出Top N
top_etfs
=
sorted
(etf_scores,
key
=lambda
x: x[
'score'
],
reverse
=
True
)[:N]
4.2 三大优势
优势1:同时考虑收益与稳定性
传统涨跌幅只看收益率,可能选到"虚高"的资产:
指标
简单涨跌幅
斜率动量
ETF-A:稳定上涨
+30%
0.27
(30% × 0.9)
ETF-B:暴涨后回调
+40%
0.16
(40% × 0.4)
选择结果
❌ 选B
✅ 选A
结论
:斜率动量能过滤掉不稳定的"虚假强势"。
优势2:平滑噪音,识别真实趋势
线性回归本质上是一种
去噪拟合
,能过滤短期波动:
价格波动: 100 → 105 → 103 → 108 → 106 → 112
简单涨跌: +12%(但中间反复震荡)
斜率拟合: 识别出稳定的+2%/天趋势(R²高)
优势3:多周期组合,提升稳健性
可以结合不同周期构建评分体系:
python
# 短期(捕捉近期动量)
score_20d
=
calculate_slope_momentum(df,
20
,
use_weighted_regression
=
True
)
# 中期(确认趋势延续)
score_60d
=
calculate_slope_momentum(df,
60
,
use_weighted_regression
=
False
)
# 长期(避免追高)
score_120d
=
calculate_slope_momentum(df,
120
,
use_weighted_regression
=
False
)
# 综合评分
final_score
=
0.5
*
score_20d
+
0.3
*
score_60d
+
0.2
*
score_120d
六、总结
斜率动量指标的核心价值
科学量化趋势
:用数学模型替代主观判断
兼顾收益与稳定
:R²加权避免追逐虚假动量
灵活适配场景
:通过参数调整适应不同市场环境
易于实现与回测
:计算简单,历史数据充足
在ETF轮动中的独特优势
✅ 客观排序,消除情绪干扰
✅ 趋势过滤,提高胜率
✅ 多周期组合,提升稳健性
✅ 适应性强,牛熊皆可用