# Load packages
# Core
library(tidyverse)
library(tidyquant)
Visualize and compare skewness of your portfolio and its assets.
symbols <- c("UNH", "LLY", "JNJ", "PFE", "MRK")
prices <- tq_get(x = symbols,
get = "stock.prices",
from = "2010-01-01",
to = "2025-01-01")
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"))
# Symbols
symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "JNJ" "LLY" "MRK" "PFE" "UNH"
# weights
weights <- c(0.3, 0.25, 0.20, 0.13, 0.12)
weights
## [1] 0.30 0.25 0.20 0.13 0.12
w_tbl <-tibble(symbols, weights)
w_tbl
## # A tibble: 5 Ă— 2
## symbols weights
## <chr> <dbl>
## 1 JNJ 0.3
## 2 LLY 0.25
## 3 MRK 0.2
## 4 PFE 0.13
## 5 UNH 0.12
# ?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: 179 Ă— 2
## date returns
## <date> <dbl>
## 1 2010-02-26 -0.0103
## 2 2010-03-31 0.0209
## 3 2010-04-30 -0.0379
## 4 2010-05-28 -0.0629
## 5 2010-06-30 0.00805
## 6 2010-07-30 0.0222
## 7 2010-08-31 0.00400
## 8 2010-09-30 0.0797
## 9 2010-10-29 0.00154
## 10 2010-11-30 -0.0318
## # ℹ 169 more rows
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.0675
# 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 - sd_portfolio * 2, "ext_neg", "not_ex_neg")) %>%
ggplot(aes(x = returns, fill = extreme_neg)) +
geom_histogram(binwidth = 0.003) +
scale_x_continuous(breaks = seq(-0.06, 0.06, 0.02)) +
labs(x = "monthly returns")
asset_returns_tbl %>%
ggplot(aes(x = returns)) +
geom_density(aes(color = asset), show.legend = FALSE, alpha = 1) +
geom_histogram(aes(fill = asset), show.legend = FALSE, alpha = 0.3, binwidth = 0.01) +
facet_wrap(~asset, ncol = 1) +
# Labeling
labs(title = "Distribution of Monthly Returns, 2010-2025",
y = "Frequency",
x= "Rate of Returns")
# 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: 6 Ă— 2
## asset skew
## <chr> <dbl>
## 1 JNJ -0.142
## 2 LLY 0.210
## 3 MRK -0.213
## 4 PFE 0.265
## 5 UNH -0.157
## 6 Portfolio -0.0675
# 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")