# Load packages
# Core
library(tidyverse)
library(tidyquant)
Collect individual returns into a portfolio by assigning a weight to each stock
Choose your stocks.
from 2021-01-21 to 2025-01-21
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")
portfolio_returns_tbl
## # A tibble: 179 Ă— 2
## date portfolio.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_sd_tidyquant_builtin_percent <- portfolio_returns_tbl %>%
tq_performance(Ra = portfolio.returns,
performance_fun = table.Stats) %>%
select(Stdev) %>%
mutate(tq_sd = round(Stdev, 4))
portfolio_sd_tidyquant_builtin_percent
## # A tibble: 1 Ă— 2
## Stdev tq_sd
## <dbl> <dbl>
## 1 0.0379 0.0379
# Mean of portfolio returns
portfolio_mean_tidyquant_builtin_percent <- mean(portfolio_returns_tbl$portfolio.returns)
portfolio_mean_tidyquant_builtin_percent
## [1] 0.01140527
sd_mean_tbl <- asset_returns_tbl %>%
group_by(asset) %>%
tq_performance(Ra = returns,
performance_fun = table.Stats) %>%
select(Mean = ArithmeticMean, Stdev) %>%
ungroup() %>%
# Add portfolio sd
add_row(tibble(asset = "Portfolio"),
Mean = portfolio_mean_tidyquant_builtin_percent,
Stdev = portfolio_sd_tidyquant_builtin_percent$tq_sd)
sd_mean_tbl
## # A tibble: 6 Ă— 3
## asset Mean Stdev
## <chr> <dbl> <dbl>
## 1 JNJ 0.0071 0.0431
## 2 LLY 0.0196 0.0624
## 3 MRK 0.0084 0.0522
## 4 PFE 0.0055 0.0592
## 5 UNH 0.0165 0.0562
## 6 Portfolio 0.0114 0.0379
sd_mean_tbl %>%
ggplot(aes(x = Stdev, y = Mean, colour = asset)) +
geom_point() +
ggrepel::geom_text_repel(aes(label = asset))
rolling_sd_tbl <- portfolio_returns_tbl %>%
tq_mutate(select = portfolio.returns,
mutate_fun = rollapply,
width = 24,
FUN = sd,
col_rename = "rolling_sd") %>%
na.omit() %>%
select(-portfolio.returns)
rolling_sd_tbl
## # A tibble: 156 Ă— 2
## date rolling_sd
## <date> <dbl>
## 1 2012-01-31 0.0341
## 2 2012-02-29 0.0339
## 3 2012-03-30 0.0341
## 4 2012-04-30 0.0326
## 5 2012-05-31 0.0296
## 6 2012-06-29 0.0319
## 7 2012-07-31 0.0319
## 8 2012-08-31 0.0319
## 9 2012-09-28 0.0293
## 10 2012-10-31 0.0292
## # ℹ 146 more rows
rolling_sd_tbl %>%
ggplot(aes(x = date, y = rolling_sd)) +
geom_line(color = "cornflowerblue") +
# Formatting
scale_y_continuous(labels = scales:: percent_format())+
# Labeling
labs(x = NULL,
y = NULL,
title = "24-Month Rolling Volatility") +
theme(plot.title = element_text(hjust = 0.5))