CAPM.beta rollapply [英] CAPM.beta rollapply

查看:104
本文介绍了CAPM.beta rollapply的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用

beta <- rollapplyr(x,width=width_cor,function(x) CAPM.beta(x[,1],x[,-1]),by.column=FALSE)

在我的xts对象中成功计算了滚动相关性

 x <- cbind(market_return,stock_returns)
rollcor_3year <- rollapplyr(
    x, width=width_cor,function(x) cor(x[,1],x[,-1],
    use="pairwise.complete.obs"),by.column=FALSE)
 

此相关性后来用于计算滚动Beta.

现在我从PerformanceAnalytics包中找到了函数CAPM.beta,我想知道为什么我不能使用

beta <- rollapplyr(x,width=width_cor,function(x) CAPM.beta(x[,1],x[,-1]),by.column=FALSE)

beta <- rollapplyr(stock_returns,width=width_cor,CAPM.beta,Rb=market_return,by.column=FALSE)

直接.

使用这两个功能,它都会开始计算,但不会停止...

很高兴看到我是否从预定义函数中获得了相同的beta,但显然它不能那样工作.我做错了什么?

解决方案

实际上,PerformanceAnalytics函数将给出相同的结果,但是花费的时间更长.下面的代码使用2017年1月1日至今的样本数据,其中AMZN和XOM作为股票,SPY作为市场回报的代理.滚动计算中使用40个交易日的窗口.使用PerformanceAnalytics中的CAPM.betaBetaCoVariance函数并通过直接计算协方差矩阵然后取成对协方差与市场方差之比的三种方法来计算滚动beta值.显示方法的结果以表明它们是相同的. microbenchmark包中的microbenchmark用于测量所有方法的执行时间.直接计算的速度要快一到两个数量级.

  library(xts)
  library(quantmod)
  library(PerformanceAnalytics)
  library(microbenchmark)
#
#  get price time histories and calculate returns
#  use SPY as proxy for S&P 500; SPY should be first symbol in assets
#
  assets <- c("SPY", "AMZN", "XOM")   
  getSymbols( assets, from = "2017-01-01", auto.assign = TRUE)

  asset_prices <- xts()
  asset_prices <- Reduce(f=function(x,y) {y_sym=eval(as.name(y));  merge(x,y_sym[,paste0(y,".Adjusted")])},
                         x = assets, init=asset_prices) 
  asset_returns <- diff.xts(asset_prices, arithmetic = FALSE, na.pad=FALSE)-1

  market_return <- asset_returns$SPY.Adjusted
  stock_returns <- asset_returns[,-1] 

#
#  calculate rolling beta with a 40 trading-day window using CAPM.beta.roll
#  For this amount of data and calculating daily betas (by = 1), calculation should take 5-10 seconds
#
  width_cor = 40
  CAPM.beta_roll <- rollapply(data=stock_returns, FUN=CAPM.beta, Rb= market_return, Rf = 2.5/252, 
                       width = width_cor, by = 1, align = "right", by.column=TRUE)

#
#  calculate rolling beta with a 40 trading-day window by calculating the covariance matrix and taking ratio of two elements
#  For this amount of data and calculating daily betas (by = 1), calculation should be very quick
#
  CovVar <- function(Ra, Rb) {R = merge.xts(Rb, Ra, join="inner"); cv=cov(x=R);  
                               cv[1,-1]/cv[1,1,drop=TRUE]}
  CovVar_roll <- rollapplyr(data=stock_returns, width=width_cor,
                            FUN= CovVar,  Rb = market_return, by.column=FALSE)

#
#  since rollapply does not apply the window to Rb, it is done in CovVar for each time window
#  CovVar1 is a faster version which passes the merged market and stock return to cov directly
#  Its single argument R must be the merged data matrix R
#
  CovVar1 <- function(R){  cv=cov(x=R); cv[-1,1]/cv[1,1]}
  CovVar1_roll <- rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                             FUN= CovVar1,  by.column=FALSE)

  #
  #  CovVar2 is a faster version which passes the merged market and stock return to cov directly and 
  #  calculates the covariances only between the market returns and stock_returns.  For a small number of stocks,
  #  this is less efficient than calculating the entire covariance for a single matrix as in CovVar1 but it should become more 
  #  efficient for a larger number of stocks.
  #  Its single argument R must be the merged data matrix R
  #
  CovVar2 <- function(R){  cv = cov(R[,1], R );  cv[,-1]/cv[1,1] }
  CovVar2_roll <- rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                             FUN= CovVar2,  by.column=FALSE)

#
# Compare to verify that results are the same 
#
  print(tail(merge(CAPM.beta_roll, CovVar_roll, CovVar1_roll, CovVar2_roll )))
#
#  Compare execution times for four above methods and third method using BetaCovariance function from PerformanceAnalytics
#  This should take 25-35 seconds to run
#

  elapsed_times <- microbenchmark(
                  CAPM.beta_roll = rollapplyr(data=stock_returns, width=width_cor,
                                              FUN= CAPM.beta, Rb=market_return,by.column=FALSE),
                  BetaCoVar_roll = rollapplyr(data=stock_returns, width=width_cor,
                                               FUN= BetaCoVariance, Rb=market_return,by.column=FALSE),
                  CovVar_roll = rollapplyr(data=stock_returns, width=width_cor,
                                           FUN= CovVar,  Rb = market_return, by.column=FALSE),
                  CovVar1_roll = rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                                             FUN= CovVar1,  by.column=FALSE),
                  CovVar2_roll = rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                                             FUN= CovVar2,  by.column=FALSE),
                   times = 3)

# 
#  Direct calculation using covariance matrix, CovVar, is 50 - 100 times faster than PerformanceAnalytics functions 
#
  print(elapsed_times)

执行时间为:

Unit: milliseconds
           expr        min         lq       mean     median         uq        max neval
 CAPM.beta_roll 3007.34309 3009.92618 3016.57905 3012.50928 3021.19703 3029.88477     3
 BetaCoVar_roll 3453.83531 3471.70954 3478.91433 3489.58377 3491.45383 3493.32390     3
    CovVar_roll   69.19571   69.57012   69.83189   69.94453   70.14999   70.35544     3
   CovVar1_roll   38.72437   39.17021   39.33052   39.61605   39.63359   39.65113     3
   CovVar2_roll   60.75020   61.08255   61.36130   61.41490   61.66684   61.91878     3 

CovVar1是最快的,因为至少对于少量维而言,R对于单个矩阵输入要比必须对齐矩阵的两个矩阵输入要高效得多,从而计算出协方差矩阵.对于更大的尺寸,CovVar2应该更快.

I have already successfully calculated my rolling correlations in my xts object with

x <- cbind(market_return,stock_returns)
rollcor_3year <- rollapplyr(
    x, width=width_cor,function(x) cor(x[,1],x[,-1],
    use="pairwise.complete.obs"),by.column=FALSE)

The correlation was later used to calculate rolling Betas.

Now I found the function CAPM.beta from the PerformanceAnalytics package and I wonder why I cannot use

beta <- rollapplyr(x,width=width_cor,function(x) CAPM.beta(x[,1],x[,-1]),by.column=FALSE)

or

beta <- rollapplyr(stock_returns,width=width_cor,CAPM.beta,Rb=market_return,by.column=FALSE)

directly.

With both functions it starts to calculate but doesnt stop...

It would be nice to see if I get the same betas out of the predefined function, but apparently it does not work like that. What did I do wrong?

解决方案

Actually, the PerformanceAnalytics function will give the same results but it takes longer to do it. The code below uses sample data for 2017-01-01 to now with AMZN and XOM as stocks and SPY as a proxy for market returns. A window of 40 trading days is used in the rolling calculations. The rolling beta value is calculated using the CAPM.beta and BetaCoVariance functions from PerformanceAnalytics and by three methods which directly calculate the covariance matrix and then taking the ratio of the pairwise covariances to the market variance. The results from the methods are displayed to show they are the same. microbenchmark from the microbenchmark package is used to measure execution times for all methods. The direct calculations is one to two orders of magnitude faster.

  library(xts)
  library(quantmod)
  library(PerformanceAnalytics)
  library(microbenchmark)
#
#  get price time histories and calculate returns
#  use SPY as proxy for S&P 500; SPY should be first symbol in assets
#
  assets <- c("SPY", "AMZN", "XOM")   
  getSymbols( assets, from = "2017-01-01", auto.assign = TRUE)

  asset_prices <- xts()
  asset_prices <- Reduce(f=function(x,y) {y_sym=eval(as.name(y));  merge(x,y_sym[,paste0(y,".Adjusted")])},
                         x = assets, init=asset_prices) 
  asset_returns <- diff.xts(asset_prices, arithmetic = FALSE, na.pad=FALSE)-1

  market_return <- asset_returns$SPY.Adjusted
  stock_returns <- asset_returns[,-1] 

#
#  calculate rolling beta with a 40 trading-day window using CAPM.beta.roll
#  For this amount of data and calculating daily betas (by = 1), calculation should take 5-10 seconds
#
  width_cor = 40
  CAPM.beta_roll <- rollapply(data=stock_returns, FUN=CAPM.beta, Rb= market_return, Rf = 2.5/252, 
                       width = width_cor, by = 1, align = "right", by.column=TRUE)

#
#  calculate rolling beta with a 40 trading-day window by calculating the covariance matrix and taking ratio of two elements
#  For this amount of data and calculating daily betas (by = 1), calculation should be very quick
#
  CovVar <- function(Ra, Rb) {R = merge.xts(Rb, Ra, join="inner"); cv=cov(x=R);  
                               cv[1,-1]/cv[1,1,drop=TRUE]}
  CovVar_roll <- rollapplyr(data=stock_returns, width=width_cor,
                            FUN= CovVar,  Rb = market_return, by.column=FALSE)

#
#  since rollapply does not apply the window to Rb, it is done in CovVar for each time window
#  CovVar1 is a faster version which passes the merged market and stock return to cov directly
#  Its single argument R must be the merged data matrix R
#
  CovVar1 <- function(R){  cv=cov(x=R); cv[-1,1]/cv[1,1]}
  CovVar1_roll <- rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                             FUN= CovVar1,  by.column=FALSE)

  #
  #  CovVar2 is a faster version which passes the merged market and stock return to cov directly and 
  #  calculates the covariances only between the market returns and stock_returns.  For a small number of stocks,
  #  this is less efficient than calculating the entire covariance for a single matrix as in CovVar1 but it should become more 
  #  efficient for a larger number of stocks.
  #  Its single argument R must be the merged data matrix R
  #
  CovVar2 <- function(R){  cv = cov(R[,1], R );  cv[,-1]/cv[1,1] }
  CovVar2_roll <- rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                             FUN= CovVar2,  by.column=FALSE)

#
# Compare to verify that results are the same 
#
  print(tail(merge(CAPM.beta_roll, CovVar_roll, CovVar1_roll, CovVar2_roll )))
#
#  Compare execution times for four above methods and third method using BetaCovariance function from PerformanceAnalytics
#  This should take 25-35 seconds to run
#

  elapsed_times <- microbenchmark(
                  CAPM.beta_roll = rollapplyr(data=stock_returns, width=width_cor,
                                              FUN= CAPM.beta, Rb=market_return,by.column=FALSE),
                  BetaCoVar_roll = rollapplyr(data=stock_returns, width=width_cor,
                                               FUN= BetaCoVariance, Rb=market_return,by.column=FALSE),
                  CovVar_roll = rollapplyr(data=stock_returns, width=width_cor,
                                           FUN= CovVar,  Rb = market_return, by.column=FALSE),
                  CovVar1_roll = rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                                             FUN= CovVar1,  by.column=FALSE),
                  CovVar2_roll = rollapplyr(data=merge(market_return, stock_returns), width=width_cor,
                                             FUN= CovVar2,  by.column=FALSE),
                   times = 3)

# 
#  Direct calculation using covariance matrix, CovVar, is 50 - 100 times faster than PerformanceAnalytics functions 
#
  print(elapsed_times)

The execution times are:

Unit: milliseconds
           expr        min         lq       mean     median         uq        max neval
 CAPM.beta_roll 3007.34309 3009.92618 3016.57905 3012.50928 3021.19703 3029.88477     3
 BetaCoVar_roll 3453.83531 3471.70954 3478.91433 3489.58377 3491.45383 3493.32390     3
    CovVar_roll   69.19571   69.57012   69.83189   69.94453   70.14999   70.35544     3
   CovVar1_roll   38.72437   39.17021   39.33052   39.61605   39.63359   39.65113     3
   CovVar2_roll   60.75020   61.08255   61.36130   61.41490   61.66684   61.91878     3 

CovVar1 is the quickest since at least for a small number of dimensions, R calculates the covariance matrix much more efficiently for a single matrix input than for an input of two matrices where it has to align the matrices. For some larger number of dimensions, the CovVar2 should be faster.

这篇关于CAPM.beta rollapply的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆