You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复时间序列图表起始段严重失真问题

滚动夏普比率起始段数据失真问题

Rolling Sharpe Ratio

无论设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:35:22