# 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("HD", "WMT", "F", "IBM", "JPM")

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

2 Convert prices to returns (monthly)

asset_returns_tbl <- prices %>%

    # Calculate monthly returns
    group_by(symbol) %>%
    tq_transmute(select = adjusted,
                 mutate_fun = periodReturn,
                 period = "monthly",
                 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 (change the weigting scheme)

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

w <- c(0.25,
       0.25,
       0.20,
       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 = "months")

portfolio_returns_rebalanced_monthly_tbl
## # A tibble: 60 × 2
##    date        returns
##    <date>        <dbl>
##  1 2013-01-31  0.0506 
##  2 2013-02-28  0.00678
##  3 2013-03-28  0.0287 
##  4 2013-04-30  0.0240 
##  5 2013-05-31  0.0775 
##  6 2013-06-28 -0.0301 
##  7 2013-07-31  0.0492 
##  8 2013-08-30 -0.0633 
##  9 2013-09-30  0.0252 
## 10 2013-10-31  0.00963
## # ℹ 50 more rows
# write_rds(portfolio_returns_rebalanced_monthly_tbl,
#           "00_data/Ch03_portfolio_returns_rebalanced_monthly_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.0357  3.57

6 Plot: Expected Returns versus Risk

# 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: 60 × 2
##    date        returns
##    <date>        <dbl>
##  1 2013-01-31  0.0506 
##  2 2013-02-28  0.00678
##  3 2013-03-28  0.0287 
##  4 2013-04-30  0.0240 
##  5 2013-05-31  0.0775 
##  6 2013-06-28 -0.0301 
##  7 2013-07-31  0.0492 
##  8 2013-08-30 -0.0633 
##  9 2013-09-30  0.0252 
## 10 2013-10-31  0.00963
## # ℹ 50 more rows
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 <- 24

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.
It seems as though F, WMT, and IBM have lower expected returns than my portfolio. On the other hand, JPM and HD have greater returns than my portfolio. While my expected return may be greater from investing in an individual stock like HD or JPM, that would also add a lot of risk (standard deviation). Spreading my assets across the entire portfolio, may decrease my returns slightly, however it also greatly reduces risk (standard deviation).