# 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("SPOT", "ISRG", "KHC", "FIS", "GOOG")

# Using tq_get() ----
prices <- tq_get(x = symbols,
                 get = "stock.prices",
                 from = "2019-12-31",
                 to = "2024-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() %>%

    # rename
    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.30,
       0.25,
       0.15,
       0.15,
       0.15)

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: 58 × 2
##    date        returns
##    <date>        <dbl>
##  1 2020-01-31 -0.00379
##  2 2020-02-28 -0.0617 
##  3 2020-03-31 -0.103  
##  4 2020-04-30  0.130  
##  5 2020-05-29  0.0781 
##  6 2020-06-30  0.0451 
##  7 2020-07-31  0.0769 
##  8 2020-08-31  0.0612 
##  9 2020-09-30 -0.0838 
## 10 2020-10-30 -0.0333 
## # ℹ 48 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.0655  6.55

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: 58 × 2
##    date        returns
##    <date>        <dbl>
##  1 2020-01-31 -0.00379
##  2 2020-02-28 -0.0617 
##  3 2020-03-31 -0.103  
##  4 2020-04-30  0.130  
##  5 2020-05-29  0.0781 
##  6 2020-06-30  0.0451 
##  7 2020-07-31  0.0769 
##  8 2020-08-31  0.0612 
##  9 2020-09-30 -0.0838 
## 10 2020-10-30 -0.0333 
## # ℹ 48 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))

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

Expected Returns: Some individual stocks such as GOOG and ISRG offer better returns than the portfolio, but at the cost of higher risk. Risk: The portfolio features the lowest risk which makes it the safer investment option than any of the individual stocks, especially when compared to the very high risk stock such as ISRG and SPOT

Would I invest in individual stock instead of portfolio? Personally, I would look at this data and make a new portfolio, getting rid of FIS, adding a new stock, and adding more weight to KHC to help ground the possible future returns. I personally like higher risk and more reward.