3. 无风险利率与基准:无风险利率的选择、基准指数的构建与意义
做因子投资,说白了就是跟市场对赌。但赌之前,你得先搞清楚两件事:你的对手盘是谁?你的起跑线在哪?
无风险利率和基准指数,就是回答这两个问题的。我见过不少新手,策略回测跑得飞起,年化50%+,结果一问,用的是余额宝收益率当无风险利率,拿沪深300当基准。嗯,这数据基本可以扔进垃圾桶了。
3.1 无风险利率:你的起跑线
无风险利率,理论上是你把钱借给一个绝对不会违约的实体能拿到的回报。现实中,我们通常用短期国债收益率来近似。
核心原则:无风险利率必须与你的投资期限匹配。做日频交易用隔夜Shibor,做月频调仓用1年期国债收益率,做长期持有用10年期国债收益率。
3.1.1 中国市场常用选择
我个人习惯用以下三个层级:
| 投资周期 | 推荐指标 | 数据来源 |
|---|---|---|
| 日内/高频 | 隔夜Shibor | 全国银行间同业拆借中心 |
| 周频/月频 | 1年期国债到期收益率 | 中债登/ Wind |
| 季度/年度 | 10年期国债到期收益率 | 中债登/ Wind |
避坑指南:我曾经用央行一年期定期存款利率当无风险利率,结果发现策略的夏普比率虚高。为什么?因为存款利率有管制,不能真实反映资金的机会成本。后来我全部切换成国债收益率,数据才变得靠谱。
3.1.2 为什么不能随便选?
你想想看,如果你用2%的无风险利率算夏普比率,别人用4%算,同一个策略的结论可能完全相反。我见过一个极端案例:某私募用余额宝收益率当无风险利率,策略夏普2.5,换成10年期国债收益率后直接掉到0.8。
说白了,无风险利率决定了你策略的「超额收益」到底有多少含金量。
3.2 基准指数:你的对手盘
基准指数就是你策略的「假想敌」。你跑赢它,才算创造了价值。
3.2.1 基准的构建原则
一个好的基准,需要满足三个条件:
- 可投资性:基准里的成分股必须能实际买到,不能全是涨停板买不到的票
- 可复制性:别人拿着你的基准也能复制出差不多的收益
- 风格匹配:你做小盘股策略,就别拿沪深300当基准,那叫欺负人
注意:很多人在回测里用全市场等权指数当基准,这其实是个坑。全市场等权指数需要每天调仓,交易成本极高,现实中根本跑不赢。我建议用市值加权指数,比如中证全指。
3.2.2 基准指数的构建方法
这里我直接给代码,你们拿去就能用。这是构建一个简单的市值加权基准:
import pandas as pd
import numpy as np
def build_market_cap_weighted_benchmark(
stock_returns: pd.DataFrame,
market_caps: pd.DataFrame,
rebalance_freq: str = 'M'
) -> pd.Series:
"""
构建市值加权基准指数
Parameters:
-----------
stock_returns : DataFrame, 个股收益率 (index=日期, columns=股票代码)
market_caps : DataFrame, 个股总市值 (index=日期, columns=股票代码)
rebalance_freq : str, 调仓频率 ('M'=月度, 'Q'=季度, 'Y'=年度)
Returns:
--------
benchmark_returns : Series, 基准指数日收益率
"""
# 获取调仓日期
rebalance_dates = pd.date_range(
start=stock_returns.index[0],
end=stock_returns.index[-1],
freq=rebalance_freq
)
# 初始化权重
weights = pd.DataFrame(0, index=stock_returns.index, columns=stock_returns.columns)
# 在每个调仓日重新计算权重
for date in rebalance_dates:
if date in market_caps.index:
# 获取该日的市值数据
caps = market_caps.loc[date]
# 计算市值权重(剔除缺失值)
caps = caps.dropna()
w = caps / caps.sum()
# 填充到调仓日之后的所有日期
next_date = rebalance_dates[rebalance_dates > date].min() if any(rebalance_dates > date) else stock_returns.index[-1]
mask = (weights.index >= date) & (weights.index < next_date)
weights.loc[mask, w.index] = w.values
# 计算基准收益率
benchmark_returns = (stock_returns * weights.shift(1)).sum(axis=1)
return benchmark_returns.dropna()
个人经验:我刚开始做因子研究时,直接用万得的全A指数当基准。后来发现不对——全A指数包含了新股上市前几个月的暴涨效应,导致基准收益虚高。正确的做法是剔除上市不满60个交易日的股票,或者直接用中证流通指数。
3.3 无风险利率与基准的联动
这两个东西不是孤立的。它们共同决定了你的超额收益计算:
超额收益 = 策略收益 - 基准收益
信息比率 = 超额收益的均值 / 超额收益的标准差
夏普比率 = (策略收益 - 无风险利率) / 策略收益的标准差
你看,基准影响分子,无风险利率影响分母。选错了任何一个,你的绩效评估都会失真。
3.4 知识体系总览
下面这张图,是我自己总结的。它把无风险利率和基准指数的选择逻辑串在了一起:
3.5 实战中的常见问题
我总结几个你们一定会遇到的坑:
- 基准漂移:你的策略风格变了,但基准没变。比如你从大盘股切到小盘股,还拿沪深300当基准,超额收益会失真。
- 幸存者偏差:用现在的指数成分股回测过去,基准收益会偏高。因为退市的垃圾股被剔除了。
- 分红处理:全收益指数和价格指数差很多。做因子研究一定要用全收益指数(含分红再投资)。
重要提醒:我曾经犯过一个低级错误——用价格指数当基准,但策略收益是含分红的。结果超额收益被低估了2-3个百分点。后来我统一用全收益指数,数据才对齐。
好了,关于无风险利率和基准指数,核心就这些。记住一句话:选对了起跑线和对手盘,你的绩效评估才有意义。否则,再漂亮的回测曲线也只是自欺欺人。