# Load packages
# Core
library(tidyverse)
library(tidyquant)
Visualize expected returns and risk to make it easier to compare the performance of multiple assets and portfolios.
Choose your stocks.
from 2017-12-31 to 2022-12-31
# Choose stocks
symbols <- c("MSFT", "JPM", "GM", "TMUS", "IRVRF")
prices <- tq_get(x = symbols,
get = "stock.prices",
from = "2017-12-31",
to = "2022-12-31")
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] "GM" "IRVRF" "JPM" "MSFT" "TMUS"
# weights
weights <- c(0.25, 0.2, 0.2, 0.1, 0.25)
weights
## [1] 0.25 0.20 0.20 0.10 0.25
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 5 × 2
## symbols weights
## <chr> <dbl>
## 1 GM 0.25
## 2 IRVRF 0.2
## 3 JPM 0.2
## 4 MSFT 0.1
## 5 TMUS 0.25
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: 59 × 2
## date portfolio.returns
## <date> <dbl>
## 1 2018-02-28 0.00823
## 2 2018-03-29 -0.0253
## 3 2018-04-30 0.0341
## 4 2018-05-31 -0.00672
## 5 2018-06-29 -0.0144
## 6 2018-07-31 -0.00515
## 7 2018-08-31 0.0271
## 8 2018-09-28 -0.0164
## 9 2018-10-31 0.0523
## 10 2018-11-30 0.0644
## # … with 49 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.0683 0.0683
# Mean of Portfolio Returns
portfolio_mean_tidyquant_builtin_percent <- mean(portfolio_returns_tbl$portfolio.returns)
portfolio_mean_tidyquant_builtin_percent
## [1] 0.005300198
# Expected Returns vs Risk
sd_mean_tbl <- asset_returns_tbl %>%
group_by(asset) %>%
tq_performance(Ra = returns,
performance_fun = table.Stats) %>%
select(Mean = ArithmeticMean, Stdev) %>%
ungroup() %>%
# Add Portfolio Standard Deviation
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 GM -0.0023 0.114
## 2 IRVRF -0.0001 0.184
## 3 JPM 0.0049 0.0805
## 4 MSFT 0.0167 0.0613
## 5 TMUS 0.013 0.0651
## 6 Portfolio 0.00530 0.0683
# Graph
sd_mean_tbl %>%
ggplot(aes(x = Stdev, y = Mean, color = asset)) +
geom_point() +
ggrepel::geom_text_repel(aes(label = asset))
When examining the portfolios expected returns versus the risk, there are clear indicators that the portfolio should be expected to have a moderate return with little associated risk. Although this conclusion is drawn from comparing the portfolio to each individual asset’s performance and risk profiles, being that four out of five assets have a standard deviation below 0.13. The overall portfolio return is 0.5% monthly, which could be improved with the addition of emerging growth stocks, but this would also adversely effect the portfolios current negligible volatility. The positions in MSFT and TMUS have the highest relative monthly returns and the lowest stdev, signifying these would be the most ideal assets to invest in. The portfolio would likely benefit from adjusting the weighting, so that a larger portion is invested in TMUS and less in IRVRF. GM, IRVRF, and to an extent JPM have humble average monthly returns, but serve as good diversification in the portfolio. I believe with relative certainty that investing in alternative assets within the same industry that have lower dollar-for-dollar risk, would improve the performance of the portfolio. An investor with a higher appetite for risk would see a greater potential for returns after a rebalance, and ultimately there is plenty of leeway in the current portfolio for additional risk based on the last five years of historical data.