如何使用R语言批量计算多股票等权组合的历史波动率
实现方案
第一步:预处理近三个月收益率数据
首先你需要先从perf中提取近三个月的日收益率数据,假设你的perf数据框的行对应交易日,且已经按时间升序排列(最早的日期在第一行,最晚的在最后一行),近三个月大概对应63个交易日(全球主流市场年均约252个交易日,季度约63个),可以按如下方式提取:
# 提取最近63个交易日的收益率数据,也可以根据你实际的日期列做更精准的日期筛选 perf_recent <- tail(perf, 63) # 固定等权权重,所有四股组合通用 weights <- rep(0.25, 4)
如果你的perf有专门的日期列(比如列名为trade_date,格式为Date类型),可以用日期筛选更准确:
library(lubridate) # 筛选近3个月的收益率数据 end_date <- max(perf$trade_date) start_date <- end_date %m-% months(3) perf_recent <- perf[perf$trade_date >= start_date & perf$trade_date <= end_date, ] # 去掉日期列,只保留各ISIN的收益率列 perf_recent <- perf_recent[, setdiff(colnames(perf_recent), "trade_date")]
第二步:批量计算所有组合的波动率
直接用apply函数按行遍历final_output的每一条组合记录,逐一计算波动率即可,1万多条记录运行速度非常快,不会有性能问题:
# 定义单组合波动率计算函数 calc_portfolio_vol <- function(isin_vec) { # 提取当前组合4只股票的收益率序列 port_return <- perf_recent[, isin_vec, drop = FALSE] # 校验ISIN是否都存在于perf中,不存在则返回NA if (ncol(port_return) != 4) { return(NA_real_) } # 计算协方差矩阵 cov_mat <- cov(port_return, use = "pairwise.complete.obs") # 计算组合波动率 vol <- as.numeric(sqrt(t(weights) %*% cov_mat %*% weights)) return(vol) } # 批量计算,结果直接保存到final_output的新列portfolio_vol中 final_output$portfolio_vol <- apply(final_output[, c("ISIN_1", "ISIN_2", "ISIN_3", "ISIN_4")], 1, calc_portfolio_vol)
补充说明
use = "pairwise.complete.obs"是协方差计算的缺失值处理规则,某两只股票的共同交易日数据完整时就参与计算,适合部分股票有上市时间差、临时停牌的场景,你也可以根据需要替换为use = "complete.obs"(仅用4只股票都有数据的交易日计算)- 如果你需要基于月度收益率计算协方差,可以先把日收益率转成月度收益率再执行上述计算,转换参考代码:
library(dplyr) library(lubridate) # 假设你有trade_date列,先按年月分组计算累计月度收益率 perf_monthly <- perf %>% mutate(year_month = floor_date(trade_date, "month")) %>% group_by(year_month) %>% summarise(across(-trade_date, ~prod(1 + .x) - 1)) %>% ungroup() %>% select(-year_month)
替换上述代码中的perf_recent为perf_monthly即可。
内容的提问来源于stack exchange,提问作者Enrico Corneli
相关产品推荐
相关产品推荐

