# Load packages
library(tidyverse)
library(tidyquant)
library(moments)
library(ggrepel)
library(scales)
library(stringr)

1. Import Prices

symbols <- c("AAPL", "MSFT", "GOOG", "AMZN", "TSLA", "NFLX")

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

2. Convert to Monthly log Returns

asset_returns_tbl <- prices %>%
  group_by(symbol) %>%
  tq_transmute(select = adjusted,
               mutate_fun = periodReturn,
               period = "monthly",
               type = "log") %>%
  ungroup()
# Create portfolio returns
weights <- rep(1/6, 6)

portfolio_returns_tbl <- asset_returns_tbl %>%
  tq_portfolio(
    assets_col = symbol,
    returns_col = monthly.returns,
    weights = weights,
    col_rename = "returns"
  )
# Step 1: Calculate kurtosis for the portfolio
portfolio_kurt_tbl <- portfolio_returns_tbl %>%
  tq_performance(Ra = returns, performance_fun = table.Stats) %>%
  select(Kurtosis)
# Step 2: Histogram of portfolio returns
portfolio_returns_tbl %>%
  ggplot(aes(x = returns)) +
  geom_histogram()

Step 3: Scatterplot of Expected Return vs. Kurtosis

mean_kurt_tbl <- asset_returns_tbl %>%
  group_by(symbol) %>%
  summarise(mean = mean(monthly.returns),
            kurt = kurtosis(monthly.returns)) %>%
  ungroup()

portfolio_stats <- portfolio_returns_tbl %>%
  summarise(mean = mean(returns), kurt = kurtosis(returns)) %>%
  mutate(symbol = "portfolio")

mean_kurt_tbl <- bind_rows(mean_kurt_tbl, portfolio_stats)
# Plot
mean_kurt_tbl %>%
  ggplot(aes(x = kurt, y = mean, color = symbol)) +
  geom_point() +
  geom_text_repel(aes(label = symbol)) +
  theme(legend.position = "none") +
  labs(x = "Kurtosis", y = "Expected Return") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 0.1))

Step 4: Rolling 24-Month Kurtosis Line Plot

# Set rolling window
window <- 24

rolling_kurt_tbl <- portfolio_returns_tbl %>%
  tq_mutate(select = returns,
            mutate_fun = rollapply,
            width = window,
            FUN = kurtosis,
            col_rename = "kurt") %>%
  na.omit() %>%
  select(date, kurt)
# Plot
rolling_kurt_tbl %>%
  ggplot(aes(x = date, y = kurt)) +
  geom_line(color = "cornflowerblue") +
  scale_y_continuous(breaks = seq(-1, 4, 0.5)) +
  scale_x_date(breaks = scales::pretty_breaks(n = 7)) +
  labs(
    x = NULL,
    y = "Kurtosis",
    title = paste0("Rolling ", window, " Month Kurtosis")
  ) +
  theme(plot.title = element_text(hjust = 0.5)) +
  annotate(
    "text",
    x = as.Date("2017-07-01"),
    y = 3.3,
    label = str_glue("Downside risk\nskyrocketed toward end of 2017"),
    size = 5,
    color = "red"
  )