# Load packages
# Core
library(tidyverse)
library(tidyquant)
library(quantmod)
library(TTR)
# Source function
source("../00_scripts/simulate_accumulation.R")
Revise the code below.
symbols <- c("AVGO", "SBUX", "GE", "MSFT", "PG")
prices <- tq_get(x = symbols,
get = "stock.prices",
from = "2012-12-31",
to = "2022-12-08")
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"))
Revise the code for weights.
# symbols
symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "AVGO" "GE" "MSFT" "PG" "SBUX"
# weights
weights <- c(0.2, 0.2, 0.2, 0.2, 0.2)
weights
## [1] 0.2 0.2 0.2 0.2 0.2
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 5 × 2
## symbols weights
## <chr> <dbl>
## 1 AVGO 0.2
## 2 GE 0.2
## 3 MSFT 0.2
## 4 PG 0.2
## 5 SBUX 0.2
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: 120 × 2
## date returns
## <date> <dbl>
## 1 2013-01-31 0.0729
## 2 2013-02-28 0.00409
## 3 2013-03-28 0.0254
## 4 2013-04-30 0.0124
## 5 2013-05-31 0.0623
## 6 2013-06-28 0.00567
## 7 2013-07-31 0.0167
## 8 2013-08-30 0.00265
## 9 2013-09-30 0.0423
## 10 2013-10-31 0.0661
## # … with 110 more rows
# Get mean portfolio return
mean_port_return <- mean(portfolio_returns_tbl$returns)
mean_port_return
## [1] 0.01272009
# Get standard deviation of portfolio returns
stddev_port_return <- sd(portfolio_returns_tbl$returns)
stddev_port_return
## [1] 0.04594607
** No Need **
sims <- 51
starts <- rep(100, sims) %>%
set_names(paste0("sims", 1:sims))
starts
## sims1 sims2 sims3 sims4 sims5 sims6 sims7 sims8 sims9 sims10 sims11
## 100 100 100 100 100 100 100 100 100 100 100
## sims12 sims13 sims14 sims15 sims16 sims17 sims18 sims19 sims20 sims21 sims22
## 100 100 100 100 100 100 100 100 100 100 100
## sims23 sims24 sims25 sims26 sims27 sims28 sims29 sims30 sims31 sims32 sims33
## 100 100 100 100 100 100 100 100 100 100 100
## sims34 sims35 sims36 sims37 sims38 sims39 sims40 sims41 sims42 sims43 sims44
## 100 100 100 100 100 100 100 100 100 100 100
## sims45 sims46 sims47 sims48 sims49 sims50 sims51
## 100 100 100 100 100 100 100
# Simulate
# For reproducible research
set.seed(1234)
monte_carlo_sim_51 <- starts %>%
# Simulate
map_dfc(.x = .,
.f = ~simulate_accumulation(initial_value = .x,
N = 240,
mean_return = mean_port_return,
sd_return = stddev_port_return)) %>%
# Add column month
mutate(month = 1:nrow(.)) %>%
select(month, everything()) %>%
# Rearrange column names
set_names(c("month", names(starts))) %>%
# Transform to long form
pivot_longer(cols = -month, names_to = "sim", values_to = "growth")
monte_carlo_sim_51
## # A tibble: 12,291 × 3
## month sim growth
## <int> <chr> <dbl>
## 1 1 sims1 100
## 2 1 sims2 100
## 3 1 sims3 100
## 4 1 sims4 100
## 5 1 sims5 100
## 6 1 sims6 100
## 7 1 sims7 100
## 8 1 sims8 100
## 9 1 sims9 100
## 10 1 sims10 100
## # … with 12,281 more rows
# Find Quantiles
monte_carlo_sim_51 %>%
group_by(sim) %>%
summarise(growth = last(growth)) %>%
ungroup() %>%
pull(growth) %>%
quantile(Probs = c(0, .25, .5, .75, 1)) %>%
round(2)
## 0% 25% 50% 75% 100%
## 372.37 1223.77 1965.38 3054.13 5754.96
Line Plot of Simulations with Max, Median, and Min
New Line plot with max, median, and minimum
# Step 1: Summarize data into max, median, and min of the last value
sim_summary <- monte_carlo_sim_51 %>%
group_by(sim) %>%
summarise(growth = last(growth)) %>%
ungroup() %>%
summarise(max = max(growth),
median = median(growth),
min = min(growth))
sim_summary
## # A tibble: 1 × 3
## max median min
## <dbl> <dbl> <dbl>
## 1 5755. 1965. 372.
# Step 2 Plot
monte_carlo_sim_51 %>%
# Filter for max, median, and min sim
group_by(sim) %>%
filter(last(growth) == sim_summary$max |
last(growth) == sim_summary$median |
last(growth) == sim_summary$min) %>%
ungroup() %>%
# Plot
ggplot(aes(x = month, y = growth, color = sim)) +
geom_line() +
theme(legend.position = "none") +
theme(plot.title = element_text(hjust = 0.5)) +
theme(plot.subtitle = element_text(hjust = 0.5)) +
labs(title = "Simulating growth of $100 over 240 months",
subtitle = "Maximum, Median, and Minimum Simulation")
Based on the Monte Carlo simulation results, how much should you expect from your $100 investment after 20 years? What is the best-case scenario? What is the worst-case scenario? What are limitations of this simulation analysis?
Based on this analysis I should be able to expect around a $2,000 return after 20 years. This is the Median price for the portfolio. $5,755 is the most that I could expect, and $372 is the least I could expect. The main limitation to this simulation is that it is going based on historical data of price variance. The returns might end up being affected by future macroeconomic events that the stocks have never seen before. There is definitely uncertainty within the price estimations, however it does give the investor an insight about what they are looking at potentially making.