# Load packages

# Core
library(tidyverse)
library(tidyquant)

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

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

1 Import stock prices

symbols <- c("MCD", "ISRG", "KHC", "FIS", "GOOG")

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 %>%
    
    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] "FIS"  "GOOG" "ISRG" "KHC"  "MCD"
# weights
weights <- c(0.3, 0.3, 0.15, 0.15, 0.1)
weights
## [1] 0.30 0.30 0.15 0.15 0.10
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 5 × 2
##   symbols weights
##   <chr>     <dbl>
## 1 FIS        0.3 
## 2 GOOG       0.3 
## 3 ISRG       0.15
## 4 KHC        0.15
## 5 MCD        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.0705 
##  2 2013-02-28  0.00545
##  3 2013-03-28  0.0127 
##  4 2013-04-30  0.0319 
##  5 2013-05-31  0.0329 
##  6 2013-06-28 -0.00442
##  7 2013-07-31 -0.0361 
##  8 2013-08-30 -0.00886
##  9 2013-09-30  0.0225 
## 10 2013-10-31  0.0618 
## # ℹ 50 more rows

5 Calculate Skewness

portfolio_returns_tbl %>%

    tq_performance(Ra = returns,
                   Rb = NULL,
                   performance_fun = table.Stats) %>%
    select(Kurtosis)
## # A tibble: 1 × 1
##   Kurtosis
##      <dbl>
## 1    0.200

6 Plot

Rolling kurtosis

# 3 Rolling kurtosis ----

# Assign a value to winder
window <- 24

port_rolling_kurtosis_tbl <- portfolio_returns_tbl %>%

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

# Figure 6.5 Rolling kurtosis ggplot ----

port_rolling_kurtosis_tbl %>%

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

    scale_y_continuous(breaks = scales::pretty_breaks(n = 10)) +
    scale_x_date(breaks = scales::breaks_pretty(n = 7)) +

    labs(title = paste0("Rolling ", window, "-Month Kurtosis"),
         x = NULL,
         y = "kurtosis") +
    theme(plot.title = element_text(hjust = 0.5)) +

    annotate(geom = "text",
             x = as.Date("2016-12-01"), y = 3.5,
             color = "red", size = 5,
             label = str_glue(""))

Has the downside risk of your portfolio increased or decreased over time? Explain using the plot you created.

Initially, the downside risk was low, but it increased sharply as kurtosis rose, indicating the presence of more extreme fluctuations in portfolio returns. Over time, the jagged decline and subsequent stabilization suggest that the downside risk began to decrease, leading to more stable returns. However, in the final period, kurtosis dipped below zero, reaching -1.0, which reflects a shift towards even fewer extreme movements and greater stability.