# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Visualize expected returns and risk to make it easier to compare the performance of multiple assets and portfolios.

Choose your stocks.

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

1 Import stock prices

# Choose stocks

symbols <- c("SPY", "IBM", "TSLA")

# Using tq_get() ----
prices <- tq_get(x = symbols,
                 get = "stock.prices",
                 from = "2012-12-31",
                 to = "2017-12-31")

2 Convert prices to returns

asset_returns_tbl <- prices %>%

    # Calculate quarterly returns
    group_by(symbol) %>%
    tq_transmute(select = adjusted,
                 mutate_fun = periodReturn,
                 period = "quarterly",
                 type = "log") %>%
    slice(-1) %>%
    ungroup() %>%

    # remane
    set_names(c("asset", "date", "returns"))

# period_returns = c("yearly", "quarterly", "monthly", "weekly")

3 Assign a weight to each asset

symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()

w <- c(0.25,
       0.20,
       0.10)

w_tbl <- tibble(symbols, w)

4 Build a portfolio

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

portfolio_returns_rebalanced_monthly_tbl
## # A tibble: 20 × 2
##    date         returns
##    <date>         <dbl>
##  1 2013-03-28  0.0591  
##  2 2013-06-28  0.0836  
##  3 2013-09-30  0.0624  
##  4 2013-12-31 -0.000552
##  5 2014-03-31  0.0438  
##  6 2014-06-30  0.0106  
##  7 2014-09-30  0.0164  
##  8 2014-12-31 -0.0395  
##  9 2015-03-31 -0.0128  
## 10 2015-06-30  0.0408  
## 11 2015-09-30 -0.0477  
## 12 2015-12-31 -0.000540
## 13 2016-03-31  0.0248  
## 14 2016-06-30 -0.000118
## 15 2016-09-30  0.0170  
## 16 2016-12-30  0.0256  
## 17 2017-03-31  0.0519  
## 18 2017-06-30  0.00366 
## 19 2017-09-29 -0.00921 
## 20 2017-12-29  0.0204
# write_rds(portfolio_returns_rebalanced_quarterly_tbl,
#           "00_data/Ch03_portfolio_returns_rebalanced_quarterly_tbl.rds")

5 Compute Standard Deviation

portfolio_sd_tidyquant_builtin_percent <- portfolio_returns_rebalanced_monthly_tbl %>%
    
    tq_performance(Ra = returns,
                   Rb = NULL, 
                   performance_fun = table.Stats) %>%
    
    select(Stdev) %>%
    mutate(tq_sd = round(Stdev, 4) * 100)

portfolio_sd_tidyquant_builtin_percent
## # A tibble: 1 × 2
##    Stdev tq_sd
##    <dbl> <dbl>
## 1 0.0332  3.32

6 Plot

# Figure 4.1 Dispersion of Portfolio Returns ----

portfolio_returns_rebalanced_monthly_tbl %>%

    ggplot(aes(date, returns)) +
    geom_point(color = "cornflowerblue", size = 2) +

    labs(title = "Scatterplot of Returns by Date") +
    theme(plot.title = element_text(hjust = 0.5))

# Figure 4.2 Scatter of Returns Colored by Distance from Mean ----

sd_plot <- sd(portfolio_returns_rebalanced_monthly_tbl$returns)
mean_plot <- mean(portfolio_returns_rebalanced_monthly_tbl$returns)

portfolio_returns_rebalanced_monthly_tbl %>%

    mutate(hist_col = case_when(
        returns > mean_plot + sd_plot ~ "high",
        returns < mean_plot - sd_plot ~ "middle",
        TRUE                          ~ "low"
    )) %>%

    # Plot
    ggplot(aes(date, returns, col = hist_col)) +
    geom_point(size = 2) +

    labs(title = "Colored Scatter") +
    theme(plot.title = element_text(hjust = 0.5))

# Figure 4.3 Scatter of Returns with Line at Standard Deviation ----

sd_plot <- sd(portfolio_returns_rebalanced_monthly_tbl$returns)
mean_plot <- mean(portfolio_returns_rebalanced_monthly_tbl$returns)

portfolio_returns_rebalanced_monthly_tbl %>%

    mutate(hist_col = case_when(
        returns > mean_plot + sd_plot ~ "high",
        returns < mean_plot - sd_plot ~ "middle",
        TRUE                          ~ "low"
    )) %>%

    # Plot
    ggplot(aes(date, returns, col = hist_col)) +
    geom_point(size = 2) +

    labs(title = "Colored Scatter with Line") +
    theme(plot.title = element_text(hjust = 0.5)) +

    # Add lines
    geom_hline(yintercept = mean_plot + sd_plot, linetype = "dotted", color = "purple") +
    geom_hline(yintercept = mean_plot - sd_plot, linetype = "dotted", color = "purple")

# Figure 4.4 Asset and Portfolio Standard Deviation Comparison ----

portfolio_returns_rebalanced_monthly_tbl
## # A tibble: 20 × 2
##    date         returns
##    <date>         <dbl>
##  1 2013-03-28  0.0591  
##  2 2013-06-28  0.0836  
##  3 2013-09-30  0.0624  
##  4 2013-12-31 -0.000552
##  5 2014-03-31  0.0438  
##  6 2014-06-30  0.0106  
##  7 2014-09-30  0.0164  
##  8 2014-12-31 -0.0395  
##  9 2015-03-31 -0.0128  
## 10 2015-06-30  0.0408  
## 11 2015-09-30 -0.0477  
## 12 2015-12-31 -0.000540
## 13 2016-03-31  0.0248  
## 14 2016-06-30 -0.000118
## 15 2016-09-30  0.0170  
## 16 2016-12-30  0.0256  
## 17 2017-03-31  0.0519  
## 18 2017-06-30  0.00366 
## 19 2017-09-29 -0.00921 
## 20 2017-12-29  0.0204
asset_returns_sd_tbl <- asset_returns_tbl %>%

    group_by(asset) %>%
    tq_performance(Ra = returns,
                   Rb = NULL,
                   performance_fun = table.Stats) %>%

    select(asset, Stdev) %>%
    ungroup() %>%

    # Add portfolio sd
    add_row(tibble(asset = "Portfolio",
                  Stdev = sd(portfolio_returns_rebalanced_monthly_tbl$returns)))

asset_returns_sd_tbl %>%

    # Plot
    ggplot(aes(asset, Stdev, col = asset)) +
    geom_point() +
    ggrepel::geom_text_repel(aes(label = asset),
                             data = asset_returns_sd_tbl %>%
                                 filter(asset == "Portfolio")) +

    labs(title = "")

# Figure 4.5 Expected Returns versus Risk ----

asset_returns_sd_mean_tbl <- asset_returns_tbl %>%

    group_by(asset) %>%
    tq_performance(Ra = returns,
                   Rb = NULL,
                   performance_fun = table.Stats) %>%

    select(asset, Mean = ArithmeticMean, Stdev) %>%
    ungroup() %>%

    add_row(tibble(asset = "Portfolio",
                   Mean  = mean(portfolio_returns_rebalanced_monthly_tbl$returns),
                   Stdev = sd(portfolio_returns_rebalanced_monthly_tbl$returns)))


asset_returns_sd_mean_tbl %>%

    ggplot(aes(Stdev, Mean, col = asset)) +
    geom_point() +
    ggrepel::geom_text_repel(aes(label = asset))

# 3 Rolling standard deviation ----
# Why rolling sd?
# Suppose that we have 10 years of data and calculated standard deviation for every six months.
# Consider two different scenarios: 1) sd of each six-month period is always 3% and
# 2) sd for each six-month period fluctuated between 0% and 6%.
# It's possible that both scenarios have the same 3% sd for the entire period, which are not the same
# Rolling sd can show us what might have caused spikes in volatility
# and consider dynamically rebalancing the portfolio to better manage the volatility

# Assign a value to winder
window <- 12

port_rolling_sd_tbl <- portfolio_returns_rebalanced_monthly_tbl %>%

    tq_mutate(select = returns,
              mutate_fun = rollapply,
              width      = window,
              FUN        = sd,
              col_rename = "rolling_sd") %>%
    select(date, rolling_sd) %>%
    na.omit()

# Figure 4.7 Rolling Volatility ggplot ----

port_rolling_sd_tbl %>%

    ggplot(aes(date, rolling_sd)) +
    geom_line(color = "cornflowerblue") +

    scale_y_continuous(labels = scales::percent) +
    scale_x_date(breaks = scales::breaks_pretty(n = 7))+

    labs(title = "24-Month Rolling Volatility",
         x = NULL,
         y = NULL) +
    theme(plot.title = element_text(hjust = 0.5))

How should you expect your portfolio to perform relative to its assets in the portfolio? Would you invest all your money in any of the individual stocks instead of the portfolio? Discuss both in terms of expected return and risk.

I expect my portfolio to preform well, give me good returns with also low risk. But it does suggest that I invest all of my money into the SPY 500 as it is just as risky as my portfolio but should give me better returns. SPY’s mean is higher then portfolio while the stdev remains the same.