##Midterm Exam
#import data
#load libraries
library(tidyquant)
## Loading required package: lubridate
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
## Loading required package: PerformanceAnalytics
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
## Loading required package: quantmod
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## ══ Need to Learn tidyquant? ══════════════════════════════════════════════════════════════════════════════════════
## Business Science offers a 1-hour course - Learning Lab #9: Performance Analysis & Portfolio Optimization with tidyquant!
## </> Learn more at: https://university.business-science.io/p/learning-labs-pro </>
library(lubridate)
library(timetk)
library(purrr)
library(quantmod)
Data <- function(x) (getSymbols(x, src = "yahoo", from = "2010-01-04",
to = "2021-04-14",
auto.assign = FALSE))
tickers <- c("SPY","QQQ", "EEM", "IWM","EFA", "TLT", "IYR", "GLD")
getSymbols(tickers, from = "2010-01-01", to = "2021-04-15")
## 'getSymbols' currently uses auto.assign=TRUE by default, but will
## use auto.assign=FALSE in 0.5-0. You will still be able to use
## 'loadSymbols' to automatically load data. getOption("getSymbols.env")
## and getOption("getSymbols.auto.assign") will still be checked for
## alternate defaults.
##
## This message is shown once per session and may be disabled by setting
## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
## pausing 1 second between requests for more than 5 symbols
## pausing 1 second between requests for more than 5 symbols
## pausing 1 second between requests for more than 5 symbols
## pausing 1 second between requests for more than 5 symbols
## [1] "SPY" "QQQ" "EEM" "IWM" "EFA" "TLT" "IYR" "GLD"
prices_adj <- map(tickers, Data) %>% map(Ad) %>% reduce(merge.xts)
names(prices_adj) <- tickers
head(names(prices_adj))
## [1] "SPY" "QQQ" "EEM" "IWM" "EFA" "TLT"
head(prices_adj)
## SPY QQQ EEM IWM EFA TLT IYR
## 2010-01-04 90.79006 41.51847 34.10928 54.61730 41.03314 66.13428 30.41554
## 2010-01-05 91.03041 41.51847 34.35684 54.42949 41.06930 66.56142 30.48858
## 2010-01-06 91.09449 41.26806 34.42872 54.37827 41.24289 65.67038 30.47530
## 2010-01-07 91.47905 41.29489 34.22906 54.77949 41.08377 65.78078 30.74751
## 2010-01-08 91.78343 41.63475 34.50059 55.07827 41.40926 65.75137 30.54169
## 2010-01-11 91.91164 41.46482 34.42872 54.85632 41.74921 65.39054 30.68776
## GLD
## 2010-01-04 109.80
## 2010-01-05 109.70
## 2010-01-06 111.51
## 2010-01-07 110.82
## 2010-01-08 111.37
## 2010-01-11 112.85
#Calculate weekly and monthly returns using log returns
prices_weekly <- to.weekly(prices_adj,
indexAt = "lastof",
OHLC = FALSE)
head(prices_weekly)
## SPY QQQ EEM IWM EFA TLT IYR
## 2010-01-08 91.78343 41.63475 34.50059 55.07827 41.40926 65.75137 30.54169
## 2010-01-15 91.03842 41.00866 33.50232 54.36120 41.26460 67.06946 30.34914
## 2010-01-22 87.48950 39.49712 31.63353 52.69655 38.96448 67.74699 29.08100
## 2010-01-29 86.03146 38.27178 30.57135 51.31363 37.95908 67.97523 28.83534
## 2010-02-05 85.44667 38.44172 29.70885 50.59654 37.23578 67.97155 28.92829
## 2010-02-12 86.55216 39.13937 30.69913 52.09046 37.43107 66.64877 28.70919
## GLD
## 2010-01-08 111.37
## 2010-01-15 110.86
## 2010-01-22 107.17
## 2010-01-29 105.96
## 2010-02-05 104.68
## 2010-02-12 107.04
returns_weekly <- Return.calculate(prices_weekly,
method = "log") %>% na.omit()
str(returns_weekly)
## An 'xts' object on 2010-01-15/2021-04-13 containing:
## Data: num [1:588, 1:8] -0.00815 -0.03976 -0.01681 -0.00682 0.01285 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:8] "SPY" "QQQ" "EEM" "IWM" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 5
## $ src : chr "yahoo"
## $ updated : POSIXct[1:1], format: "2021-04-16 12:49:30"
## $ ret_type : chr "log"
## $ coredata_content: chr "logReturn"
## $ na.action : 'omit' int 1
## ..- attr(*, "index")= num 1.26e+09
head(returns_weekly)
## SPY QQQ EEM IWM EFA
## 2010-01-15 -0.008150165 -0.015151916 -0.02936168 -0.01310462 -0.003499562
## 2010-01-22 -0.039762828 -0.037555380 -0.05739709 -0.03110062 -0.057354555
## 2010-01-29 -0.016805812 -0.031515101 -0.03415421 -0.02659356 -0.026141568
## 2010-02-05 -0.006820546 0.004430648 -0.02861835 -0.01407321 -0.019238635
## 2010-02-12 0.012854811 0.017985357 0.03278946 0.02909861 0.005230847
## 2010-02-19 0.028289444 0.024157168 0.02415967 0.03288489 0.022734954
## TLT IYR GLD
## 2010-01-15 0.0198483225 -0.006324356 -0.004589865
## 2010-01-22 0.0100512027 -0.042683345 -0.033851813
## 2010-01-29 0.0033633583 -0.008483115 -0.011354685
## 2010-02-05 -0.0000540947 0.003218256 -0.012153577
## 2010-02-12 -0.0196525984 -0.007602937 0.022294528
## 2010-02-19 -0.0082390553 0.048966490 0.022447943
prices_monthly <- to.monthly(prices_adj,
indexAt = "lastof",
OHLC = FALSE)
head(prices_monthly)
## SPY QQQ EEM IWM EFA TLT IYR
## 2010-01-31 86.03146 38.27178 30.57135 51.31363 37.95908 67.97523 28.83534
## 2010-02-28 88.71517 40.03376 31.11442 53.60998 38.06035 67.74242 30.40889
## 2010-03-31 94.11614 43.12074 33.63808 58.02244 40.49066 66.34879 33.37330
## 2010-04-30 95.57211 44.08773 33.58218 61.31721 39.35506 68.55278 35.50523
## 2010-05-31 87.97849 40.82861 30.42761 56.69596 34.95013 72.05472 33.48727
## 2010-06-30 83.42641 38.38882 30.00203 52.30577 34.22948 76.23226 31.92338
## GLD
## 2010-01-31 105.96
## 2010-02-28 109.43
## 2010-03-31 108.95
## 2010-04-30 115.36
## 2010-05-31 118.88
## 2010-06-30 121.68
returns_monthly <- Return.calculate(prices_monthly,
method = "log") %>% na.omit()
str(returns_monthly)
## An 'xts' object on 2010-02-28/2021-04-30 containing:
## Data: num [1:135, 1:8] 0.0307 0.0591 0.0154 -0.0828 -0.0531 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:8] "SPY" "QQQ" "EEM" "IWM" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 5
## $ src : chr "yahoo"
## $ updated : POSIXct[1:1], format: "2021-04-16 12:49:30"
## $ ret_type : chr "log"
## $ coredata_content: chr "logReturn"
## $ na.action : 'omit' int 1
## ..- attr(*, "index")= num 1.26e+09
head(returns_monthly)
## SPY QQQ EEM IWM EFA
## 2010-02-28 0.03071793 0.04501044 0.01760802 0.04377882 0.002664268
## 2010-03-31 0.05909865 0.07428087 0.07798729 0.07909466 0.061898269
## 2010-04-30 0.01535150 0.02217754 -0.00166310 0.05523070 -0.028446722
## 2010-05-31 -0.08278878 -0.07679864 -0.09864508 -0.07835767 -0.118702355
## 2010-06-30 -0.05312741 -0.06161677 -0.01408547 -0.08059619 -0.020834896
## 2010-07-31 0.06606917 0.07006933 0.10375152 0.06514060 0.109844203
## TLT IYR GLD
## 2010-02-28 -0.003430817 0.05313334 0.032223420
## 2010-03-31 -0.020787064 0.09302102 -0.004396042
## 2010-04-30 0.032678511 0.06192375 0.057168648
## 2010-05-31 0.049821843 -0.05851441 0.030056874
## 2010-06-30 0.056358956 -0.04782683 0.023280092
## 2010-07-31 -0.009508418 0.08988455 -0.052210719
#Convert monthly returns into tibble format
library(tibble)
data(returns_monthly)
## Warning in data(returns_monthly): data set 'returns_monthly' not found
class(returns_monthly)
## [1] "xts" "zoo"
head(returns_monthly, 6)
## SPY QQQ EEM IWM EFA
## 2010-02-28 0.03071793 0.04501044 0.01760802 0.04377882 0.002664268
## 2010-03-31 0.05909865 0.07428087 0.07798729 0.07909466 0.061898269
## 2010-04-30 0.01535150 0.02217754 -0.00166310 0.05523070 -0.028446722
## 2010-05-31 -0.08278878 -0.07679864 -0.09864508 -0.07835767 -0.118702355
## 2010-06-30 -0.05312741 -0.06161677 -0.01408547 -0.08059619 -0.020834896
## 2010-07-31 0.06606917 0.07006933 0.10375152 0.06514060 0.109844203
## TLT IYR GLD
## 2010-02-28 -0.003430817 0.05313334 0.032223420
## 2010-03-31 -0.020787064 0.09302102 -0.004396042
## 2010-04-30 0.032678511 0.06192375 0.057168648
## 2010-05-31 0.049821843 -0.05851441 0.030056874
## 2010-06-30 0.056358956 -0.04782683 0.023280092
## 2010-07-31 -0.009508418 0.08988455 -0.052210719
my_data <- as_tibble(returns_monthly)
class(my_data)
## [1] "tbl_df" "tbl" "data.frame"
my_data
## # A tibble: 135 x 8
## SPY QQQ EEM IWM EFA TLT IYR GLD
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.0307 0.0450 0.0176 0.0438 0.00266 -0.00343 0.0531 0.0322
## 2 0.0591 0.0743 0.0780 0.0791 0.0619 -0.0208 0.0930 -0.00440
## 3 0.0154 0.0222 -0.00166 0.0552 -0.0284 0.0327 0.0619 0.0572
## 4 -0.0828 -0.0768 -0.0986 -0.0784 -0.119 0.0498 -0.0585 0.0301
## 5 -0.0531 -0.0616 -0.0141 -0.0806 -0.0208 0.0564 -0.0478 0.0233
## 6 0.0661 0.0701 0.104 0.0651 0.110 -0.00951 0.0899 -0.0522
## 7 -0.0460 -0.0527 -0.0329 -0.0774 -0.0387 0.0806 -0.0131 0.0555
## 8 0.0858 0.124 0.111 0.117 0.0951 -0.0255 0.0453 0.0467
## 9 0.0375 0.0615 0.0297 0.0406 0.0373 -0.0457 0.0386 0.0362
## 10 0 -0.00173 -0.0295 0.0343 -0.0494 -0.0170 -0.0160 0.0209
## # … with 125 more rows
str(my_data)
## tibble [135 × 8] (S3: tbl_df/tbl/data.frame)
## $ SPY: num [1:135] 0.0307 0.0591 0.0154 -0.0828 -0.0531 ...
## $ QQQ: num [1:135] 0.045 0.0743 0.0222 -0.0768 -0.0616 ...
## $ EEM: num [1:135] 0.01761 0.07799 -0.00166 -0.09865 -0.01409 ...
## $ IWM: num [1:135] 0.0438 0.0791 0.0552 -0.0784 -0.0806 ...
## $ EFA: num [1:135] 0.00266 0.0619 -0.02845 -0.1187 -0.02083 ...
## $ TLT: num [1:135] -0.00343 -0.02079 0.03268 0.04982 0.05636 ...
## $ IYR: num [1:135] 0.0531 0.093 0.0619 -0.0585 -0.0478 ...
## $ GLD: num [1:135] 0.0322 -0.0044 0.0572 0.0301 0.0233 ...
#Download Fama French 3 factors data and change to digit numbers (not in percetage)
library(readr)
library(xts)
library(magrittr)
##
## Attaching package: 'magrittr'
## The following object is masked from 'package:purrr':
##
## set_names
library(PerformanceAnalytics)
ff3.csv <- read.csv('ff3.csv')
str(ff3.csv)
## 'data.frame': 1136 obs. of 5 variables:
## $ Date : int 192607 192608 192609 192610 192611 192612 192701 192702 192703 192704 ...
## $ Mkt.RF: num 2.96 2.64 0.36 -3.24 2.53 2.62 -0.06 4.18 0.13 0.46 ...
## $ SMB : num -2.3 -1.4 -1.32 0.04 -0.2 -0.04 -0.56 -0.1 -1.6 0.43 ...
## $ HML : num -2.87 4.19 0.01 0.51 -0.35 -0.02 4.83 3.17 -2.67 0.6 ...
## $ RF : num 0.22 0.25 0.23 0.32 0.31 0.28 0.25 0.26 0.3 0.25 ...
head(ff3.csv)
## Date Mkt.RF SMB HML RF
## 1 192607 2.96 -2.30 -2.87 0.22
## 2 192608 2.64 -1.40 4.19 0.25
## 3 192609 0.36 -1.32 0.01 0.23
## 4 192610 -3.24 0.04 0.51 0.32
## 5 192611 2.53 -0.20 -0.35 0.31
## 6 192612 2.62 -0.04 -0.02 0.28
dim(ff3.csv)
## [1] 1136 5
tail(ff3.csv)
## Date Mkt.RF SMB HML RF
## 1131 202009 -3.63 0.06 -2.51 0.01
## 1132 202010 -2.10 4.44 4.03 0.01
## 1133 202011 12.47 5.48 2.11 0.01
## 1134 202012 4.63 4.81 -1.36 0.01
## 1135 202101 -0.04 7.19 2.85 0.00
## 1136 202102 2.79 2.11 7.07 0.00
glimpse(ff3.csv)
## Rows: 1,136
## Columns: 5
## $ Date <int> 192607, 192608, 192609, 192610, 192611, 192612, 192701, 192702,…
## $ Mkt.RF <dbl> 2.96, 2.64, 0.36, -3.24, 2.53, 2.62, -0.06, 4.18, 0.13, 0.46, 5…
## $ SMB <dbl> -2.30, -1.40, -1.32, 0.04, -0.20, -0.04, -0.56, -0.10, -1.60, 0…
## $ HML <dbl> -2.87, 4.19, 0.01, 0.51, -0.35, -0.02, 4.83, 3.17, -2.67, 0.60,…
## $ RF <dbl> 0.22, 0.25, 0.23, 0.32, 0.31, 0.28, 0.25, 0.26, 0.30, 0.25, 0.3…
ff3.csv[c(1110:1123),]
## Date Mkt.RF SMB HML RF
## 1110 201812 -9.55 -2.48 -1.89 0.19
## 1111 201901 8.41 2.89 -0.46 0.21
## 1112 201902 3.40 2.12 -2.71 0.18
## 1113 201903 1.10 -3.05 -4.19 0.19
## 1114 201904 3.96 -1.75 2.02 0.21
## 1115 201905 -6.94 -1.18 -2.28 0.21
## 1116 201906 6.93 0.22 -0.79 0.18
## 1117 201907 1.19 -2.08 0.34 0.19
## 1118 201908 -2.58 -2.40 -4.85 0.16
## 1119 201909 1.43 -1.05 6.77 0.18
## 1120 201910 2.06 0.24 -1.88 0.15
## 1121 201911 3.87 0.91 -2.05 0.12
## 1122 201912 2.77 0.67 1.91 0.14
## 1123 202001 -0.11 -3.08 -6.27 0.13
colnames(ff3.csv)[2] <- "MKT_RF" #Replace "Mkt-RF" with MKT_RF";
FAMA <- ff3.csv
head(FAMA)
## Date MKT_RF SMB HML RF
## 1 192607 2.96 -2.30 -2.87 0.22
## 2 192608 2.64 -1.40 4.19 0.25
## 3 192609 0.36 -1.32 0.01 0.23
## 4 192610 -3.24 0.04 0.51 0.32
## 5 192611 2.53 -0.20 -0.35 0.31
## 6 192612 2.62 -0.04 -0.02 0.28
str(FAMA)
## 'data.frame': 1136 obs. of 5 variables:
## $ Date : int 192607 192608 192609 192610 192611 192612 192701 192702 192703 192704 ...
## $ MKT_RF: num 2.96 2.64 0.36 -3.24 2.53 2.62 -0.06 4.18 0.13 0.46 ...
## $ SMB : num -2.3 -1.4 -1.32 0.04 -0.2 -0.04 -0.56 -0.1 -1.6 0.43 ...
## $ HML : num -2.87 4.19 0.01 0.51 -0.35 -0.02 4.83 3.17 -2.67 0.6 ...
## $ RF : num 0.22 0.25 0.23 0.32 0.31 0.28 0.25 0.26 0.3 0.25 ...
FAMA$MKT_RF <- FAMA[2]/100
FAMA$SMB <- FAMA[3]/100
FAMA$HML <- FAMA[4]/100
head(FAMA)
## Date MKT_RF SMB HML RF
## 1 192607 0.0296 -0.0230 -0.0287 0.22
## 2 192608 0.0264 -0.0140 0.0419 0.25
## 3 192609 0.0036 -0.0132 0.0001 0.23
## 4 192610 -0.0324 0.0004 0.0051 0.32
## 5 192611 0.0253 -0.0020 -0.0035 0.31
## 6 192612 0.0262 -0.0004 -0.0002 0.28
#Convert into xts
FF3.xts <- xts(FAMA[,-1], order.by = as.POSIXct.Date(FAMA$Date))
head(FF3.xts)
## MKT_RF SMB HML RF
## 2497-05-04 0.0296 -0.0230 -0.0287 0.22
## 2497-05-05 0.0264 -0.0140 0.0419 0.25
## 2497-05-06 0.0036 -0.0132 0.0001 0.23
## 2497-05-07 -0.0324 0.0004 0.0051 0.32
## 2497-05-08 0.0253 -0.0020 -0.0035 0.31
## 2497-05-09 0.0262 -0.0004 -0.0002 0.28
str(FF3.xts)
## An 'xts' object on 2497-05-04/2523-05-04 containing:
## Data: num [1:1136, 1:4] 0.0296 0.0264 0.0036 -0.0324 0.0253 0.0262 -0.0006 0.0418 0.0013 0.0046 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:4] "MKT_RF" "SMB" "HML" "RF"
## Indexed by objects of class: [POSIXct,POSIXt] TZ: Etc/UTC
## xts Attributes:
## NULL
#convert to monthly in Tibble Format
FFFT <- as_tibble(FF3.xts)
head(FFFT)
## # A tibble: 6 x 4
## MKT_RF SMB HML RF
## <dbl> <dbl> <dbl> <dbl>
## 1 0.0296 -0.023 -0.0287 0.22
## 2 0.0264 -0.014 0.0419 0.25
## 3 0.0036 -0.0132 0.0001 0.23
## 4 -0.0324 0.0004 0.0051 0.32
## 5 0.0253 -0.002 -0.0035 0.31
## 6 0.0262 -0.0004 -0.0002 0.28
#Merge monthly return data in question 3 and 4 into tibble format.
MERGE <- merge(my_data, FF3.xts) %>% na.omit
head(MERGE)
## SPY QQQ EEM IWM EFA TLT
## 1 0.03071793 0.04501044 0.01760802 0.04377882 0.002664268 -0.003430817
## 2 0.05909865 0.07428087 0.07798729 0.07909466 0.061898269 -0.020787064
## 3 0.01535150 0.02217754 -0.00166310 0.05523070 -0.028446722 0.032678511
## 4 -0.08278878 -0.07679864 -0.09864508 -0.07835767 -0.118702355 0.049821843
## 5 -0.05312741 -0.06161677 -0.01408547 -0.08059619 -0.020834896 0.056358956
## 6 0.06606917 0.07006933 0.10375152 0.06514060 0.109844203 -0.009508418
## IYR GLD MKT_RF SMB HML RF
## 1 0.05313334 0.032223420 0.0296 -0.023 -0.0287 0.22
## 2 0.09302102 -0.004396042 0.0296 -0.023 -0.0287 0.22
## 3 0.06192375 0.057168648 0.0296 -0.023 -0.0287 0.22
## 4 -0.05851441 0.030056874 0.0296 -0.023 -0.0287 0.22
## 5 -0.04782683 0.023280092 0.0296 -0.023 -0.0287 0.22
## 6 0.08988455 -0.052210719 0.0296 -0.023 -0.0287 0.22
my_data.FF3 <- MERGE
head(my_data.FF3)
## SPY QQQ EEM IWM EFA TLT
## 1 0.03071793 0.04501044 0.01760802 0.04377882 0.002664268 -0.003430817
## 2 0.05909865 0.07428087 0.07798729 0.07909466 0.061898269 -0.020787064
## 3 0.01535150 0.02217754 -0.00166310 0.05523070 -0.028446722 0.032678511
## 4 -0.08278878 -0.07679864 -0.09864508 -0.07835767 -0.118702355 0.049821843
## 5 -0.05312741 -0.06161677 -0.01408547 -0.08059619 -0.020834896 0.056358956
## 6 0.06606917 0.07006933 0.10375152 0.06514060 0.109844203 -0.009508418
## IYR GLD MKT_RF SMB HML RF
## 1 0.05313334 0.032223420 0.0296 -0.023 -0.0287 0.22
## 2 0.09302102 -0.004396042 0.0296 -0.023 -0.0287 0.22
## 3 0.06192375 0.057168648 0.0296 -0.023 -0.0287 0.22
## 4 -0.05851441 0.030056874 0.0296 -0.023 -0.0287 0.22
## 5 -0.04782683 0.023280092 0.0296 -0.023 -0.0287 0.22
## 6 0.08988455 -0.052210719 0.0296 -0.023 -0.0287 0.22
#Based on CAPM model, compute MVP monthly returns based on estimated covariance matrix
#for the 8-asset portfolio by using past 60-month returns from 2015/01 - 2021/03
library(fBasics)
## Loading required package: timeDate
##
## Attaching package: 'timeDate'
## The following objects are masked from 'package:PerformanceAnalytics':
##
## kurtosis, skewness
## Loading required package: timeSeries
##
## Attaching package: 'timeSeries'
## The following object is masked from 'package:zoo':
##
## time<-
##
## Attaching package: 'fBasics'
## The following object is masked from 'package:TTR':
##
## volatility
capm <- data.frame(MERGE, "2015-01-01/2021-03-31")
head(capm)
## SPY QQQ EEM IWM EFA TLT
## 1 0.03071793 0.04501044 0.01760802 0.04377882 0.002664268 -0.003430817
## 2 0.05909865 0.07428087 0.07798729 0.07909466 0.061898269 -0.020787064
## 3 0.01535150 0.02217754 -0.00166310 0.05523070 -0.028446722 0.032678511
## 4 -0.08278878 -0.07679864 -0.09864508 -0.07835767 -0.118702355 0.049821843
## 5 -0.05312741 -0.06161677 -0.01408547 -0.08059619 -0.020834896 0.056358956
## 6 0.06606917 0.07006933 0.10375152 0.06514060 0.109844203 -0.009508418
## IYR GLD MKT_RF SMB HML RF X.2015.01.01.2021.03.31.
## 1 0.05313334 0.032223420 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 2 0.09302102 -0.004396042 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 3 0.06192375 0.057168648 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 4 -0.05851441 0.030056874 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 5 -0.04782683 0.023280092 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 6 0.08988455 -0.052210719 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
sigma = cov(MERGE[, 1:8])
std = sqrt(diag(sigma))
ones = rep(1,8)
one.vec = matrix(ones, ncol=1)
a = inv(sigma)%*%one.vec
b = t(one.vec)%*%a
mvp.w =a / as.numeric(b)
mvp.w
## [,1]
## SPY 0.80379119
## QQQ -0.31471148
## EEM -0.04482473
## IWM 0.05087167
## EFA 0.15652218
## TLT 0.54509041
## IYR -0.27118396
## GLD 0.07444471
mvp.ret<-sum((mvp.w)*colMeans(capm[, 1:8]))
mvp.ret
## [1] 0.006158665
##Based on FF 3-factor model, compute MVP monthly returns covariance matrix
##for the 8-asset portfolio by using past 60-month returns from 2015/01 - 2021/03
capm <- data.frame(MERGE, "2015-01-01/2021-03-31")
head(capm)
## SPY QQQ EEM IWM EFA TLT
## 1 0.03071793 0.04501044 0.01760802 0.04377882 0.002664268 -0.003430817
## 2 0.05909865 0.07428087 0.07798729 0.07909466 0.061898269 -0.020787064
## 3 0.01535150 0.02217754 -0.00166310 0.05523070 -0.028446722 0.032678511
## 4 -0.08278878 -0.07679864 -0.09864508 -0.07835767 -0.118702355 0.049821843
## 5 -0.05312741 -0.06161677 -0.01408547 -0.08059619 -0.020834896 0.056358956
## 6 0.06606917 0.07006933 0.10375152 0.06514060 0.109844203 -0.009508418
## IYR GLD MKT_RF SMB HML RF X.2015.01.01.2021.03.31.
## 1 0.05313334 0.032223420 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 2 0.09302102 -0.004396042 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 3 0.06192375 0.057168648 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 4 -0.05851441 0.030056874 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 5 -0.04782683 0.023280092 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
## 6 0.08988455 -0.052210719 0.0296 -0.023 -0.0287 0.22 2015-01-01/2021-03-31
sigma = cov(MERGE[, 1:8])
std = sqrt(diag(sigma))
ones = rep(1,8)
one.vec = matrix(ones, ncol=1)
a = solve(sigma)%*%one.vec
b = t(one.vec)%*%a
mvp.w =a / as.numeric(b)
mvp.w
## [,1]
## SPY 0.80379119
## QQQ -0.31471148
## EEM -0.04482473
## IWM 0.05087167
## EFA 0.15652218
## TLT 0.54509041
## IYR -0.27118396
## GLD 0.07444471
mvp.ret<-sum((mvp.w)*colMeans(capm[, 1:8]))
mvp.ret
## [1] 0.006158665