# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Visualize and compare skewness of your portfolio and its assets.

Choose your stocks.

from 2020-01-01 to 2025-01-01

1 Import stock prices

symbols <- c("NXPI", "IFX.DE", "AMD", "ON")

prices <- tq_get(
  x = symbols,
  get = "stock.prices",
  from = "2020-01-01",
  to = "2025-01-01"
)

2 Convert prices to returns (monthly)

asset_returns_tbl <- prices %>%
  group_by(symbol) %>%
    
  tq_transmute(
    select       = adjusted,
    mutate_fun   = periodReturn,
    period       = "monthly",
    type         = "arithmetic",
    col_rename   = "returns") %>%
    
  slice(-1) %>%
    
  ungroup() %>%
    
  rename(asset = symbol)

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

# symbols
symbols <- asset_returns_tbl %>% distinct(asset) %>% pull(asset)
symbols
## [1] "AMD"    "IFX.DE" "NXPI"   "ON"
# weights
weights <- c(0.25, 0.25, 0.25, 0.25)
weights
## [1] 0.25 0.25 0.25 0.25
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 4 × 2
##   symbols weights
##   <chr>     <dbl>
## 1 AMD        0.25
## 2 IFX.DE     0.25
## 3 NXPI       0.25
## 4 ON         0.25

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: 63 × 2
##    date       returns
##    <date>       <dbl>
##  1 2020-02-28 -0.0895
##  2 2020-03-31 -0.222 
##  3 2020-04-30  0.226 
##  4 2020-05-29  0.0330
##  5 2020-06-30  0.119 
##  6 2020-07-31  0.138 
##  7 2020-08-31  0.0941
##  8 2020-09-30 -0.0114
##  9 2020-10-30  0.0372
## 10 2020-11-30  0.196 
## # ℹ 53 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.0876
# mean of portfolio returns
portfolio_mean_tidyquant_builtin_percent <-
    mean(portfolio_returns_tbl$returns, na.rm = TRUE)

portfolio_mean_tidyquant_builtin_percent
## [1] 0.01989704

6 Compare portfolio and asset skewness

## 6 Plot: Skewness Comparison
# skewness of each stock
asset_skew_tbl <- asset_returns_tbl %>%
    
    group_by(asset) %>%
    
    tq_performance(Ra = returns,
                   performance_fun = table.Stats) %>%
    
    select(asset, Skewness) %>%
    
    ungroup()

# combine stocks and portfolio
skew_comparison_tbl <- bind_rows(
    asset_skew_tbl,
    portfolio_skew_tidyquant_builtin_percent %>%
        mutate(asset = "portfolio") %>%
        select(asset, Skewness)
)

# plot
skew_comparison_tbl %>%
    
    ggplot(aes(x = asset, y = Skewness, color = asset)) +
    geom_point(size = 2.5) +
    
    geom_text(
        data = filter(skew_comparison_tbl, asset == "portfolio"),
        aes(label = asset),
        vjust = 1.5,
        show.legend = FALSE
    ) +
    
    labs(x = "asset",
         y = "skewness")

6 Plot: Skewness Comparison

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.

AMD and IFX.DE have higher positive skewness than my portfolio. AMD is around 0.54 and IFX.DE is around 0.16, compared to my portfolio at 0.09. This suggests their returns lean more toward extreme positive outcomes, especially AMD. NXPI is close to zero, so its returns are more balanced, while ON has negative skewness, showing a tilt toward extreme losses.