问题描述
> df
date comp ret mret
1 1/1/75 A 0.07 0.06
2 1/2/75 A 0.04 0.05
3 1/3/75 A 0.01 0.01
4 1/4/75 A -0.05 -0.04
5 1/5/75 A 0.05 0.05
6 1/6/75 A 0.04 0.04
7 1/7/75 A 0.07 0.08
8 1/8/75 A 0.01 0.00
9 1/9/75 A -0.02 -0.01
10 1/10/75 A -0.03 -0.01
11 1/11/75 A 0.01 0.02
12 1/12/75 A 0.03 0.04
13 1/1/75 B 0.09 0.06
14 1/2/75 B 0.07 0.05
15 1/3/75 B 0.04 0.01
16 1/4/75 B -0.02 -0.04
17 1/5/75 B 0.06 0.05
18 1/6/75 B 0.08 0.04
19 1/7/75 B 0.10 0.08
20 1/8/75 B 0.02 0.00
21 1/9/75 B -0.01 -0.01
22 1/10/75 B 0.01 -0.01
23 1/11/75 B -0.01 0.02
24 1/12/75 B 0.07 0.04
我想根据 CAPM 计算 beta,它是 ret 和 mret 之间的斜率(y 变量 = ret,x 变量 = mret)。这意味着我需要做一个线性回归来计算这个 beta。
然后,我想计算每家公司过去 5 个月和至少 3 个月的滚动测试版。分解:
-
我需要在第 3 行进行第一个 beta 计算,因为这有 3 个月的数据。在第 4 行我想在计算 beta 时使用过去 4 个月的数据,在第 5 行我想要过去 5 个月的数据,在第 6 行我再次想要过去 5 个月的数据等等。
-
我想通过变量“comp”对计算进行分组,这意味着在第 13 行,一切都将重置,第一个计算从第 15 行开始,然后遵循上述方法。
结果应该是这样的:
date comp ret mret beta
1 1/1/75 A 0.07 0.06 NA
2 1/2/75 A 0.04 0.05 NA
3 1/3/75 A 0.01 0.01 1.0714
4 1/4/75 A -0.05 -0.04 1.1129
5 1/5/75 A 0.05 0.05 1.1098
6 1/6/75 A 0.04 0.04 1.0578
7 1/7/75 A 0.07 0.08 1.0193
8 1/8/75 A 0.01 0.00 0.9839
9 1/9/75 A -0.02 -0.01 0.9307
10 1/10/75 A -0.03 -0.01 1.0161
11 1/11/75 A 0.01 0.02 0.9895
12 1/12/75 A 0.03 0.04 1.0106
13 1/1/75 B 0.09 0.06 NA
14 1/2/75 B 0.07 0.05 NA
15 1/3/75 B 0.04 0.01 0.9286
16 1/4/75 B -0.02 -0.04 1.0484
17 1/5/75 B 0.06 0.05 0.9913
18 1/6/75 B 0.08 0.04 0.9932
19 1/7/75 B 0.10 0.08 0.9807
20 1/8/75 B 0.02 0.00 1.0046
21 1/9/75 B -0.01 -0.01 1.1496
22 1/10/75 B 0.01 -0.01 1.1613
23 1/11/75 B -0.01 0.02 1.0559
24 1/12/75 B 0.07 0.04 1.0426
在 R 中有没有办法做到这一点?
解决方法
使用末尾注释中的 df
,创建一个 slope
函数并使用 rollapplyr
在移动窗口上运行它。 partial = 3
告诉它在至少 3 行的开头使用部分窗口。
library(dplyr)
library(zoo)
slope <- function(m) {
ret <- m[,1]
mret <- m[,2]
cov(ret,mret) / var(mret)
}
df %>%
group_by(comp) %>%
mutate(beta = rollapplyr(cbind(ret,mret),5,slope,partial = 3,fill = NA,by.column = FALSE)) %>%
ungroup
给予:
# A tibble: 24 x 5
date comp ret mret beta
<chr> <chr> <dbl> <dbl> <dbl>
1 1/1/75 A 0.07 0.06 NA
2 1/2/75 A 0.04 0.05 NA
3 1/3/75 A 0.01 0.01 1.07
4 1/4/75 A -0.05 -0.04 1.11
5 1/5/75 A 0.05 0.05 1.11
6 1/6/75 A 0.04 0.04 1.06
7 1/7/75 A 0.07 0.08 1.02
8 1/8/75 A 0.01 0 0.984
9 1/9/75 A -0.02 -0.01 0.931
10 1/10/75 A -0.03 -0.01 1.02
# ... with 14 more rows
注意
以可重现的形式输入:
Lines <- "date comp ret mret
1 1/1/75 A 0.07 0.06
2 1/2/75 A 0.04 0.05
3 1/3/75 A 0.01 0.01
4 1/4/75 A -0.05 -0.04
5 1/5/75 A 0.05 0.05
6 1/6/75 A 0.04 0.04
7 1/7/75 A 0.07 0.08
8 1/8/75 A 0.01 0.00
9 1/9/75 A -0.02 -0.01
10 1/10/75 A -0.03 -0.01
11 1/11/75 A 0.01 0.02
12 1/12/75 A 0.03 0.04
13 1/1/75 B 0.09 0.06
14 1/2/75 B 0.07 0.05
15 1/3/75 B 0.04 0.01
16 1/4/75 B -0.02 -0.04
17 1/5/75 B 0.06 0.05
18 1/6/75 B 0.08 0.04
19 1/7/75 B 0.10 0.08
20 1/8/75 B 0.02 0.00
21 1/9/75 B -0.01 -0.01
22 1/10/75 B 0.01 -0.01
23 1/11/75 B -0.01 0.02
24 1/12/75 B 0.07 0.04"
df <- read.table(text = Lines)