# Load packages
library(tidyquant)
library(tidyverse)
from <- today() - years(5)
stock_returns_monthly <- c("FB", "NFLX", "AMZN") %>%
tq_get(get = "stock.prices",
from = from) %>%
group_by(symbol) %>%
tq_transmute(select = adjusted,
mutate_fun = periodReturn,
period = "monthly",
col_rename = "Ra")
stock_returns_monthly
## # A tibble: 183 x 3
## # Groups: symbol [3]
## symbol date Ra
## <chr> <date> <dbl>
## 1 FB 2015-11-30 -0.0328
## 2 FB 2015-12-31 0.00403
## 3 FB 2016-01-29 0.0721
## 4 FB 2016-02-29 -0.0471
## 5 FB 2016-03-31 0.0672
## 6 FB 2016-04-29 0.0305
## 7 FB 2016-05-31 0.0105
## 8 FB 2016-06-30 -0.0381
## 9 FB 2016-07-29 0.0845
## 10 FB 2016-08-31 0.0176
## # ... with 173 more rows
baseline_returns_monthly <- "^GSPC" %>%
tq_get(get = "stock.prices",
from = from) %>%
tq_transmute(select = adjusted,
mutate_fun = periodReturn,
period = "monthly",
col_rename = "Rb")
baseline_returns_monthly
## # A tibble: 61 x 2
## date Rb
## <date> <dbl>
## 1 2015-11-30 -0.00152
## 2 2015-12-31 -0.0175
## 3 2016-01-29 -0.0507
## 4 2016-02-29 -0.00413
## 5 2016-03-31 0.0660
## 6 2016-04-29 0.00270
## 7 2016-05-31 0.0153
## 8 2016-06-30 0.000911
## 9 2016-07-29 0.0356
## 10 2016-08-31 -0.00122
## # ... with 51 more rows
#
stock_returns_monthly_multi <- stock_returns_monthly %>%
tq_repeat_df(n = 10)
stock_returns_monthly_multi
## # A tibble: 1,830 x 4
## # Groups: portfolio [10]
## portfolio symbol date Ra
## <int> <chr> <date> <dbl>
## 1 1 FB 2015-11-30 -0.0328
## 2 1 FB 2015-12-31 0.00403
## 3 1 FB 2016-01-29 0.0721
## 4 1 FB 2016-02-29 -0.0471
## 5 1 FB 2016-03-31 0.0672
## 6 1 FB 2016-04-29 0.0305
## 7 1 FB 2016-05-31 0.0105
## 8 1 FB 2016-06-30 -0.0381
## 9 1 FB 2016-07-29 0.0845
## 10 1 FB 2016-08-31 0.0176
## # ... with 1,820 more rows
# Assign weights to individual stocks
weights <- c(
0.80, 0.10, 0.10,
0.10, 0.80, 0.10,
0.10, 0.10, 0.80,
0.60, 0.20, 0.20,
0.20, 0.60, 0.20,
0.20, 0.20, 0.60,
0.50, 0.25, 0.25,
0.25, 0.50, 0.25,
0.25, 0.25, 0.50,
0.40, 0.40, 0.20
)
stocks <- c("FB", "AMZN", "NFLX")
weights_table <- tibble(stocks) %>%
tq_repeat_df(n = 10) %>%
bind_cols(tibble(weights)) %>%
group_by(portfolio)
weights_table
## # A tibble: 30 x 3
## # Groups: portfolio [10]
## portfolio stocks weights
## <int> <chr> <dbl>
## 1 1 FB 0.8
## 2 1 AMZN 0.1
## 3 1 NFLX 0.1
## 4 2 FB 0.1
## 5 2 AMZN 0.8
## 6 2 NFLX 0.1
## 7 3 FB 0.1
## 8 3 AMZN 0.1
## 9 3 NFLX 0.8
## 10 4 FB 0.6
## # ... with 20 more rows
# Aggregate a Portfolio using Vector of Weights
portfolio_returns_monthly <-
stock_returns_monthly_multi %>%
tq_portfolio(assets_col = symbol,
returns_col = Ra,
weights = weights_table,
col_rename = "Ra")
portfolio_returns_monthly
## # A tibble: 610 x 3
## # Groups: portfolio [10]
## portfolio date Ra
## <int> <date> <dbl>
## 1 1 2015-11-30 -0.0238
## 2 1 2015-12-31 -0.00269
## 3 1 2016-01-29 0.0246
## 4 1 2016-02-29 -0.0433
## 5 1 2016-03-31 0.0700
## 6 1 2016-04-29 0.0251
## 7 1 2016-05-31 0.0278
## 8 1 2016-06-30 -0.0408
## 9 1 2016-07-29 0.0756
## 10 1 2016-08-31 0.0206
## # ... with 600 more rows
# Merging Ra and Rb
RaRb_multi_portfolio <- left_join(portfolio_returns_monthly ,
baseline_returns_monthly,
by = "date")
RaRb_multi_portfolio
## # A tibble: 610 x 4
## # Groups: portfolio [10]
## portfolio date Ra Rb
## <int> <date> <dbl> <dbl>
## 1 1 2015-11-30 -0.0238 -0.00152
## 2 1 2015-12-31 -0.00269 -0.0175
## 3 1 2016-01-29 0.0246 -0.0507
## 4 1 2016-02-29 -0.0433 -0.00413
## 5 1 2016-03-31 0.0700 0.0660
## 6 1 2016-04-29 0.0251 0.00270
## 7 1 2016-05-31 0.0278 0.0153
## 8 1 2016-06-30 -0.0408 0.000911
## 9 1 2016-07-29 0.0756 0.0356
## 10 1 2016-08-31 0.0206 -0.00122
## # ... with 600 more rows
# Sharpe Ratio
RaRb_multi_portfolio %>%
tq_performance(Ra = Ra, Rb = NULL, performance_fun = SharpeRatio.annualized, scale = 12)
## # A tibble: 10 x 2
## # Groups: portfolio [10]
## portfolio `AnnualizedSharpeRatio(Rf=0%)`
## <int> <dbl>
## 1 1 0.916
## 2 2 1.26
## 3 3 0.945
## 4 4 1.05
## 5 5 1.24
## 6 6 1.04
## 7 7 1.10
## 8 8 1.21
## 9 9 1.09
## 10 10 1.18
Hint: Use dplyr::arrange().
# Calculate Sharpe Ratio for hundreds of portfolios
RaRb_multi_portfolio %>%
tq_performance(Ra = Ra, Rb = NULL, performance_fun = SharpeRatio.annualized, scale = 12) %>%
arrange(desc(`AnnualizedSharpeRatio(Rf=0%)`))
## # A tibble: 10 x 2
## # Groups: portfolio [10]
## portfolio `AnnualizedSharpeRatio(Rf=0%)`
## <int> <dbl>
## 1 2 1.26
## 2 5 1.24
## 3 8 1.21
## 4 10 1.18
## 5 7 1.10
## 6 9 1.09
## 7 4 1.05
## 8 6 1.04
## 9 3 0.945
## 10 1 0.916
Hint: Make your argument using the calculated Sharpe
Weighting scheme #2 worked the best because the sharpe ratio is the highest.
Hint: Calculate Beta from the Capital Asset Pricing Model. Make your argument based on the calculated Beta.
# Beta and Alpha
RaRb_multi_portfolio %>%
tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.CAPM) %>%
t()
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## portfolio 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000
## ActivePremium 0.1199 0.2263 0.1938 0.1485 0.2085 0.1893 0.1619 0.1992
## Alpha 0.0089 0.0160 0.0172 0.0111 0.0150 0.0156 0.0121 0.0145
## AnnualizedAlpha 0.1116 0.2094 0.2269 0.1411 0.1955 0.2043 0.1556 0.1891
## Beta 1.1402 1.1666 0.9612 1.1029 1.1296 1.0062 1.0900 1.1099
## Beta- 0.8342 0.8820 0.7865 0.8135 0.8541 0.7856 0.8094 0.8386
## Beta+ 1.4721 1.2683 1.2967 1.3855 1.2883 1.2953 1.3536 1.2979
## Correlation 0.6732 0.6520 0.4446 0.6677 0.6541 0.5221 0.6559 0.6485
## Correlationp-value 0.0000 0.0000 0.0003 0.0000 0.0000 0.0000 0.0000 0.0000
## InformationRatio 0.6306 1.0974 0.6636 0.7980 1.0528 0.7635 0.8537 1.0098
## R-squared 0.4531 0.4251 0.1977 0.4458 0.4279 0.2726 0.4302 0.4205
## TrackingError 0.1901 0.2062 0.2921 0.1861 0.1980 0.2479 0.1897 0.1972
## TreynorRatio 0.2053 0.2918 0.3204 0.2382 0.2856 0.3016 0.2533 0.2823
## [,9] [,10]
## portfolio 9.0000 10.0000
## ActivePremium 0.1870 0.1799
## Alpha 0.0149 0.0131
## AnnualizedAlpha 0.1942 0.1685
## Beta 1.0306 1.1149
## Beta- 0.7915 0.8333
## Beta+ 1.2992 1.3318
## Correlation 0.5624 0.6721
## Correlationp-value 0.0000 0.0000
## InformationRatio 0.8178 0.9668
## R-squared 0.3163 0.4517
## TrackingError 0.2286 0.1861
## TreynorRatio 0.2922 0.2638
Scheme #4 is the most volatile because its maximum and minimum betas are have the largest difference.
Hint: Use message, echo and results in the chunk options. Refer to the RMarkdown Reference Guide.