# Load packages
library(tidyquant)
library(tidyverse)
from <- today() - years(5)
stock_returns_monthly <- c("TSLA","AAPL", "NFLX") %>%
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: 180 x 3
## # Groups: symbol [3]
## symbol date Ra
## <chr> <date> <dbl>
## 1 TSLA 2016-05-31 -0.0768
## 2 TSLA 2016-06-30 -0.0491
## 3 TSLA 2016-07-29 0.106
## 4 TSLA 2016-08-31 -0.0970
## 5 TSLA 2016-09-30 -0.0376
## 6 TSLA 2016-10-31 -0.0309
## 7 TSLA 2016-11-30 -0.0421
## 8 TSLA 2016-12-30 0.128
## 9 TSLA 2017-01-31 0.179
## 10 TSLA 2017-02-28 -0.00770
## # ... with 170 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: 60 x 2
## date Rb
## <date> <dbl>
## 1 2016-05-31 0.00746
## 2 2016-06-30 0.000911
## 3 2016-07-29 0.0356
## 4 2016-08-31 -0.00122
## 5 2016-09-30 -0.00123
## 6 2016-10-31 -0.0194
## 7 2016-11-30 0.0342
## 8 2016-12-30 0.0182
## 9 2017-01-31 0.0179
## 10 2017-02-28 0.0372
## # ... with 50 more rows
stock_returns_monthly_multi <- stock_returns_monthly %>%
tq_repeat_df(n = 10)
stock_returns_monthly_multi
## # A tibble: 1,800 x 4
## # Groups: portfolio [10]
## portfolio symbol date Ra
## <int> <chr> <date> <dbl>
## 1 1 TSLA 2016-05-31 -0.0768
## 2 1 TSLA 2016-06-30 -0.0491
## 3 1 TSLA 2016-07-29 0.106
## 4 1 TSLA 2016-08-31 -0.0970
## 5 1 TSLA 2016-09-30 -0.0376
## 6 1 TSLA 2016-10-31 -0.0309
## 7 1 TSLA 2016-11-30 -0.0421
## 8 1 TSLA 2016-12-30 0.128
## 9 1 TSLA 2017-01-31 0.179
## 10 1 TSLA 2017-02-28 -0.00770
## # ... with 1,790 more rows
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("TSLA","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 TSLA 0.8
## 2 1 AMZN 0.1
## 3 1 NFLX 0.1
## 4 2 TSLA 0.1
## 5 2 AMZN 0.8
## 6 2 NFLX 0.1
## 7 3 TSLA 0.1
## 8 3 AMZN 0.1
## 9 3 NFLX 0.8
## 10 4 TSLA 0.6
## # ... with 20 more rows
portfolio_returns_monthly <-
stock_returns_monthly_multi %>%
tq_portfolio(assets_col = symbol,
returns_col = Ra,
weights = weights_table,
col_rename = "Ra")
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
## Warning in check_weights(weights, assets_col, map, x): The assets in weights
## does not match the assets in data.
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1: assuming
## a return of 0 for the residual weights
portfolio_returns_monthly
## # A tibble: 600 x 3
## # Groups: portfolio [10]
## portfolio date Ra
## <int> <date> <dbl>
## 1 1 2016-05-31 -0.0513
## 2 1 2016-06-30 -0.0507
## 3 1 2016-07-29 0.0824
## 4 1 2016-08-31 -0.0705
## 5 1 2016-09-30 -0.0278
## 6 1 2016-10-31 0.00843
## 7 1 2016-11-30 -0.0405
## 8 1 2016-12-30 0.103
## 9 1 2017-01-31 0.154
## 10 1 2017-02-28 -0.00451
## # ... with 590 more rows
RaRb_multi_portfolio <- left_join(portfolio_returns_monthly ,
baseline_returns_monthly,
by = "date")
RaRb_multi_portfolio
## # A tibble: 600 x 4
## # Groups: portfolio [10]
## portfolio date Ra Rb
## <int> <date> <dbl> <dbl>
## 1 1 2016-05-31 -0.0513 0.00746
## 2 1 2016-06-30 -0.0507 0.000911
## 3 1 2016-07-29 0.0824 0.0356
## 4 1 2016-08-31 -0.0705 -0.00122
## 5 1 2016-09-30 -0.0278 -0.00123
## 6 1 2016-10-31 0.00843 -0.0194
## 7 1 2016-11-30 -0.0405 0.0342
## 8 1 2016-12-30 0.103 0.0182
## 9 1 2017-01-31 0.154 0.0179
## 10 1 2017-02-28 -0.00451 0.0372
## # ... with 590 more rows
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 1.16
## 2 2 1.14
## 3 3 1.30
## 4 4 1.27
## 5 5 1.26
## 6 6 1.40
## 7 7 1.31
## 8 8 1.31
## 9 9 1.41
## 10 10 1.27
Hint: Use dplyr::arrange().
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 9 1.41
## 2 6 1.40
## 3 7 1.31
## 4 8 1.31
## 5 3 1.30
## 6 10 1.27
## 7 4 1.27
## 8 5 1.26
## 9 1 1.16
## 10 2 1.14
Hint: Make your argument using the calculated Sharpe
The 9th weighting scheme Tesla(0.25), Amazon(0.25), Netflix (0.50), performs the best because it has the highest ratio.
Hint: Calculate Beta from the Capital Asset Pricing Model. Make your argument based on the calculated Beta.
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.4881 0.0726 0.2735 0.4237 0.1992 0.2927 0.3870 0.2480
## Alpha 0.0298 0.0097 0.0230 0.0258 0.0156 0.0221 0.0241 0.0179
## AnnualizedAlpha 0.4232 0.1234 0.3136 0.3577 0.2041 0.2994 0.3301 0.2375
## Beta 1.7847 0.6827 0.8692 1.5768 0.9921 1.0146 1.4571 1.0958
## Beta- 1.4853 0.4632 0.7936 1.2809 0.7291 0.8503 1.1681 0.8290
## Beta+ 3.0843 1.2512 1.3755 2.7402 1.7623 1.6803 2.5348 1.9249
## Correlation 0.4883 0.5235 0.3998 0.5216 0.5375 0.4800 0.5329 0.5394
## Correlationp-value 0.0001 0.0000 0.0016 0.0000 0.0000 0.0001 0.0000 0.0000
## InformationRatio 0.9891 0.4179 0.9114 1.0667 0.8517 1.0504 1.0920 0.9632
## R-squared 0.2385 0.2741 0.1598 0.2721 0.2890 0.2304 0.2840 0.2909
## TrackingError 0.4935 0.1736 0.3001 0.3972 0.2339 0.2786 0.3544 0.2575
## TreynorRatio 0.3583 0.3280 0.4888 0.3647 0.3533 0.4377 0.3695 0.3645
## [,9] [,10]
## portfolio 9.0000 10.0000
## ActivePremium 0.3019 0.3283
## Alpha 0.0217 0.0213
## AnnualizedAlpha 0.2935 0.2875
## Beta 1.0920 1.3404
## Beta- 0.8871 1.0465
## Beta+ 1.8412 2.3688
## Correlation 0.5114 0.5318
## Correlationp-value 0.0000 0.0000
## InformationRatio 1.0937 1.0107
## R-squared 0.2616 0.2828
## TrackingError 0.2761 0.3248
## TreynorRatio 0.4151 0.3579
The most volatile scheme is the first because it has the largest gap in itβs min and max beta of 1.6.
Hint: Use message, echo and results in the chunk options. Refer to the RMarkdown Reference Guide.