计算滚动窗口协方差矩阵
Posted
技术标签:
【中文标题】计算滚动窗口协方差矩阵【英文标题】:Compute rolling window covariance matrix 【发布时间】:2012-09-13 15:31:47 【问题描述】:我正在尝试计算多个资产的滚动窗口(移动 1 天)协方差矩阵。
假设我的 df 看起来像这样:
df <- data.frame(x = c(1.5,2.3,4.7,3,8.4), y =c(5.3,2.4,8.4,1.3,2.5),z=c(2.5,1.3,6.5,4.3,2.8),u=c(1.1,2.5,4.3,2.5,6.3))
我希望输出如下所示:
cov(df[1:3,]) :
x y z u
x 2.773333 3.666667 4.053333 2.613333
y 3.666667 9.003333 7.846667 2.776667
z 4.053333 7.846667 7.413333 3.413333
u 2.613333 2.776667 3.413333 2.573333
cov(df[2:4,]) :
x y z u
x 1.523333 4.283333 3.053333 1.23
y 4.283333 14.603333 7.253333 3.93
z 3.053333 7.253333 6.813333 2.22
u 1.230000 3.930000 2.220000 1.08
cov(df[3:5,]) :
x y z u
x 7.6233333 -0.5466667 -3.008333 5.1633333
y -0.5466667 14.4433333 5.941667 0.9233333
z -3.0083333 5.9416667 3.463333 -1.5233333
u 5.1633333 0.9233333 -1.523333 3.6133333
但是一切都是循环进行的,因为我在数据集中有很多行...
如果我想通过将滚动窗口移动 1 天来滚动计算协方差矩阵,那么可能的 for
循环会是什么样子?还是我应该使用一些apply
家庭功能?
如果我想为上面的循环创建时间序列对象,最好使用哪个时间序列类?现在我使用来自fPortfolio
包的as.timeSeries
。
我就是看不懂……
最好的问候
【问题讨论】:
请展示您希望输出的样子。 【参考方案1】:要创建滚动窗口,您可以使用embed
。
## your data.frame
df <- data.frame(x=c(1.5,2.3,4.7,3,8.4), y=c(5.3,2.4,8.4,1.3,2.5), z=c(2.5,1.3,6.5,4.3,2.8), u=c(1.1,2.5,4.3,2.5,6.3))
## define windows
windowSize <- 3
windows <- embed(1:nrow(df), windowSize)
lapplyApproach <- function(df, windows)
## convert window matrix to a list
windowsList <- split(t(windows), rep(1:nrow(windows), each=ncol(windows)))
## edit: customize names: "from:to"
names(windowsList) <- unlist(lapply(windowsList, function(x)paste(range(x), sep="", collapse=":")))
return(lapply(windowsList, function(x)cov(df[x, ])))
forApproach <- function(df, windows)
l <- vector(mode="list", length=nrow(windows))
for (i in 1:nrow(windows))
l[[i]] <- cov(df[windows[i, ], ])
return(l)
## check results
all.equal(forApproach(df, windows), unname(lapplyApproach(df, windows)))
# TRUE
## test running time
library("rbenchmark")
## small example
benchmark(lapplyApproach(df, windows), forApproach(df, windows), order="relative")
# test replications elapsed relative user.self sys.self user.child sys.child
#2 forApproach(df, windows) 100 0.075 1.00 0.072 0 0 0
#1 lapplyApproach(df, windows) 100 0.087 1.16 0.084 0 0 0
## a larger one
n <- 1e3
df <- data.frame(x=rnorm(1:n), y=rnorm(1:n), z=rnorm(1:n), u=rnorm(1:n))
windows <- embed(1:nrow(df), windowSize)
benchmark(lapplyApproach(df, windows), forApproach(df, windows), order="relative")
# test replications elapsed relative user.self sys.self user.child sys.child
#1 lapplyApproach(df, windows) 100 26.386 1.000 26.301 0.004 0 0
#2 forApproach(df, windows) 100 26.932 1.021 26.838 0.000 0 0
编辑:对于时间序列,您可以使用包xts
及其函数endpoints
、period.apply
、apply.daily
、...
【讨论】:
非常感谢!欣赏它:) 对于如何“重命名”计算出的协方差矩阵,您有什么好的解决方案吗?例如,而不是像“2011-01-01 到 2011 02-30”这样的 $3291
?最好的问候
@user1665355 如果问题解决了您的问题,请将问题标记为已回答。
关于如何创建滚动窗口,而不是提前 1 天滚动,您有什么明确的建议吗?比如说,60 天的数据用于创建协方差矩阵。然后,在 60 天后计算下一个 cov.matrix。再次感谢您:)
@user1665355 增加windowSize
?!以上是关于计算滚动窗口协方差矩阵的主要内容,如果未能解决你的问题,请参考以下文章