如何在Pandas DataFrame中用滚动窗口计算每日VaR与CVaR
滚动窗口计算单只股票及投资组合的VaR与CVaR解决方案
你已经完成了数据获取、组合构建以及全局VaR/CVaR的计算,要实现窗口大小为7的滚动窗口每日VaR/CVaR计算,可以利用Pandas的rolling方法结合你已有的VaR/CVaR函数来实现,以下是完整解决方案:
完整代码实现
import pandas as pd import numpy as np import datetime as dt from pandas_datareader import data as pdr # 获取数据函数 def getData(stocks, start, end): stockData = pdr.get_data_yahoo(stocks, start=start, end=end) stockData = stockData['Close'] returns_pctchange = stockData.pct_change() return returns_pctchange # VaR计算函数 def historicalVaR(returns, alpha=5): """ 输入收益率的Series/DataFrame,输出指定置信水平的历史VaR """ if isinstance(returns, pd.Series): return np.percentile(returns, alpha) elif isinstance(returns, pd.DataFrame): return returns.aggregate(historicalVaR, alpha=alpha) else: raise TypeError("Expected returns to be dataframe or series") # CVaR计算函数 def historicalCVaR(returns, alpha=5): """ 输入收益率的Series/DataFrame,输出指定置信水平的历史CVaR """ if isinstance(returns, pd.Series): var_val = historicalVaR(returns, alpha=alpha) belowVaR = returns <= var_val return returns[belowVaR].mean() elif isinstance(returns, pd.DataFrame): return returns.aggregate(historicalCVaR, alpha=alpha) else: raise TypeError("Expected returns to be dataframe or series") # 数据获取与处理 stockList = ['IOC', 'RELIANCE', 'BPCL', 'HINDPETRO', 'EXIDEIND'] stocks = [stock+'.NS' for stock in stockList] endDate = dt.datetime.now() startDate = endDate - dt.timedelta(days=800) returns = getData(stocks, start=startDate, end=endDate) returns = returns.dropna() # 构建等权重投资组合 weights = np.array([1/len(stocks) for _ in stocks]) returns['portfolio'] = returns.dot(weights) # -------------------------- 滚动窗口计算核心代码 -------------------------- window_size = 7 # 滚动窗口大小 alpha_level = 5 # 置信水平(5%分位数) # 计算每日滚动VaR:每个窗口取前7天数据计算当日VaR rolling_var = returns.rolling(window=window_size).apply( lambda window_returns: historicalVaR(window_returns, alpha=alpha_level) ) # 计算每日滚动CVaR:逻辑同滚动VaR rolling_cvar = returns.rolling(window=window_size).apply( lambda window_returns: historicalCVaR(window_returns, alpha=alpha_level) ) # 查看结果示例(可选) print("滚动VaR结果(前10行):") print(rolling_var.head(10)) print("\n滚动CVaR结果(前10行):") print(rolling_cvar.head(10))
关键说明
- 滚动窗口实现:使用
returns.rolling(window=7)创建滚动窗口对象,每个窗口包含当前日期及之前的6个交易日数据(共7天); - 函数适配:通过
apply方法将你已实现的historicalVaR和historicalCVaR函数应用到每个窗口的收益率数据上,lambda函数用于传递置信水平参数; - 结果特点:前6条数据会显示为
NaN,因为需要至少7天的数据才能计算第一个窗口的VaR/CVaR,这是正常现象; - 结果解读:
rolling_var和rolling_cvar的每一行对应当日基于过去7天数据计算出的VaR/CVaR值,包含单只股票和投资组合的结果。
内容的提问来源于stack exchange,提问作者Baby Groot
相关产品推荐
相关产品推荐

