# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Visualize and compare skewness of your portfolio and its assets.

Choose your stocks.

four stocks: “BABA”, “LLY”, “JPM”, “UNH”

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

1 Import stock prices

symbols <- c("BABA", "LLY", "JPM", "UNH") 

prices <- tq_get(x = symbols,
                 get = "stock.prices",
                 from = "2012-12-31",
                 to = "2017-12-31")
symbols
## [1] "BABA" "LLY"  "JPM"  "UNH"
prices
## # A tibble: 4,607 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 BABA   2014-09-19  92.7  99.7  89.9  93.9 271879400     89.2
##  2 BABA   2014-09-22  92.7  92.9  89.5  89.9  66657800     85.4
##  3 BABA   2014-09-23  88.9  90.5  86.6  87.2  39009800     82.8
##  4 BABA   2014-09-24  88.5  90.6  87.2  90.6  32088000     86.0
##  5 BABA   2014-09-25  91.1  91.5  88.5  88.9  28598000     84.4
##  6 BABA   2014-09-26  89.7  90.5  88.7  90.5  18340000     85.9
##  7 BABA   2014-09-29  89.6  89.7  88.0  88.8  25302000     84.3
##  8 BABA   2014-09-30  89    90.9  88.5  88.8  24419400     84.4
##  9 BABA   2014-10-01  88.7  88.9  86.0  86.1  24029600     81.8
## 10 BABA   2014-10-02  86.3  88.2  85.6  87.1  21469700     82.7
## # ℹ 4,597 more rows

2 Convert prices to returns (monthly)

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"))
asset_returns_tbl
## # A tibble: 219 × 3
##    asset date       returns
##    <chr> <date>       <dbl>
##  1 BABA  2014-10-31  0.104 
##  2 BABA  2014-11-28  0.124 
##  3 BABA  2014-12-31 -0.0715
##  4 BABA  2015-01-30 -0.154 
##  5 BABA  2015-02-27 -0.0455
##  6 BABA  2015-03-31 -0.0223
##  7 BABA  2015-04-30 -0.0237
##  8 BABA  2015-05-29  0.0942
##  9 BABA  2015-06-30 -0.0822
## 10 BABA  2015-07-31 -0.0489
## # ℹ 209 more rows

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

# symbols
symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "BABA" "JPM"  "LLY"  "UNH"
# 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 BABA       0.25
## 2 JPM        0.25
## 3 LLY        0.2 
## 4 UNH        0.3

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.0409 
##  2 2013-02-28  0.00544
##  3 2013-03-28  0.0216 
##  4 2013-04-30  0.0185 
##  5 2013-05-31  0.0337 
##  6 2013-06-28 -0.00952
##  7 2013-07-31  0.0630 
##  8 2013-08-30 -0.0338 
##  9 2013-09-30  0.00205
## 10 2013-10-31 -0.0153 
## # ℹ 50 more rows

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.486

6 Plot: 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 BABA       0.528
## 2 JPM       -0.330
## 3 LLY       -0.220
## 4 UNH       -0.261
## 5 Portfolio -0.486
# 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") 

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.

Only BABA has positive skewness meaning it is the only stock with a long tail to the right which represents upside potential. This means it is higher probability to return large gains which could potentially outweigh frequent small losses compared to the other stocks and the portfolio. This also means a shorter left tail which means extreme losses are less likely than extreme gains.