What is CAMP? https://www.investopedia.com/terms/c/capm.asp

Step 1: Import stock prices and calculate returns.

# Load packages
library(tidyquant)
library(tidyverse)

# Asset Period Returns
stock_returns_monthly <- c("AAPL", "GOOG", "NFLX") %>%
    tq_get(get  = "stock.prices",
           from = "2010-01-01",
           to   = "2015-12-31") %>%
    group_by(symbol) %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn, 
                 period     = "monthly", 
                 col_rename = "Ra")
stock_returns_monthly 
## # A tibble: 216 x 3
## # Groups:   symbol [3]
##    symbol date            Ra
##    <chr>  <date>       <dbl>
##  1 AAPL   2010-01-29 -0.103 
##  2 AAPL   2010-02-26  0.0654
##  3 AAPL   2010-03-31  0.148 
##  4 AAPL   2010-04-30  0.111 
##  5 AAPL   2010-05-28 -0.0161
##  6 AAPL   2010-06-30 -0.0208
##  7 AAPL   2010-07-30  0.0227
##  8 AAPL   2010-08-31 -0.0550
##  9 AAPL   2010-09-30  0.167 
## 10 AAPL   2010-10-29  0.0607
## # ... with 206 more rows

Step 2: Import a baseline index fund and calculate returns.

Hint: Use the Technology Select Sector SPDR Fund (XLK) as the baseline fund.

# Baseline Period Returns
baseline_returns_monthly <- "XLK" %>%
    tq_get(get  = "stock.prices",
           from = "2010-01-01",
           to   = "2015-12-31") %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn, 
                 period     = "monthly", 
                 col_rename = "Rb")
baseline_returns_monthly
## # A tibble: 72 x 2
##    date            Rb
##    <date>       <dbl>
##  1 2010-01-29 -0.0993
##  2 2010-02-26  0.0348
##  3 2010-03-31  0.0684
##  4 2010-04-30  0.0126
##  5 2010-05-28 -0.0748
##  6 2010-06-30 -0.0540
##  7 2010-07-30  0.0745
##  8 2010-08-31 -0.0561
##  9 2010-09-30  0.117 
## 10 2010-10-29  0.0578
## # ... with 62 more rows

So far it’s been the same with single portfolio case.

Step 3A: Aggregate Portfolio Returns for Multiple Portfolios

# scaling a single portfolio to many, 3 in this case
stock_returns_monthly_multi <- stock_returns_monthly %>%
    tq_repeat_df(n = 3)
stock_returns_monthly_multi
## # A tibble: 648 x 4
## # Groups:   portfolio [3]
##    portfolio symbol date            Ra
##        <int> <chr>  <date>       <dbl>
##  1         1 AAPL   2010-01-29 -0.103 
##  2         1 AAPL   2010-02-26  0.0654
##  3         1 AAPL   2010-03-31  0.148 
##  4         1 AAPL   2010-04-30  0.111 
##  5         1 AAPL   2010-05-28 -0.0161
##  6         1 AAPL   2010-06-30 -0.0208
##  7         1 AAPL   2010-07-30  0.0227
##  8         1 AAPL   2010-08-31 -0.0550
##  9         1 AAPL   2010-09-30  0.167 
## 10         1 AAPL   2010-10-29  0.0607
## # ... with 638 more rows

Examining the results, we can see that a few things happened:

  1. The length (number of rows) has tripled. This is the essence of tq_repeat_df: it grows the data frame length-wise, repeating the data frame n times. In our case, n = 3. Our data frame, which was grouped by symbol, was ungrouped. This is needed to prevent tq_portfolio from blending on the individual stocks. tq_portfolio only works on groups of stocks.
  2. We have a new column, named “portfolio”. The “portfolio” column name is a key that tells tq_portfolio that multiple groups exist to analyze. Just note that for multiple portfolio analysis, the “portfolio” column name is required.
  3. We have three groups of portfolios. This is what tq_portfolio will split, apply (aggregate), then combine on.
# Create Vector of Weights
# not all symbols need to be specified. Any symbol not specified by default gets a weight of zero.
weights <- c(
    0.50, 0.25, 0.25,
    0.25, 0.50, 0.25,
    0.25, 0.25, 0.50
)
stocks <- c("AAPL", "GOOG", "NFLX")
weights_table <-  tibble(stocks) %>%
    tq_repeat_df(n = 3) %>%
    bind_cols(tibble(weights)) %>%
    group_by(portfolio)
weights_table
## # A tibble: 9 x 3
## # Groups:   portfolio [3]
##   portfolio stocks weights
##       <int> <chr>    <dbl>
## 1         1 AAPL      0.5 
## 2         1 GOOG      0.25
## 3         1 NFLX      0.25
## 4         2 AAPL      0.25
## 5         2 GOOG      0.5 
## 6         2 NFLX      0.25
## 7         3 AAPL      0.25
## 8         3 GOOG      0.25
## 9         3 NFLX      0.5




# Aggregate a Portfolio using Vector of Weights
portfolio_returns_monthly_multi  <-
  stock_returns_monthly_multi %>%
    tq_portfolio(assets_col  = symbol, 
                 returns_col = Ra, 
                 weights     = weights_table, 
                 col_rename  = "Ra")
portfolio_returns_monthly_multi 
## # A tibble: 216 x 3
## # Groups:   portfolio [3]
##    portfolio date              Ra
##        <int> <date>         <dbl>
##  1         1 2010-01-29 -0.0489  
##  2         1 2010-02-26  0.0482  
##  3         1 2010-03-31  0.123   
##  4         1 2010-04-30  0.145   
##  5         1 2010-05-28  0.0245  
##  6         1 2010-06-30 -0.0308  
##  7         1 2010-07-30  0.000600
##  8         1 2010-08-31  0.0474  
##  9         1 2010-09-30  0.222   
## 10         1 2010-10-29  0.0789  
## # ... with 206 more rows

Step 3B: Merging Ra and Rb

# Merging Ra and Rb
RaRb_single_portfolio <- left_join(portfolio_returns_monthly_multi , 
                                   baseline_returns_monthly,
                                   by = "date")
RaRb_single_portfolio
## # A tibble: 216 x 4
## # Groups:   portfolio [?]
##    portfolio date              Ra      Rb
##        <int> <date>         <dbl>   <dbl>
##  1         1 2010-01-29 -0.0489   -0.0993
##  2         1 2010-02-26  0.0482    0.0348
##  3         1 2010-03-31  0.123     0.0684
##  4         1 2010-04-30  0.145     0.0126
##  5         1 2010-05-28  0.0245   -0.0748
##  6         1 2010-06-30 -0.0308   -0.0540
##  7         1 2010-07-30  0.000600  0.0745
##  8         1 2010-08-31  0.0474   -0.0561
##  9         1 2010-09-30  0.222     0.117 
## 10         1 2010-10-29  0.0789    0.0578
## # ... with 206 more rows

Step 4: Computing the CAPM Table

RaRb_single_portfolio %>%
    tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.CAPM) %>%
  t()
##                      [,1]   [,2]    [,3]
## portfolio          1.0000 2.0000  3.0000
## ActivePremium      0.2520 0.2304  0.3267
## Alpha              0.0203 0.0197  0.0310
## AnnualizedAlpha    0.2726 0.2632  0.4423
## Beta               0.9314 0.9018  0.7342
## Beta-              0.3438 0.4527 -0.1644
## Beta+              0.7142 0.6456  0.3860
## Correlation        0.4862 0.4495  0.2599
## Correlationp-value 0.0000 0.0001  0.0275
## InformationRatio   1.0132 0.8650  0.8030
## R-squared          0.2364 0.2021  0.0675
## TrackingError      0.2487 0.2664  0.4068
## TreynorRatio       0.4086 0.3981  0.6202

Interpreting CAPM model results http://www.moneychimp.com/articles/risk/regression.htm