Python如何为多资产矩阵计算60期滚动窗口协方差矩阵
滚动窗口协方差矩阵计算实现(适配VaR计算场景)
公式与计算目标
基于3类资产共1610条收益率观测值,按公式 Σ = σDσ 逐60期滚动窗口计算协方差矩阵,作为风险价值(VaR)计算的输入参数:
σ:3×3对角矩阵,对角线元素为对应窗口内单资产收益率的标准差D:对应窗口内3类资产的相关系数矩阵
原有代码的问题点
- 循环逻辑未对齐滚动窗口索引,σ和D的取值不属于同一计算窗口
- 直接调用
returns.corr仅能计算全样本相关矩阵,无法得到窗口内动态相关系数 rolling()是pandas面向DataFrame/Series的窗口计算方法,无法直接作用于numpy矩阵对象- 矩阵运算误用元素级乘法
*,协方差分解需要用矩阵乘法规则计算
实现步骤
核心思路是同步计算同窗口下的滚动标准差、滚动相关系数,再逐期做矩阵乘法,不需要编写冗余的显式遍历逻辑:
- 第一步:计算窗口长度为60的单资产滚动标准差,得到每个时间点3个资产的标准差序列
- 第二步:计算窗口长度为60的两两资产滚动相关系数矩阵,得到每个时间点对应的3×3相关矩阵D
- 第三步:从第一个有效窗口(第60个观测点)开始,逐期取出当期σ对角矩阵、D矩阵,按公式计算Σ
- 第四步:按时间索引存储所有窗口的协方差矩阵,供VaR计算调用
可运行代码示例
假设3类资产的收益率数据存储在名为returns的pandas DataFrame中,列名分别对应三类资产:
import numpy as np import pandas as pd # 配置参数 window_size = 60 # 1. 计算滚动单资产标准差(σ矩阵的对角线元素) rolling_std = returns.rolling(window=window_size).std() # 2. 计算滚动相关系数矩阵D,返回多级索引格式的动态相关系数 rolling_corr = returns.rolling(window=window_size).corr(pairwise=True) # 3. 逐期计算滚动协方差矩阵,用字典按时间索引存储结果 rolling_cov = {} # 跳过前window_size-1个凑不满窗口的无效观测 valid_dates = rolling_std.dropna().index for dt in valid_dates: # 生成当期对角σ矩阵 sigma_mat = np.diag(rolling_std.loc[dt].values) # 取出当期3×3相关系数矩阵 corr_mat = rolling_corr.loc[dt].values # 矩阵乘法计算协方差:注意用@做矩阵乘,不要用*做元素乘 cov_mat = sigma_mat @ corr_mat @ sigma_mat rolling_cov[dt] = cov_mat # 可选:将结果转为多级索引DataFrame,和pandas rolling输出格式对齐 rolling_cov_df = pd.DataFrame.from_dict( {dt: mat.flatten() for dt, mat in rolling_cov.items()}, orient='index', columns=pd.MultiIndex.from_product([returns.columns, returns.columns]) )
注意事项
- 公式中σ矩阵的对角线元素是单资产收益率的标准差,如果之前存储的
sigmabtc/sigmaeth/sigmaxlm是方差值,需要先做开平方处理再传入,否则协方差计算量级会出错 - 前59个观测值不满足60期窗口长度要求,没有有效协方差结果,VaR回测时从第60个时间点开始计算即可
- 后续调用时,直接按日期索引从
rolling_cov中取出对应3×3矩阵,即可作为sigma参数传入VaR计算公式
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

