# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

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

five stocks: “BAC”, “NOK”, “F”, “T”, “NVDA”

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

1 Import stock prices

symbols <- c("BAC", "NOK", "F", "T", "NVDA")

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 <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "BAC"  "F"    "NOK"  "NVDA" "T"
# weights
weights <- c(0.2, 0.2, 0.2, 0.2, 0.2)
weights
## [1] 0.2 0.2 0.2 0.2 0.2
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 5 × 2
##   symbols weights
##   <chr>     <dbl>
## 1 BAC         0.2
## 2 F           0.2
## 3 NOK         0.2
## 4 NVDA        0.2
## 5 T           0.2

4 Build a portfolio

# tq_portfolio

portfolio_returns_tbl <- asset_returns_tbl %>%
    
    tq_portfolio(assets_col = asset,
                 returns_col = returns,
                 weights = w_tbl,
                 rebalence_on = "months",
                 col_rename = "returns")

portfolio_returns_tbl
## # A tibble: 60 × 2
##    date        returns
##    <date>        <dbl>
##  1 2013-01-31  0.00459
##  2 2013-02-28 -0.00659
##  3 2013-03-28  0.0117 
##  4 2013-04-30  0.0383 
##  5 2013-05-31  0.0494 
##  6 2013-06-28 -0.00677
##  7 2013-07-31  0.0634 
##  8 2013-08-30 -0.0208 
##  9 2013-09-30  0.103  
## 10 2013-10-31  0.0530 
## # ℹ 50 more rows

5 Calculate Kurtosis

portfolio_kurt_tidyquant_builtin_percent <- portfolio_returns_tbl %>%
    
    tq_performance(Ra = returns,
                   performance_fun = table.Stats) %>%

    select(Kurtosis)

portfolio_kurt_tidyquant_builtin_percent
## # A tibble: 1 × 1
##   Kurtosis
##      <dbl>
## 1     1.18

6 Plot

Distribution of Portfolio Returns

portfolio_returns_tbl %>%
    
    ggplot(aes(x = returns)) +
    geom_histogram()

Expected Return vs Downside Risk

# Transform data
mean_kurt_tbl <- asset_returns_tbl %>%
    
    # Calculate mean return and kurtosis for assets
    group_by(asset) %>%
    summarize(mean = mean(returns),
              kurt = kurtosis(returns)) %>%
    ungroup() %>%
    
    # Add portfolio stats
    add_row(portfolio_returns_tbl %>%
    summarize(mean = mean(returns),
              kurt = kurtosis(returns)) %>%
    mutate(asset = "Portflio"))

# Plot
mean_kurt_tbl %>%
    
    ggplot(aes(x = kurt, y = mean)) +
    geom_point() +
    ggrepel::geom_label_repel(aes(label = asset, color = asset)) +
    
    # Formatting
    theme(legend.position = "none") +
    scale_y_continuous(labels = scales::percent_format(accuracy = 0.1)) +
    
    # Labeling
    labs(x = "Kurtosis", 
         y = "Expected Returns")

Rolling 24 Month Kurtosis

# Assign a value for window
window = 24

# Transform data: calculate 24 month rolling kurtosis
rolling_kurt_tbl <- portfolio_returns_tbl %>%

    tq_mutate(select = returns, 
              mutate_fun = rollapply, 
              width = window,
              FUN = kurtosis, 
              col_rename = "kurt") %>%

    na.omit() %>%
        select(-returns) 
    
# Plot
rolling_kurt_tbl %>%
    
    ggplot(aes(x = date, y = kurt)) +
    geom_line(color = "cornflowerblue") +

# Formatting
scale_y_continuous(breaks = seq(-1, 4, 0.5)) +
scale_x_date(breaks = scales::pretty_breaks(n = 7)) +
    theme(plot.title = element_text(hjust = 0.5)) +

# Labeling
    labs(x = NULL,
       y = "Kurtosis",
       title = paste0("Rolling", window, " Month Kurtosis")) +
           
    annotate(geom = "text", x = as.Date("2016-07-01"), y = 3,
             label = str_glue("Downside risk stayed 
                              consistently low"))

### Has the downside risk of your portfolio increased or decreased over time? You may also refer to the skewness of the returns distribution you plotted in the previous assignment.

The downside risk of the portfolio remained relatively low overtime. The rolling 24 month kurtosis stayed mostly between -0.6 and 0.5, showing that extreme negative returns were uncommon. There is a spike around 2017, the overall risk remained stable.