【问题标题】:Compute daily explained variance计算每日解释方差
【发布时间】:2015-05-13 06:05:29
【问题描述】:

我想使用 R 来估计固定数量的特征向量的每日解释方差(这与 Kritzman 等人在 this article 中定义的“吸收率”相同)。我正在使用this data file,这是一个每日回报矩阵。我的主要目标是以与 Kritzman 等人在上面的文章中所做的相同的方式估计每日解释方差(吸收率)。关于估计,Kritzman 等人说:

为了估计吸收率,我们使用一个 [rolling] 500 天的窗口来估计协方差矩阵和特征向量,我们将特征向量的数量固定在大约 1/ 5 我们样本中的资产数量。

为了在 R 中计算这个,我尝试了以下代码:

rm(list=ls(all=TRUE))
library("quadprog")

# read data set consisting of daily returns
data <- read.table("10_Industry_Portfolios_Daily.txt", header=TRUE)
Ret <- data[,2:ncol(data)]/100
names <- c("NoDur","Durbl","Manuf","Enrgy","HiTec",
           "Telcm","Shops","Hlth","Utils","Other")
colnames(Ret) <- names

# lookback period in number of days (rolling window)
lb.period <- 500
nRow <- nrow(Ret)
nCol <- ncol(Ret)
n <- nRow-lb.period

ar <- rep(0,n) # reserve space for daily absorption ratio
for(i in 1:n) {
# define rolling window
  start <- i
  end <- i+lb.period-1
  ret <- Ret[start:end,]
  cov <- cov(ret)
  eigenval <- eigen(cov)$values
  sumeigenval <- sum(eigenval)
  abs <- eigenval[1:2]/sumeigenval # variance explained by 2 eigenvectors
  ar[i] <- ar[i]+abs # daily variance explained, out of sample period
}

当我运行这个程序时,我收到以下警告消息; “要替换的项目数不是替换长度的倍数”,并以由 n 个相等的数字组成的 ar[i] 向量结束。

我非常有信心这是计算 2 个特征向量的解释方差的正确方法

  ret <- Ret[start:end,]
  cov <- cov(ret)
  eigenval <- eigen(cov)$values
  sumeigenval <- sum(eigenval)
  abs <- eigenval[1:2]/sumeigenval

但我的问题是我如何使用滚动窗口方法每天计算这个数字,正如 Kritzman 在他的文章中所做的那样。恐怕我的 R 知识在这里并不适用,所以如果有人能在这方面帮助我,我将不胜感激。如果有不清楚的地方,请随时提出问题。

【问题讨论】:

  • 我还找到了this article,作者实际上在其中发布了与估计吸收率相关的 R 代码,但是当我用他的代码尝试我的数据文件时它不起作用。不过,您可能会在这里找到一些编程灵感。
  • 我无权访问您的数据(一个可重复的示例将有很长的路要走),但您可以自己开始调试有问题的部分。要么将browser()放在你认为会导致问题的块之前(并运行循环),要么手动定义i(例如i &lt;- 3)并逐步完成循环。
  • 我确实分享了我在第一篇文章中使用的数据,但我可以再次分享:mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/… 我会继续努力,所以我也会尝试你的建议。感谢您的支持。
  • 还有其他人有什么建议吗?
  • @Captain_Slow 嗨,我知道这是几年前发布的。我目前对实施吸收率感兴趣..您最终解决了问题吗?

标签: r for-loop time-series pca eigenvalue


【解决方案1】:

我想我已经完成了这项工作。并不是说它是证据,但结果似乎是合理的。

我怀疑这是由于数据的形状造成的。我也确信这可以变得更快、更优雅,但是这里......

library(tidyverse)

# site <- 'http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/10_Industry_Portfolios_daily_TXT.zip'

# Import downloaded data
data <- read_table2(
  file = "10_Industry_Portfolios_Daily.txt", 
  col_types = cols(
    NoDur = col_date(format = "%Y%m%d")
    ), 
  skip = 9
  ) %>% 
  group_by(NoDur) %>% 
  slice(1) %>% 
  ungroup() %>% 
  filter(!is.na(NoDur)) %>% 
  mutate_if(.predicate = is.numeric, .funs = ~.x/100)

head(data)

# A tibble: 6 x 10
  NoDur         Durbl     Manuf   Enrgy    HiTec    Telcm   Shops     Hlth   Utils    Other
  <date>        <dbl>     <dbl>   <dbl>    <dbl>    <dbl>   <dbl>    <dbl>   <dbl>    <dbl>
1 1926-07-01  0.0002  -0.0028   -0.0023  0.00570 -0.0021  -0.0002 -0.0001   0.0097  0.00610
2 1926-07-02  0.00290  0.0107    0.0081  0.0064   0.0036   0.0026  0.0001   0.0013  0.00470
3 1926-07-06  0.00240  0.0072    0.0022  0.0017   0.00470  0.0017 -0.0023   0.0023  0.0073 
4 1926-07-07  0.0027   0.000600  0.0023 -0.0004  -0.001    0.0032 -0.00580  0.0033  0.0017 
5 1926-07-08  0.0069   0.0005    0.0015  0.00120  0.00350  0.004  -0.0036   0.0091 -0.002  
6 1926-07-09 -0.0039  -0.0115   -0.011  -0.016   -0.0073   0.0021  0.004   -0.0028 -0.0074 

一旦您拥有正确形状的数据,您就可以继续使用您的原始代码...

Ret <- data[,-1]

# lookback period in number of days (rolling window)
lb.period <- 500
nRow <- nrow(Ret)
nCol <- ncol(Ret)
n <- nRow-lb.period

ar <- rep(0,n) # reserve space for daily absorption ratio
for(i in 1:n) {
  # define rolling window
  start <- i
  end <- i+lb.period-1
  ret <- Ret[start:end,]
  cov <- cov(ret)
  eigenval <- eigen(cov)$values
  sumeigenval <- sum(eigenval)
  abs <- eigenval[1:2]/sumeigenval # variance explained by 2 eigenvectors
  ar[i] <- ar[i]+abs # daily variance explained, out of sample period
}

将其与数据结合起来会产生以下结果...

ar_new <- c(rep(NA, lb.period), ar)
results <- bind_cols(data, Absorption = ar_new)
tail(results)

# A tibble: 6 x 11
  NoDur         Durbl    Manuf     Enrgy    HiTec    Telcm     Shops    Hlth   Utils    Other Absorption
  <date>        <dbl>    <dbl>     <dbl>    <dbl>    <dbl>     <dbl>   <dbl>   <dbl>    <dbl>      <dbl>
1 2019-06-21 -0.0027  -0.002   -0.00470   0.00610 -0.0026  -0.0069   -0.0034  0.002   0.00470      0.663
2 2019-06-24 -0.002   -0.00410  0.000600 -0.0092  -0.0005  -0.000600 -0.0045 -0.006  -0.0031       0.663
3 2019-06-25 -0.0027  -0.00350 -0.0045   -0.0078  -0.0184  -0.0068   -0.0065 -0.003  -0.0072       0.663
4 2019-06-26 -0.00940  0.0055  -0.0013    0.0174   0.0068  -0.0086    0.0017 -0.0125 -0.0178       0.663
5 2019-06-27  0.0026   0.0125   0.0028   -0.0083   0.00470  0.005     0.0053  0.0077  0.0017       0.662
6 2019-06-28  0.0036   0.00610  0.0095    0.0108   0.00350  0.0071    0.0016  0.0069  0.0075       0.661

...我们可以从中生成以下图表...

results %>% 
  ggplot(
    aes(
      x = NoDur, 
      y = Absorption
    )
  ) + 
  geom_line() + 
  theme_minimal() +
  labs(
    x = "", 
    y = "", 
    title = "Absorption Ratio over Time"
    )

【讨论】:

    猜你喜欢
    • 2019-05-05
    • 2022-08-14
    • 2016-04-03
    • 2015-09-04
    • 2019-12-09
    • 1970-01-01
    • 2016-12-08
    • 2020-09-29
    • 1970-01-01
    相关资源
    最近更新 更多