##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