将滚动窗口回归应用于 R 中的 XTS 系列
我有 5 个货币对的 1033 个每日回报点,我想对其运行滚动窗口回归,但 rollapply 不适用于我定义的使用 lm() 的函数。这是我的数据:
> head(fxr)
USDZAR USDEUR USDGBP USDCHF USDCAD
2007-10-18 -0.005028709 -0.0064079963 -0.003878743 -0.0099537170 -0.0006153215
2007-10-19 -0.001544470 0.0014275520 -0.001842564 0.0023058211 -0.0111410271
2007-10-22 0.010878027 0.0086642116 0.010599365 0.0051899551 0.0173792230
2007-10-23 -0.022783987 -0.0075236355 -0.010804304 -0.0041668499 -0.0144788687
2007-10-24 -0.006561223 0.0008545792 0.001024275 -0.0004261666 0.0049525483
2007-10-25 -0.014788901 -0.0048523001 -0.001434280 -0.0050425302 -0.0046422944
> tail(fxr)
USDZAR USDEUR USDGBP USDCHF USDCAD
2012-02-10 0.018619309 0.007548205 0.005526184 0.006348533 0.0067151342
2012-02-13 -0.006449463 -0.001055966 -0.002206810 -0.001638002 -0.0016995755
2012-02-14 0.006320364 0.006843933 0.006605875 0.005992935 0.0007001751
2012-02-15 -0.001666872 0.004319096 -0.001568874 0.003686840 -0.0015009759
2012-02-16 0.006419616 -0.003401364 -0.005194817 -0.002709588 -0.0019044761
2012-02-17 -0.004339687 -0.003675992 -0.003319899 -0.003043481 0.0000000000
我可以轻松地对整个数据集运行 lm,以针对其他货币对对 USDZAR 进行建模:
> lm(USDZAR ~ ., data = fxr)$coefficients
(Intercept) USDEUR USDGBP USDCHF USDCAD
-1.309268e-05 5.575627e-01 1.664283e-01 -1.657206e-01 6.350490e-01
但是,我想运行 62 天的滚动窗口来获取这些系数随时间的演变,因此我创建了一个函数 dolm 执行此操作:
> dolm
function(x) {
return(lm(USDZAR ~ ., data = x)$coefficients)
}
但是,当我对此运行 rollapply 时,我得到以下信息:
> rollapply(fxr, 62, FUN = dolm)
Error in terms.formula(formula, data = data) :
'.' in formula and no 'data' argument
即使 dolm(fxr) 本身工作正常:
> dolm(fxr)
(Intercept) USDEUR USDGBP USDCHF USDCAD
-1.309268e-05 5.575627e-01 1.664283e-01 -1.657206e-01 6.350490e-01
这里发生了什么?如果 dolm 是一个更简单的函数,那么它似乎工作得很好,例如mean:
> dolm <- edit(dolm)
> dolm
function(x) {
return(mean(x))
}
> rollapply(fxr, 62, FUN = dolm)
USDZAR USDEUR USDGBP USDCHF USDCAD
2007-11-29 -1.766901e-04 -6.899297e-04 6.252596e-04 -1.155952e-03 7.021468e-04
2007-11-30 -1.266130e-04 -6.512204e-04 7.067767e-04 -1.098413e-03 7.247315e-04
2007-12-03 8.949942e-05 -6.406932e-04 6.637066e-04 -1.154806e-03 8.727564e-04
2007-12-04 2.042046e-04 -5.758493e-04 5.497422e-04 -1.116308e-03 7.124593e-04
2007-12-05 7.343586e-04 -4.899982e-04 6.161819e-04 -1.057904e-03 9.915495e-04
非常感谢任何帮助。本质上,我想要的是在 62 天滚动窗口内获得 USDZAR ~ USDEUR + USDGBP + USDCHF + USDCAD 回归的权重。
I have an xts of 1033 daily returns points for 5 currency pairs on which I want to run a rolling window regression, but rollapply is not working for my defined function which uses lm(). Here is my data:
> head(fxr)
USDZAR USDEUR USDGBP USDCHF USDCAD
2007-10-18 -0.005028709 -0.0064079963 -0.003878743 -0.0099537170 -0.0006153215
2007-10-19 -0.001544470 0.0014275520 -0.001842564 0.0023058211 -0.0111410271
2007-10-22 0.010878027 0.0086642116 0.010599365 0.0051899551 0.0173792230
2007-10-23 -0.022783987 -0.0075236355 -0.010804304 -0.0041668499 -0.0144788687
2007-10-24 -0.006561223 0.0008545792 0.001024275 -0.0004261666 0.0049525483
2007-10-25 -0.014788901 -0.0048523001 -0.001434280 -0.0050425302 -0.0046422944
> tail(fxr)
USDZAR USDEUR USDGBP USDCHF USDCAD
2012-02-10 0.018619309 0.007548205 0.005526184 0.006348533 0.0067151342
2012-02-13 -0.006449463 -0.001055966 -0.002206810 -0.001638002 -0.0016995755
2012-02-14 0.006320364 0.006843933 0.006605875 0.005992935 0.0007001751
2012-02-15 -0.001666872 0.004319096 -0.001568874 0.003686840 -0.0015009759
2012-02-16 0.006419616 -0.003401364 -0.005194817 -0.002709588 -0.0019044761
2012-02-17 -0.004339687 -0.003675992 -0.003319899 -0.003043481 0.0000000000
I can easily run an lm on it for the whole data set to model USDZAR against the other pairs:
> lm(USDZAR ~ ., data = fxr)$coefficients
(Intercept) USDEUR USDGBP USDCHF USDCAD
-1.309268e-05 5.575627e-01 1.664283e-01 -1.657206e-01 6.350490e-01
However I want to run a rolling 62 day window to get the evolution of these coefficients over time, so I create a function dolm which does this:
> dolm
function(x) {
return(lm(USDZAR ~ ., data = x)$coefficients)
}
However when I run rollapply on this I get the following:
> rollapply(fxr, 62, FUN = dolm)
Error in terms.formula(formula, data = data) :
'.' in formula and no 'data' argument
that is even though dolm(fxr) on its own works fine:
> dolm(fxr)
(Intercept) USDEUR USDGBP USDCHF USDCAD
-1.309268e-05 5.575627e-01 1.664283e-01 -1.657206e-01 6.350490e-01
What's going on here? It seems to work fine if dolm is a simpler function for example mean:
> dolm <- edit(dolm)
> dolm
function(x) {
return(mean(x))
}
> rollapply(fxr, 62, FUN = dolm)
USDZAR USDEUR USDGBP USDCHF USDCAD
2007-11-29 -1.766901e-04 -6.899297e-04 6.252596e-04 -1.155952e-03 7.021468e-04
2007-11-30 -1.266130e-04 -6.512204e-04 7.067767e-04 -1.098413e-03 7.247315e-04
2007-12-03 8.949942e-05 -6.406932e-04 6.637066e-04 -1.154806e-03 8.727564e-04
2007-12-04 2.042046e-04 -5.758493e-04 5.497422e-04 -1.116308e-03 7.124593e-04
2007-12-05 7.343586e-04 -4.899982e-04 6.161819e-04 -1.057904e-03 9.915495e-04
Any help much appreciated. Essentially what I want is to get the weightings for the regression of USDZAR ~ USDEUR + USDGBP + USDCHF + USDCAD over a rolling 62-day window.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里有几个问题:
rollapply
传递一个矩阵,但lm
需要一个data.frame
。rollapply
将函数分别应用于每一列,除非我们指定
by.column=FALSE
。与日期右对齐,但如果您确实使用
rollapplyr
:1) 结合上述内容,我们有:
2)
的替代方案上面
是使用dolm
中的 lmlm.fit
直接处理矩阵,而且速度更快:There are several problems here:
rollapply
passes a matrix butlm
requires adata.frame
.rollapply
applies the function to each column separately unless wespecify
by.column=FALSE
.right aligned with the dates but if you do use
rollapplyr
:1) Incorporating the above we have:
2) An alternative to the
lm
in thedolm
above is to uselm.fit
which directly works with matrices and is also faster:新答案
G. Grothendieck 的答案 是正确的,但您可以使用
rollRegres
包更快地完成此操作,如以下示例所示(roll_regres.fit
函数快约 118 倍)如果您想使用 R 公式,还可以使用包中的
roll_regres
函数。旧答案
第三种选择是更新 QR 分解中的 R 矩阵,如下面的代码所示。您可以通过使用 C++ 来加快速度,但您将需要 LINPACK 中的 dchud 和 dchdd 子例程(或更新 R 的另一个函数)。
上述解决方案要求您首先形成
model.matrix
和model.response
但这只是在调用之前的三个调用(一个额外的model.frame
)roll_coef
。New answer
G. Grothendieck's answer is correct but you can do it faster with the
rollRegres
package as the following example shows (theroll_regres.fit
function is ~118 times faster)You can also use the
roll_regres
function from the package if you want to use a R formula instead.Old answer
A third options would be to update the R matrix in a QR decomposition as done in the code below. You can speed this up by doing it in C++ but than you will need the
dchud
anddchdd
subroutines from LINPACK (or another function to update R)The solution above requires that you form the
model.matrix
andmodel.response
first but this is just three calls (one extra tomodel.frame
) prior to the call toroll_coef
.