# Load packages
# Core
library(tidyverse)
library(tidyquant)
# Source function
source("../00_scripts/simulate_accumulation.R")
Revise the code below.
symbols <- c("SPY", "EFA", "IJS", "EEM", "AGG")
prices <- tq_get(x = symbols,
get = "stock.prices",
from = "2012-12-31",
to = "2024-12-11")
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] "AGG" "EEM" "EFA" "IJS" "SPY"
# weights
weights <- c(0.25, 0.25, 0.2, 0.2, 0.1)
weights
## [1] 0.25 0.25 0.20 0.20 0.10
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 5 Ă— 2
## symbols weights
## <chr> <dbl>
## 1 AGG 0.25
## 2 EEM 0.25
## 3 EFA 0.2
## 4 IJS 0.2
## 5 SPY 0.1
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: 144 Ă— 2
## date returns
## <date> <dbl>
## 1 2013-01-31 0.0204
## 2 2013-02-28 -0.00239
## 3 2013-03-28 0.0121
## 4 2013-04-30 0.0174
## 5 2013-05-31 -0.0128
## 6 2013-06-28 -0.0247
## 7 2013-07-31 0.0321
## 8 2013-08-30 -0.0224
## 9 2013-09-30 0.0511
## 10 2013-10-31 0.0301
## # ℹ 134 more rows
# Get mean portfolio return
mean_port_return <- mean(portfolio_returns_tbl$returns)
mean_port_return
## [1] 0.004529814
# Get standard deviation of portfolio returns
stddev_port_return <- sd(portfolio_returns_tbl$returns)
stddev_port_return
## [1] 0.03433387
No need
# Create a vector of 1s as a starting point
sims <- 100
starts <- rep(100, sims) %>%
set_names(paste0("sim", 1:sims))
starts
## sim1 sim2 sim3 sim4 sim5 sim6 sim7 sim8 sim9 sim10 sim11
## 100 100 100 100 100 100 100 100 100 100 100
## sim12 sim13 sim14 sim15 sim16 sim17 sim18 sim19 sim20 sim21 sim22
## 100 100 100 100 100 100 100 100 100 100 100
## sim23 sim24 sim25 sim26 sim27 sim28 sim29 sim30 sim31 sim32 sim33
## 100 100 100 100 100 100 100 100 100 100 100
## sim34 sim35 sim36 sim37 sim38 sim39 sim40 sim41 sim42 sim43 sim44
## 100 100 100 100 100 100 100 100 100 100 100
## sim45 sim46 sim47 sim48 sim49 sim50 sim51 sim52 sim53 sim54 sim55
## 100 100 100 100 100 100 100 100 100 100 100
## sim56 sim57 sim58 sim59 sim60 sim61 sim62 sim63 sim64 sim65 sim66
## 100 100 100 100 100 100 100 100 100 100 100
## sim67 sim68 sim69 sim70 sim71 sim72 sim73 sim74 sim75 sim76 sim77
## 100 100 100 100 100 100 100 100 100 100 100
## sim78 sim79 sim80 sim81 sim82 sim83 sim84 sim85 sim86 sim87 sim88
## 100 100 100 100 100 100 100 100 100 100 100
## sim89 sim90 sim91 sim92 sim93 sim94 sim95 sim96 sim97 sim98 sim99
## 100 100 100 100 100 100 100 100 100 100 100
## sim100
## 100
# Simulate
# For reproducable 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: 24,100 Ă— 3
## month sim growth
## <int> <chr> <dbl>
## 1 1 sim1 100
## 2 1 sim2 100
## 3 1 sim3 100
## 4 1 sim4 100
## 5 1 sim5 100
## 6 1 sim6 100
## 7 1 sim7 100
## 8 1 sim8 100
## 9 1 sim9 100
## 10 1 sim10 100
## # ℹ 24,090 more rows
# Find quantiles
monte_carlo_sim_51 %>%
group_by(sim) %>%
summarise(growth = last(growth)) %>%
ungroup() %>%
pull(growth) %>%
quantile(probs = c(0, 0.25, 0.5, 0.75, 1)) %>%
round(2)
## 0% 25% 50% 75% 100%
## 48.09 168.93 258.11 390.43 943.96
Line Plot of Simulations with Max, Median, and Min
# Step 1 Summarise data into max, median, and min of 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 944. 258. 48.1
# 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 $1 over 120 months",
subtitle = "Max, Median, and Minimum Simulation")
Based on the Monte Carlo simulation results, how much should you expect from your 100 dollar 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 the Monte Carlo simulation results you can expect anywhere from 50-900 on your investment, with 50 being the mininum value and 900 being the maximum value. For some reason similarly to the code along assignment, the graph wont display the median but we can assume it would be somewhere in between 50-900. Obviously you wouldn’t be very happy to lose 50 on your original investment but you would be very happy if you were to be on the max side of things and gain 900 dollars on your investment. There are some limitations to this simulation analysis, as it only shows you how your stock has grown over the last few years, and cannot correctly predict the future, however you can use this previous data to make an inference on whether you want to invest your money or not based on the returns on the graph.