# Load packages
# Core
library(tidyverse)
library(tidyquant)
Visualize and compare skewness of your portfolio and its assets.
Choose your stocks.
from 2012-12-31 to 2017-12-31
symbols <- c("JPM", "MS", "DNB.OL", "NDA-FI.HE")
prices <- tq_get(x = symbols,
get = "stock.prices",
from = "2017-01-01",
to = "2023-12-31") %>%
filter(!is.na(close))
asset_returns_tbl <-prices %>%
group_by(symbol) %>%
tq_transmute(select = adjusted,
mutate_fun = periodReturn,
period = "quarterly",
type = "log") %>%
ungroup() %>%
set_names(c("asset", "date", "returns"))
asset_returns_tbl
## # A tibble: 112 × 3
## asset date returns
## <chr> <date> <dbl>
## 1 JPM 2017-03-31 0.0125
## 2 JPM 2017-06-30 0.0455
## 3 JPM 2017-09-29 0.0495
## 4 JPM 2017-12-29 0.119
## 5 JPM 2018-03-29 0.0331
## 6 JPM 2018-06-29 -0.0488
## 7 JPM 2018-09-28 0.0851
## 8 JPM 2018-12-31 -0.138
## 9 JPM 2019-03-29 0.0444
## 10 JPM 2019-06-28 0.107
## # ℹ 102 more rows
#symbols
symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "JPM" "MS" "DNB.OL" "NDA-FI.HE"
#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 JPM 0.25
## 2 MS 0.25
## 3 DNB.OL 0.25
## 4 NDA-FI.HE 0.25
# ?tq_portfolio
portfolio_returns_tbl <- asset_returns_tbl %>%
tq_portfolio(assets_col = asset,
returns_col = returns,
weights = w_tbl,
rebalance_on = "months")
portfolio_returns_tbl
## # A tibble: 33 × 2
## date portfolio.returns
## <date> <dbl>
## 1 2017-03-31 0.0324
## 2 2017-06-30 0.0531
## 3 2017-09-29 0.0704
## 4 2017-12-29 0.00773
## 5 2018-03-28 0.0000821
## 6 2018-03-29 -0.00540
## 7 2018-06-29 -0.0306
## 8 2018-09-28 0.0706
## 9 2018-12-28 -0.119
## 10 2018-12-31 -0.0829
## # ℹ 23 more rows
portfolio_returns_tbl %>%
tq_performance(Ra = portfolio.returns,
Rb = NULL,
performance_fun = table.Stats) %>%
select(Skewness)
## # A tibble: 1 × 1
## Skewness
## <dbl>
## 1 -1.82
# Calculate skewness for each asset and add the portfolio skewness
asset_returns_skew_tbl <- asset_returns_tbl %>%
group_by(asset) %>%
summarise(skew = skewness(returns, na.rm = TRUE)) %>%
ungroup() %>%
add_row(
asset = "Portfolio",
skew = skewness(pull(portfolio_returns_tbl, portfolio.returns), na.rm = TRUE)
)
# Plot the skewness
asset_returns_skew_tbl %>%
ggplot(aes(x = asset, y = skew, color = asset)) +
geom_point(size = 3) +
ggrepel::geom_text_repel(
aes(label = asset),
data = asset_returns_skew_tbl %>% filter(asset == "Portfolio"),
size = 5
) +
labs(title = "Asset and Portfolio Skewness",
x = "Asset",
y = "Skewness") +
theme(legend.position = "none")
The skewness plot shows that MS is the only asset with positive skewness, indicating a higher likelihood of extreme positive returns compared to both the other assets and the portfolio. In contrast, the portfolio has the most negative skewness (around -1.5), suggesting it is more prone to extreme negative returns than any individual asset. This implies that while diversification may have reduced the chance of significant positive outcomes, it has also potentially increased exposure to extreme negative events.
Overall, the distribution of returns suggests that MS offers the greatest potential for outlier positive performance. Meanwhile, assets like JPM, DNB.OL, and NDA-FI.HE exhibit negative skewness but are less negatively skewed than the portfolio, indicating that the portfolio collectively faces a higher downside risk than these individual holdings