beta的滚动计算线性回归斜率

问题描述

我有一个数据框

> 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 个月的滚动测试版。分解:

  1. 我需要在第 3 行进行第一个 beta 计算,因为这有 3 个月的数据。在第 4 行我想在计算 beta 时使用过去 4 个月的数据,在第 5 行我想要过去 5 个月的数据,在第 6 行我再次想要过去 5 个月的数据等等。

  2. 我想通过变量“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)