收益分解:把总收益拆开看明白

做量化交易的朋友,肯定都遇到过这种情况:策略跑完回测,看着总收益率挺高,心里却发虚——这收益到底是怎么来的?是运气好撞上了大盘上涨,还是真有选股本事?

我个人习惯,拿到回测结果第一件事,就是做收益分解。说白了,就是把总收益拆成几块:Alpha收益、Beta收益、择时收益、选股收益。这样你才能知道,你的策略到底靠什么赚钱。

核心观点: 不拆解收益,你永远不知道自己的策略是「真本事」还是「风口上的猪」。

收益分解的基本框架

先看一个简单的公式:

总收益 = Beta收益 + Alpha收益 + 择时收益 + 选股收益 + 残差

嗯,这里要注意,不同的人对「择时」和「选股」的定义略有差异。我一般这样理解:

  • Beta收益: 市场涨你也涨,市场跌你也跌。这部分收益跟你选什么股票关系不大,纯粹是「搭便车」。
  • Alpha收益: 超越市场的部分。你选的股票比大盘涨得多,或者跌得少,这就是Alpha。
  • 择时收益: 你判断对了市场的方向。比如你预测大盘要涨,就加仓;预测要跌,就减仓。这部分收益来自「什么时候买」。
  • 选股收益: 你选对了具体的股票。比如同样看好消费板块,你选了茅台,别人选了某不知名白酒,结果茅台涨得更好。这部分收益来自「买什么」。

你想想看,如果一个策略的收益主要来自Beta,那其实你直接买指数基金就行了,何必费劲搞量化?

用SVG图看清收益分解逻辑

下面这张图,是我自己画的一个收益分解流程图。每次做归因分析时,我都会对照着看一遍:

总收益 收益分解第一层:Beta收益 vs Alpha收益 Beta收益(市场收益) Alpha收益(超额收益) 收益分解第二层:择时 vs 选股 择时收益(时机选择) 选股收益(个股选择) 收益分解流程图:从总收益到四类收益来源

这张图我每次做归因分析都会看一遍。它帮我理清了一个思路:总收益不是一块铁板,而是可以一层层拆开的。

如何计算这四类收益?

理论讲完了,咱们来点实际的。怎么算?

我一般用回归法。假设你的策略收益率是 R_p,市场收益率是 R_m,无风险利率是 R_f。那么:

R_p - R_f = α + β * (R_m - R_f) + ε

这里的 β 就是你的策略对市场的敏感度。β 越大,说明你的策略跟市场走得越近。

然后,我们可以进一步把 Alpha 拆成择时和选股。怎么做?

我个人习惯用 Treynor-Mazuy 模型:

R_p - R_f = α + β1 * (R_m - R_f) + β2 * (R_m - R_f)^2 + ε

这里的 β2 就是择时能力。如果 β2 显著为正,说明你在市场上涨时加仓了,下跌时减仓了——择时有效。

剩下的 α 就是纯粹的选股收益了。

小技巧: 我在项目中遇到过,直接用日频数据做回归,β2 往往不显著。后来我改成周频数据,效果就好多了。为什么?因为择时信号通常需要几天才能体现出来,日频数据噪声太大。

一个实际案例

来看一个我去年跑过的策略。回测结果如下:

收益来源 年化收益率 占比
总收益 18.5% 100%
Beta收益 8.2% 44.3%
Alpha收益 10.3% 55.7%
其中:择时收益 2.1% 11.4%
其中:选股收益 8.2% 44.3%

看到这个结果,我当时的第一反应是:嗯,选股能力还行,择时能力一般。44.3%的收益来自选股,说明我的因子筛选和股票打分模型是有效的。但择时只贡献了11.4%,说明我对市场方向的判断还不够准。

避坑指南: 我曾经犯过一个错误——看到总收益高就以为策略牛逼。结果一拆解,发现80%的收益来自Beta。说白了,就是那段时间大盘涨得好,我的策略只是跟上了大盘。后来我调整了策略,加入了更多Alpha因子,才真正跑出了超额收益。

收益分解的实操步骤

如果你用的是Python,代码大概长这样:

import statsmodels.api as sm
import pandas as pd
import numpy as np

# 假设 df 包含三列:strategy_return, market_return, risk_free
df['excess_return'] = df['strategy_return'] - df['risk_free']
df['market_excess'] = df['market_return'] - df['risk_free']

# 第一步:计算Beta和Alpha
X = sm.add_constant(df['market_excess'])
model = sm.OLS(df['excess_return'], X).fit()
alpha = model.params['const']
beta = model.params['market_excess']

# 第二步:计算择时能力(加入平方项)
df['market_excess_sq'] = df['market_excess'] ** 2
X2 = sm.add_constant(df[['market_excess', 'market_excess_sq']])
model2 = sm.OLS(df['excess_return'], X2).fit()
timing_coef = model2.params['market_excess_sq']

# 择时收益 = timing_coef * 市场超额收益的方差
timing_return = timing_coef * np.var(df['market_excess'])

# 选股收益 = Alpha - 择时收益
stock_selection_return = alpha - timing_return

print(f"Beta收益: {beta * df['market_excess'].mean():.4f}")
print(f"Alpha收益: {alpha:.4f}")
print(f"择时收益: {timing_return:.4f}")
print(f"选股收益: {stock_selection_return:.4f}")

这段代码我用了很多次。每次跑完回测,我都会跑一遍这个分解,看看策略的「含金量」到底有多少。

收益分解的意义

你想想看,如果你不做收益分解,你可能会犯两个错误:

  1. 过度自信: 以为自己的选股能力很强,其实只是搭上了市场的顺风车。
  2. 盲目优化: 明明择时能力很差,却拼命优化择时信号,浪费时间和精力。

我个人习惯,每季度做一次收益分解。如果发现某个策略的Alpha收益连续下降,我就会去检查因子是否失效了,或者市场风格是否发生了变化。

一句话总结: 收益分解不是炫技,而是帮你认清策略本质的工具。Beta收益是「天时」,Alpha收益是「人和」。择时是「踩点」,选股是「识货」。四者缺一不可,但权重不同,决定了策略的可持续性。

好了,这一章的内容就到这里。记住,下次拿到回测结果,先别急着高兴或沮丧,拆开看看,你的收益到底从哪来。

专注资料整理