# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Visualize and compare skewness of your portfolio and its assets.

Choose your stocks.

from 2020-12-31 to 2026-10-08

1 Import stock prices

symbols <- c("TSM", "MU", "NOW", "MRVL", "PLTR")

prices <- tq_get(x = symbols,
                 get = "stock.prices",
                 from = "2020-12-31",
                 to = "2026-10-08")
prices
## # A tibble: 7,240 × 8
##    symbol date        open  high   low close   volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>
##  1 TSM    2020-12-31  110.  110.  108.  109.  4909500     99.5
##  2 TSM    2021-01-04  111.  114.  110.  112. 11262100    102. 
##  3 TSM    2021-01-05  112.  115.  112.  113. 10583600    103. 
##  4 TSM    2021-01-06  114.  116.  113.  116. 10609300    105. 
##  5 TSM    2021-01-07  119.  123.  118.  121. 13556100    111. 
##  6 TSM    2021-01-08  126.  126.  117.  119. 18976800    108. 
##  7 TSM    2021-01-11  120.  124.  119.  123. 12006800    112. 
##  8 TSM    2021-01-12  125.  125.  122.  123  14163200    112. 
##  9 TSM    2021-01-13  124.  125.  118   119. 20650500    109. 
## 10 TSM    2021-01-14  123.  135.  122.  126. 37125400    115. 
## # ℹ 7,230 more rows

2 Convert prices to returns (monthly)

asset_returns_tbl2 <- 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 (change the weigting scheme)

symbols <- asset_returns_tbl2 %>% distinct(asset) %>% pull

symbols
## [1] "MRVL" "MU"   "NOW"  "PLTR" "TSM"
weight <- c(0.15, 0.20, 0.30, 0.25, 0.10)
weight
## [1] 0.15 0.20 0.30 0.25 0.10
weight_tbl2 <- tibble(symbols, weight)
weight_tbl2
## # A tibble: 5 × 2
##   symbols weight
##   <chr>    <dbl>
## 1 MRVL      0.15
## 2 MU        0.2 
## 3 NOW       0.3 
## 4 PLTR      0.25
## 5 TSM       0.1

4 Build a portfolio

library(PerformanceAnalytics)

portfolio_returns_tbl2 <- 
    asset_returns_tbl2 %>%
    
    tq_portfolio(assets_col = asset,
                 returns_col = returns,
                 weights = weight_tbl2,
                 rebalence_on = "months",
                 col_rename = "returns")

portfolio_returns_tbl2
## # A tibble: 70 × 2
##    date       returns
##    <date>       <dbl>
##  1 2021-01-29  0.127 
##  2 2021-02-26 -0.102 
##  3 2021-03-31 -0.0373
##  4 2021-04-30 -0.0186
##  5 2021-05-28 -0.0149
##  6 2021-06-30  0.106 
##  7 2021-07-30 -0.0408
##  8 2021-08-31  0.0589
##  9 2021-09-30 -0.0457
## 10 2021-10-29  0.0731
## # ℹ 60 more rows

5 Compute Skewness

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

portfolio_skew_tbl
## # A tibble: 1 × 1
##   Skewness
##      <dbl>
## 1    0.192

6 Plot: Skewness Comparison

# Data transformation: calculate skewness

asset_skewness_tbl2 <- asset_returns_tbl2 %>%
    
    group_by(asset) %>%
    summarise(skew = skewness(returns)) %>%
    
    ungroup() %>%
    
    # Add Portfolio Skewness
    add_row(tibble(asset = "Portfolio",
                   skew = skewness(portfolio_returns_tbl2$returns)))

asset_skewness_tbl2
## # A tibble: 6 × 2
##   asset       skew
##   <chr>      <dbl>
## 1 MRVL      -0.105
## 2 MU         0.779
## 3 NOW        0.451
## 4 PLTR       0.503
## 5 TSM        0.108
## 6 Portfolio  0.192
# Plot Skewness
asset_skewness_tbl2 %>%
    ggplot(aes(x = asset, y = skew, color = asset)) +
    geom_point() +
    ggrepel::geom_text_repel(aes(label = asset),
                             data = asset_skewness_tbl2 %>%
                                 filter(asset == "Portfolio")) +
    labs(y = "skewness",
         title = "Asset Returns in Measures of 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.

All of the assets, including the portfolio are likely to return a positive return in terms of skewness. The only exception is the stock MRVL. However, none of the assets qualify in regards of magnitude, as extreme is defined as a larger standard deviation than 1+. Stock MU is considerably close, with a tail of 0.8, however it is 0.2 sd short of the mark, and “only” likely to return moderate positive returns.