# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Calculate and visualize your portfolio’s beta.

Choose your stocks and the baseline market.

from 2012-12-31 to present

1 Import stock prices

symbols <- c("WMT", "AAPL", "NFLX", "GOOGL")

prices <- tq_get(x   = symbols,
                get  = "stock.prices",
                from = "2012-12-31")
prices
## # A tibble: 13,952 × 8
##    symbol date        open  high   low close   volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>
##  1 WMT    2012-12-31  22.5  22.8  22.5  22.7 21037500     17.4
##  2 WMT    2013-01-02  23.0  23.1  22.8  23.1 31172400     17.7
##  3 WMT    2013-01-03  23.1  23.1  22.8  22.9 26730300     17.6
##  4 WMT    2013-01-04  22.9  23.1  22.8  23.0 19314000     17.7
##  5 WMT    2013-01-07  22.9  23.0  22.7  22.8 18604200     17.5
##  6 WMT    2013-01-08  22.8  23.0  22.7  22.9 17600700     17.5
##  7 WMT    2013-01-09  22.9  22.9  22.7  22.9 15165600     17.5
##  8 WMT    2013-01-10  22.9  23.0  22.6  22.8 34361400     17.5
##  9 WMT    2013-01-11  22.9  22.9  22.7  22.9 18673500     17.6
## 10 WMT    2013-01-14  22.8  22.9  22.7  22.8 16471200     17.5
## # ℹ 13,942 more rows

2 Convert prices to returns (monthly)

asset_returns_tbl <- prices %>%
    
    group_by(symbol) %>%
    
    tq_transmute(select     = adjusted,
                 mutate_fun = periodReturn,
                 period     = "monthly",
                 type       = "log") %>%
    slice(-1) %>%
    ungroup() %>%
    set_names(c("asset", "date", "returns"))

asset_returns_tbl
## # A tibble: 668 × 3
##    asset date         returns
##    <chr> <date>         <dbl>
##  1 AAPL  2013-01-31 -0.156   
##  2 AAPL  2013-02-28 -0.0256  
##  3 AAPL  2013-03-28  0.00285 
##  4 AAPL  2013-04-30  0.000271
##  5 AAPL  2013-05-31  0.0222  
##  6 AAPL  2013-06-28 -0.126   
##  7 AAPL  2013-07-31  0.132   
##  8 AAPL  2013-08-30  0.0804  
##  9 AAPL  2013-09-30 -0.0217  
## 10 AAPL  2013-10-31  0.0920  
## # ℹ 658 more rows

3 Assign a weight to each asset (change the weigting scheme)

# symbols
symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "AAPL"  "GOOGL" "NFLX"  "WMT"
# weights
weights <- c(0.35, 0.30, 0.20, 0.15)
weights
## [1] 0.35 0.30 0.20 0.15
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 4 × 2
##   symbols weights
##   <chr>     <dbl>
## 1 AAPL       0.35
## 2 GOOGL      0.3 
## 3 NFLX       0.2 
## 4 WMT        0.15

4 Build a portfolio

portfolio_returns_tbl <- asset_returns_tbl %>%
    
    tq_portfolio(assets_col   = asset,
                 returns_col  = returns,
                 weights      = w_tbl,
                 rebalance_on = "months",
                 col_rename   = "returns")

portfolio_returns_tbl
## # A tibble: 167 × 2
##    date        returns
##    <date>        <dbl>
##  1 2013-01-31  0.0849 
##  2 2013-02-28  0.0362 
##  3 2013-03-28  0.00894
##  4 2013-04-30  0.0435 
##  5 2013-05-31  0.0287 
##  6 2013-06-28 -0.0555 
##  7 2013-07-31  0.0849 
##  8 2013-08-30  0.0350 
##  9 2013-09-30  0.0216 
## 10 2013-10-31  0.0949 
## # ℹ 157 more rows

5 Calculate CAPM Beta

5.1 Get market returns

market_returns_tbl <- tq_get(x    = "SPY",
                 get  = "stock.prices",
                 from = "2012-12-31") %>%
    # Convert prices to returns
    tq_transmute(select     = adjusted,
                 mutate_fun = periodReturn, 
                 period     = "monthly",
                 type       = "log", 
                 col_rename = "returns") %>% 
    slice(-1)

market_returns_tbl
## # A tibble: 167 × 2
##    date       returns
##    <date>       <dbl>
##  1 2013-01-31  0.0499
##  2 2013-02-28  0.0127
##  3 2013-03-28  0.0373
##  4 2013-04-30  0.0190
##  5 2013-05-31  0.0233
##  6 2013-06-28 -0.0134
##  7 2013-07-31  0.0504
##  8 2013-08-30 -0.0305
##  9 2013-09-30  0.0312
## 10 2013-10-31  0.0453
## # ℹ 157 more rows

5.2 Join returns

portfolio_market_returns_tbl <- left_join(market_returns_tbl, portfolio_returns_tbl, by = "date") %>% 
    
    set_names("date", "market_returns", "portfolio_returns")

5.3 CAPM Beta

portfolio_market_returns_tbl %>%
    
    tq_performance(Ra = portfolio_returns,
                   Rb = market_returns, 
                   performance_fun = CAPM.beta)
## # A tibble: 1 × 1
##   CAPM.beta.1
##         <dbl>
## 1        1.06

6 Plot: Scatter with regression line

portfolio_market_returns_tbl %>%
    
    ggplot(aes(x = market_returns,
               y = portfolio_returns)) + 
    geom_point(color = "cornflowerblue") + 
    geom_smooth(method = "lm", se = FALSE, size = 1.5, color = tidyquant::palette_light()[3]) + 
    
    labs(y = "Portfolio Returns", 
         x = "Market Returns")

How sensitive is your portfolio to the market? Discuss in terms of the beta coefficient. Does the plot confirm the beta coefficient you calculated?

With a beta coefficient of 1.06, this portfolio is slightly more volatile than the market. It is expected to be about 6% more volatile than the market both generating slightly larger returns and slightly larger losses. Looking at the plot, I would say it partially confirms my beta calculation. The points in the plot graph are slightly off the line for the most part, but they still follow the general direction of the line. There’s some points that fall right on the line and some that a very close to it. But, the majority of the points are a bit far off this regression line. A moderate to weak linear relationship means the beta coefficient is not the only defining factor in the portfolio returns. There are outside factors that are clearly contributing to these returns compared to the markets that are not being looked at here. Solely market movements cannot define the returns my portfolio is generating; even with the beta calculation.