# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Collect individual returns into a portfolio by assigning a weight to each stock

five stocks: “SPY”, “EFA”, “IJS”, “EEM”, “AGG”

from 2012-12-31 to 2017-12-31

1 Import stock prices

symbols <- c("NFLX", "MSFT", "NVDA", "AAPL", "TSLA")
prices <- tq_get(x = symbols,
                 from = "2012-12-31",
                 to = "2017-12-31")

2 Convert prices to returns

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"))

3 Assign a weight to each asset

#symbols
symbols <- asset_returns_tbl %>% distinct (asset) %>% pull()
symbols
## [1] "AAPL" "MSFT" "NFLX" "NVDA" "TSLA"
#weights
weight <- c(0.25,0.25,0.2,0.2,0.1)
weight
## [1] 0.25 0.25 0.20 0.20 0.10
w_tbl <- tibble(symbols,weight)
w_tbl
## # A tibble: 5 × 2
##   symbols weight
##   <chr>    <dbl>
## 1 AAPL      0.25
## 2 MSFT      0.25
## 3 NFLX      0.2 
## 4 NVDA      0.2 
## 5 TSLA      0.1

4 Build a portfolio

#?tq_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: 60 × 2
##    date       returns
##    <date>       <dbl>
##  1 2013-01-31  0.0940
##  2 2013-02-28  0.0250
##  3 2013-03-28  0.0203
##  4 2013-04-30  0.113 
##  5 2013-05-31  0.100 
##  6 2013-06-28 -0.0446
##  7 2013-07-31  0.0700
##  8 2013-08-30  0.0920
##  9 2013-09-30  0.0349
## 10 2013-10-31  0.0231
## # ℹ 50 more rows

5 Calculate CAPM Beta

market_returns_tbl <- tq_get(x = "SPY",
                get = "stock.prices",
                 from = "2012-12-31",
                 to = "2017-12-31") %>%

#Convert Prices to Returns

tq_transmute (select     = adjusted, 
                  mutate_fun = periodReturn, 
                  period     = "monthly",
                  type       = "log")    %>%
    
    slice(-1)

Join Returns

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

    set_names("date", "market_returns","portfolio_returns")

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.09

ScatterPlot with Regression Line

portfolio_market_returns_tbl %>%
    ggplot(aes(x = market_returns,
               y = portfolio_returns)) +
    geom_point(color = "blue") +
    geom_smooth(method = "lm", se = FALSE, size = 1.5, color = "green") +
    labs(x = "Market Returns",
         y = "Portfolio Returns")

Line Plot of Fitted Returns

actual_fitted_long_tbl <- portfolio_market_returns_tbl %>%
    #Linear Regression
    lm(portfolio_returns ~ market_returns, data = .) %>%
    #Fitted and Actual Returns
    broom::augment() %>%
    #Add Date
    mutate(date = portfolio_market_returns_tbl$date) %>%
    select(date, portfolio_returns, .fitted) %>%
    #Transform Data to Long
    pivot_longer(cols = c(portfolio_returns, .fitted), names_to = "type", values_to = "returns")

actual_fitted_long_tbl %>%
    ggplot(aes(x = date,
               y = returns,
               color = type)) +
    geom_line() 

6 Plot: Scatter with regression line

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

Given the beta of 1.09 this portfolio remains relatively close to market outcomes on a daily basis. Comparative to high risk portfolio beta with betas closer to 2, a beta of 1.09 would be considered conservative. The scatter plot does reinforce this beta, minus a couple one-off exceptions. The fitted returns line chart makes these returns appear more dramatically different, however the returns often do follow the same direction as the market returns just to a wider extent.