# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Visualize and compare skewness of your portfolio and its assets.

Choose your stocks.

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

1 Import stock prices

symbols <- c("TM", "SBUX", "AEO", "BBW")
prices <- tq_get(x = symbols, 
                 get = "stock.prices", 
                 from = "2012-12-31", 
                 to = "2017-12-31")

2 Convert prices to returns (monthly)

asset_returns_tbl <- prices %>%
    
    group_by(symbol) %>%
    
    tq_transmute(select = adjusted, 
                 mutate_fun = periodReturn, 
                 period = "quarterly", 
                 type = "log") %>%
    
    slice(-1) %>%
    
    ungroup() %>%
    
    set_names(c("asset", "date", "returns"))

3 Assign a weight to each asset (change the weigting scheme)

# symbols 
symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "AEO"  "BBW"  "SBUX" "TM"
# weights
weights <- c(0.25, 0.25, 0.2, 0.3)
weights
## [1] 0.25 0.25 0.20 0.30
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 4 × 2
##   symbols weights
##   <chr>     <dbl>
## 1 AEO        0.25
## 2 BBW        0.25
## 3 SBUX       0.2 
## 4 TM         0.3

4 Build a 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: 20 × 2
##    date        returns
##    <date>        <dbl>
##  1 2013-03-28  0.108  
##  2 2013-06-28  0.103  
##  3 2013-09-30  0.0238 
##  4 2013-12-31  0.0187 
##  5 2014-03-31 -0.00730
##  6 2014-06-30  0.0916 
##  7 2014-09-30  0.0548 
##  8 2014-12-31  0.136  
##  9 2015-03-31  0.112  
## 10 2015-06-30 -0.0356 
## 11 2015-09-30 -0.00379
## 12 2015-12-31 -0.0806 
## 13 2016-03-31 -0.00559
## 14 2016-06-30 -0.0278 
## 15 2016-09-30  0.00508
## 16 2016-12-30  0.0425 
## 17 2017-03-31 -0.142  
## 18 2017-06-30 -0.00367
## 19 2017-09-29  0.0345 
## 20 2017-12-29  0.108

5 Compute Skewness

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

portfolio_skew_tidyquant_builtin_percent
## # A tibble: 1 × 1
##   Skewness
##      <dbl>
## 1   -0.424

6 Plot: Skewness Comparison

Histogram of Expected Returns and Risk

# Calculate sd of portfolio returns
sd_portfolio <- sd(portfolio_returns_tbl$returns)
mean_portfolio <- mean(portfolio_returns_tbl$returns)

portfolio_returns_tbl %>%
    
    # Add a new variable
    mutate(extreme_neg = ifelse(returns < mean_portfolio - 2 * sd_portfolio,
                                "ext_neg",
                                "not_ext_neg")) %>%
    
    ggplot(aes(x = returns, fill = extreme_neg)) +
    geom_histogram(binwidth = 0.005) +
    
    scale_x_continuous(breaks = seq(-0.16, 0.16, 0.04)) +
    
    labs(x = "monthly returns")

Scatter Plot of Skewness Comparison

# Data transformation: calculate skewness
asset_skewness_tbl <- asset_returns_tbl %>%
    
    group_by(asset) %>%
    summarise(skew = skewness(returns)) %>%
    ungroup() %>%
    
    # Add portfolio skewness
    add_row(tibble(asset = "Portfolio",
                   skew = skewness(portfolio_returns_tbl$returns)))

asset_skewness_tbl
## # A tibble: 5 × 2
##   asset        skew
##   <chr>       <dbl>
## 1 AEO        0.442 
## 2 BBW       -0.522 
## 3 SBUX       0.0366
## 4 TM         0.0140
## 5 Portfolio -0.424
# Plot skewness
asset_skewness_tbl %>%
    
    ggplot(aes(x = asset, y = skew, color = asset)) +
    geom_point() +
    
    ggrepel::geom_text_repel(aes(label = asset), 
                             data = asset_skewness_tbl %>%
                                 filter(asset == "Portfolio")) +
    
    labs(y = "skewness")

Rolling Skewness

# Transform data: calculate rolling skewness
rolling_skew_tbl <- portfolio_returns_tbl %>%
    
    tq_mutate(select = returns, 
              mutate_fun = rollapply, 
              width = 12,
              FUN = skewness, 
              col_rename = "Skew") %>%
    
    select (-returns) %>%
    na.omit()

# Plot 
rolling_skew_tbl %>%
    
    ggplot(aes(x = date, y = Skew)) +
    geom_line(color = "cornflowerblue") +
    
    geom_hline(yintercept = 0, linetype = "dotted", size = 2) +
    
    # Formatting 
    scale_y_continuous(limits = c(-1,1), breaks = seq(-1,1,0.2)) +
    theme(plot.title = element_text(hjust = 0.5)) +
    
    # Labeling 
    labs(y = "Skewness",
         x = NULL, 
         title = "Rolling 12-Month Skewness") +
    
    annotate(geom = "text",
            x = as.Date("2017-01-01"),
            y = 0.8,
            color = "red",
            size = 5,
            label = str_glue("The 24-month skewness is negative for all of the lifetime."))

Is any asset in your portfolio more likely to return extreme positive returns than your portfolio collectively? Discuss in terms of skewness. You may also refer to the distribution of returns you plotted in Code along 4.

Based on the Scatter Plot of Skewness Comparison graph, AEO, SBUX, and TM are likely to have more positive returns than the portfolio. This is because these three assets show positively skewed values while the portfolio is very negatively skewed. However, SBUX and TM have values closer to zero meaning they have little skewness.

This can also be seen in the Distribution of Monthly Returns plot from code along 4 as AEO is more skewed to the right, and SBUX and TM have almost no skewness.

BBW is more negative than the portfolio and it is still negatively skewed showing almost a flat line on the Distribution graph.