# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Examine how each asset contributes to portfolio standard deviation. This is to ensure that our risk is not concentrated in any one asset.

1 Import stock prices

Choose your stocks from 2012-12-31 to present.

symbols <- c("TSLA", "DELL", "NVDA", "AAPL", "AMZN", "WMT")

prices <- tq_get(symbols, 
                 get = "stock.prices",
                 from = "2012-12-31")

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_wide_tbl <- asset_returns_tbl %>%
  pivot_wider(names_from = asset, values_from = returns) %>%
  column_to_rownames(var = "date")
w <- c(AAPL = 0.20, AMZN = 0.20, NVDA = 0.20, 
       TSLA = 0.20, DELL  = 0.10, WMT = 0.1)

3 Calculate Component Contribution to Portfolio Volatility

calculate_component_contribution <- function(returns_mat, weights) {
  cov_mat <- cov(returns_mat)
  port_sd <- as.numeric(sqrt(t(weights) %*% cov_mat %*% weights))
  
  marginal <- cov_mat %*% weights / port_sd         
  component <- weights * marginal                     
  contrib_pct <- component / port_sd * 100            
  
  tibble(
    Asset        = names(weights),
    Weight       = weights * 100,
    Contribution = round(contrib_pct, 1)
  ) %>% 
    arrange(desc(Contribution))
}
contributions <- asset_returns_wide_tbl %>%
  calculate_component_contribution(w)

contributions
## # A tibble: 6 × 3
##   Asset Weight Contribution[,1]
##   <chr>  <dbl>            <dbl>
## 1 AAPL      20               NA
## 2 AMZN      20               NA
## 3 NVDA      20               NA
## 4 TSLA      20               NA
## 5 DELL      10               NA
## 6 WMT       10               NA

6 Plot: Colum Chart of Component Contribution and Weight

contributions %>%
  pivot_longer(cols = c(Weight, Contribution), 
               names_to = "Type", values_to = "Value") %>%
  ggplot(aes(x = Asset, y = Value, fill = Type)) +
  geom_col(position = "dodge") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("Weight" = "#2c3e50", "Contribution" = "#e74c3c")) +
  labs(title = "Portfolio Weight vs Component Contribution to Risk",
       y = "Percentage", x = NULL) +
  theme_tq()

Which of the assets in your portfolio the largest contributor to the portfolio volatility? Do you think your portfolio risk is concentrated in any one asset?

NVDA carries the most risk by far in this portfolio and contributes to the most volatility within it.