修复时间序列图表起始段严重失真问题
滚动夏普比率起始段数据失真问题

无论设置10年、20年还是25年的时间范围,图表起始段数据都严重失真,数值要么极高要么极低。
- 一开始以为是
min_periods参数的问题,但调大参数后毫无改善 - 已经确认计算列里没有N/A值
- 子图绘制的是代码中的
sharpe_rf指标
问题根源与修复方案
1. 核心错误:夏普比率计算逻辑完全偏离标准
你当前的代码把已经算好的夏普比率除以无风险利率,这完全违背了夏普比率的标准公式。正确的滚动夏普比率应该是**(资产日均收益率 - 无风险日均收益率)除以收益率标准差,再乘以年化系数**,用夏普比率去除以无风险利率会导致数值异常——尤其是无风险利率偏低时,结果会被放大到离谱的程度,这是起始段数值失真的主要原因。
2. 小样本导致统计结果不稳定
你设置了min_periods=10,意味着只要凑够10个数据就会计算滚动指标,但你的窗口是252(一年交易日),样本量远小于窗口大小时,均值和标准差的波动会极大,统计意义极低,自然会出现极端值。
3. 无风险利率单位未做转换
USGG10YR的收益率是百分比形式(比如3代表3%),直接用这个数值参与计算会导致量级错误,必须先转换成小数(0.03),还要把年化的无风险利率转成日度的,才能和日度收益率匹配。
修复后的代码示例
asset1 = 'XLY Equity' asset2 = 'USGG10YR Index' # 数据获取与预处理 sids = mgr[asset1, asset2] d = sids.get_historical(prices,start=startD,end=endD) df = pd.DataFrame(d).dropna() df.columns = ['Asset', 'Risk Free Rate'] # 无风险利率转换:百分比转小数,年化转日度 df['Risk Free Rate'] = df['Risk Free Rate'] / 100 # 百分比转小数 daily_rf = df['Risk Free Rate'] / 252 # 年化收益率转日度 # 计算日度对数收益率 daily_returns = np.log(df['Asset']) - np.log(df['Asset'].shift(1)) daily_returns = daily_returns.dropna() # 滚动夏普比率(标准公式) lookback = 252 # 强制使用完整窗口计算,避免小样本失真;也可根据需求调整min_periods为中间值(如126) rolling_return_mean = daily_returns.rolling(window=lookback, min_periods=lookback).mean() rolling_return_std = daily_returns.rolling(window=lookback, min_periods=lookback).std() rolling_rf_mean = daily_rf.rolling(window=lookback, min_periods=lookback).mean() # 标准年化夏普比率计算 sharpe_rf = np.sqrt(252) * (rolling_return_mean - rolling_rf_mean) / rolling_return_std sharpe_rf = sharpe_rf.dropna()
额外建议
- 如果不想完全舍弃起始段数据,可以把
min_periods设为126(半年交易日),但要明确小样本的结果可靠性有限 - 确认无风险利率的数据源是否为年化收益率,如果是其他频率(比如日度),要调整转换方式
内容的提问来源于stack exchange,提问作者JC21
相关产品推荐
相关产品推荐

