# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

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

five stocks: “CRWD”, “AMZN”, “SHOP”, “TTD”, “NVDA”

from 2012-12-31 to 2021-01-01

1 Import stock prices

# Choose stocks

symbols <- c("CRWD", "AMZN", "SHOP", "TTD", "NVDA")

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

2 Convert prices to returns

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

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

w <- c(0.30,
       0.30,
       0.10,
       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: 96 × 2
##    date        returns
##    <date>        <dbl>
##  1 2013-01-31  0.0170 
##  2 2013-02-28  0.00243
##  3 2013-03-28  0.00384
##  4 2013-04-30 -0.00755
##  5 2013-05-31  0.0231 
##  6 2013-06-28  0.00630
##  7 2013-07-31  0.0272 
##  8 2013-08-30 -0.0182 
##  9 2013-09-30  0.0374 
## 10 2013-10-31  0.0432 
## # ℹ 86 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.0637  6.37

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: 96 × 2
##    date        returns
##    <date>        <dbl>
##  1 2013-01-31  0.0170 
##  2 2013-02-28  0.00243
##  3 2013-03-28  0.00384
##  4 2013-04-30 -0.00755
##  5 2013-05-31  0.0231 
##  6 2013-06-28  0.00630
##  7 2013-07-31  0.0272 
##  8 2013-08-30 -0.0182 
##  9 2013-09-30  0.0374 
## 10 2013-10-31  0.0432 
## # ℹ 86 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.

Expect about a 1.6% return per quarter, which comes out to roughly 0.53% return per month. The best stock in my opinion would be NVIDIA because it has a high risk but with that comes a high return. A trader not looking to take a huge risk woould invest in Amazon because you would usually see slight returns with less risk. So as it would be risky to invest in just one, the portfolio as a whole provides balanced risk and reward.