Questions:

1. Import data

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
## Warning: package 'xts' was built under R version 4.2.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.2.3
## 
## 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
## Warning: package 'quantmod' was built under R version 4.2.3
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(fPortfolio)
## Warning: package 'fPortfolio' was built under R version 4.2.3
## 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<-
## Loading required package: fBasics
## 
## Attaching package: 'fBasics'
## The following object is masked from 'package:TTR':
## 
##     volatility
## The following objects are masked from 'package:PerformanceAnalytics':
## 
##     kurtosis, skewness
## Loading required package: fAssets
## Warning: package 'fAssets' was built under R version 4.2.3
library(PerformanceAnalytics)
library(xts)
library(readr)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.2.3
## 
## ######################### Warning from 'xts' package ##########################
## #                                                                             #
## # The dplyr lag() function breaks how base R's lag() function is supposed to  #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or       #
## # source() into this session won't work correctly.                            #
## #                                                                             #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop           #
## # dplyr from breaking base R's lag() function.                                #
## #                                                                             #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning.  #
## #                                                                             #
## ###############################################################################
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:timeSeries':
## 
##     filter, lag
## The following objects are masked from 'package:xts':
## 
##     first, last
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(lubridate)
library(timetk)
library(purrr)
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.2.3
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
library(tibble)
## Warning: package 'tibble' was built under R version 4.2.3
symbols <- c("SPY", "QQQ", "EEM", "IWM", "EFA", "TLT", "IYR", "GLD")

prices <- 
  getSymbols(symbols, src = 'yahoo', from = "2010-01-01", 
             auto.assign = TRUE, warnings = FALSE) %>% 
  map(~Ad(get(.))) %>% 
  reduce(merge) %>%
  `colnames<-`(symbols)

head(prices, 6)
##                 SPY      QQQ      EEM      IWM      EFA      TLT      IYR
## 2010-01-04 88.11788 41.00547 32.42900 53.08977 37.99447 63.06118 28.77183
## 2010-01-05 88.35115 41.00547 32.66440 52.90724 38.02797 63.46839 28.84091
## 2010-01-06 88.41334 40.75814 32.73274 52.85745 38.18870 62.61876 28.82835
## 2010-01-07 88.78658 40.78463 32.54292 53.24745 38.04137 62.72409 29.08586
## 2010-01-08 89.08204 41.12030 32.80107 53.53788 38.34275 62.69599 28.89116
## 2010-01-11 89.20642 40.95247 32.73274 53.32212 38.65752 62.35199 29.02934
##               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

2. Calculate weekly and monthly returns using log returns

prices_weekly <- to.weekly(prices, indexAt = "last", OHLC = FALSE)
prices_monthly <- to.monthly(prices, indexAt = "last", OHLC = FALSE)

Calculating weekly returns

asset_returns_wk_xts <- na.omit(Return.calculate(prices_weekly))
head(asset_returns_wk_xts,6)
##                    SPY          QQQ         EEM         IWM         EFA
## 2010-01-15 -0.00811748 -0.015037422 -0.02893522 -0.01301943 -0.00349367
## 2010-01-22 -0.03898275 -0.036859494 -0.05578078 -0.03062162 -0.05574017
## 2010-01-29 -0.01666492 -0.031023677 -0.03357712 -0.02624350 -0.02580319
## 2010-02-05 -0.00679798  0.004440319 -0.02821328 -0.01397446 -0.01905500
## 2010-02-12  0.01293861  0.018148358  0.03333322  0.02952601  0.00524491
## 2010-02-19  0.02869326  0.024451190  0.02445373  0.03343178  0.02299528
##                      TLT          IYR          GLD
## 2010-01-15  2.004761e-02 -0.006303900 -0.004579349
## 2010-01-22  1.010088e-02 -0.041785761 -0.033285246
## 2010-01-29  3.369511e-03 -0.008447220 -0.011290465
## 2010-02-05 -5.391004e-05  0.003223757 -0.012080019
## 2010-02-12 -1.946104e-02 -0.007574272  0.022544905
## 2010-02-19 -8.205189e-03  0.050185301  0.022701796

Calculating monthly returns

asset_returns_mon_xts <- na.omit(Return.calculate(prices_monthly))
head(asset_returns_mon_xts,6)
##                    SPY         QQQ          EEM         IWM          EFA
## 2010-02-26  0.03119469  0.04603891  0.017763395  0.04475130  0.002667612
## 2010-03-31  0.06087986  0.07710940  0.081109172  0.08230722  0.063853990
## 2010-04-30  0.01546983  0.02242504 -0.001662106  0.05678476 -0.028045713
## 2010-05-28 -0.07945438 -0.07392361 -0.093935742 -0.07536692 -0.111928099
## 2010-06-30 -0.05174124 -0.05975683 -0.013986171 -0.07743382 -0.020619113
## 2010-07-30  0.06830062  0.07258248  0.109324772  0.06730904  0.116104271
##                     TLT         IYR          GLD
## 2010-02-26 -0.003424700  0.05457073  0.032748219
## 2010-03-31 -0.020573519  0.09748442 -0.004386396
## 2010-04-30  0.033218499  0.06388128  0.058834363
## 2010-05-28  0.051083754 -0.05683509  0.030513147
## 2010-06-30  0.057978979 -0.04670171  0.023553189
## 2010-07-30 -0.009464066  0.09404807 -0.050871157

3. Convert monthly returns into tibble format.

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.2.3
## Warning: package 'ggplot2' was built under R version 4.2.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0     ✔ stringr 1.5.0
## ✔ ggplot2 3.4.2     ✔ tidyr   1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter()          masks timeSeries::filter(), stats::filter()
## ✖ dplyr::first()           masks xts::first()
## ✖ kableExtra::group_rows() masks dplyr::group_rows()
## ✖ dplyr::lag()             masks timeSeries::lag(), stats::lag()
## ✖ dplyr::last()            masks xts::last()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
monthly_ret <- as_tibble(asset_returns_mon_xts, rownames = 'date')
head(monthly_ret,6)
## # A tibble: 6 × 9
##   date           SPY     QQQ      EEM     IWM      EFA      TLT     IYR      GLD
##   <chr>        <dbl>   <dbl>    <dbl>   <dbl>    <dbl>    <dbl>   <dbl>    <dbl>
## 1 2010-02-26  0.0312  0.0460  0.0178   0.0448  0.00267 -0.00342  0.0546  0.0327 
## 2 2010-03-31  0.0609  0.0771  0.0811   0.0823  0.0639  -0.0206   0.0975 -0.00439
## 3 2010-04-30  0.0155  0.0224 -0.00166  0.0568 -0.0280   0.0332   0.0639  0.0588 
## 4 2010-05-28 -0.0795 -0.0739 -0.0939  -0.0754 -0.112    0.0511  -0.0568  0.0305 
## 5 2010-06-30 -0.0517 -0.0598 -0.0140  -0.0774 -0.0206   0.0580  -0.0467  0.0236 
## 6 2010-07-30  0.0683  0.0726  0.109    0.0673  0.116   -0.00946  0.0940 -0.0509

4. Download Fama French 3 factors data and change to digit numbers (not in percetage):

library(readr)
data <- read_csv("C:/Users/DELL/OneDrive/Desktop/data.CSV")
## New names:
## • `` -> `...1`
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
##   dat <- vroom(...)
##   problems(dat)
## Rows: 1263 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): ...1
## dbl (4): Mkt-RF, SMB, HML, RF
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(data)
## # A tibble: 6 × 5
##   ...1   `Mkt-RF`   SMB   HML    RF
##   <chr>     <dbl> <dbl> <dbl> <dbl>
## 1 192607     2.96 -2.56 -2.43  0.22
## 2 192608     2.64 -1.17  3.82  0.25
## 3 192609     0.36 -1.4   0.13  0.23
## 4 192610    -3.24 -0.09  0.7   0.32
## 5 192611     2.53 -0.1  -0.51  0.31
## 6 192612     2.62 -0.03 -0.05  0.28
colnames(data) <- paste(c('date', "mkt_rf", "smb", "hml", "rf"))
head(data,6)
## # A tibble: 6 × 5
##   date   mkt_rf   smb   hml    rf
##   <chr>   <dbl> <dbl> <dbl> <dbl>
## 1 192607   2.96 -2.56 -2.43  0.22
## 2 192608   2.64 -1.17  3.82  0.25
## 3 192609   0.36 -1.4   0.13  0.23
## 4 192610  -3.24 -0.09  0.7   0.32
## 5 192611   2.53 -0.1  -0.51  0.31
## 6 192612   2.62 -0.03 -0.05  0.28
data_m1 <- data %>% mutate(date = as.character(date)) %>%
  mutate(date = ymd(parse_date(date, format = "%Y%m"))) %>%
  mutate(date = rollback(date))
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `date = ymd(parse_date(date, format = "%Y%m"))`.
## Caused by warning:
## ! 98 parsing failures.
##  row col       expected                           actual
## 1164  -- date like %Y%m Annual Factors: January-December
## 1166  -- date like %Y%m 1927                            
## 1167  -- date like %Y%m 1928                            
## 1168  -- date like %Y%m 1929                            
## 1169  -- date like %Y%m 1930                            
## .... ... .............. ................................
## See problems(...) for more details.
head(data_m1,6)
## # A tibble: 6 × 5
##   date       mkt_rf   smb   hml    rf
##   <date>      <dbl> <dbl> <dbl> <dbl>
## 1 1926-06-30   2.96 -2.56 -2.43  0.22
## 2 1926-07-31   2.64 -1.17  3.82  0.25
## 3 1926-08-31   0.36 -1.4   0.13  0.23
## 4 1926-09-30  -3.24 -0.09  0.7   0.32
## 5 1926-10-31   2.53 -0.1  -0.51  0.31
## 6 1926-11-30   2.62 -0.03 -0.05  0.28

5. Merge monthly return data in question 3 and 4 into tibble format. Hint: use left_join() to join the date.

mergedata1 <- merge(x = data_m1, y = asset_returns_mon_xts)
head(mergedata1,5)
##         date mkt_rf   smb   hml   rf        SPY        QQQ       EEM       IWM
## 1 1926-06-30   2.96 -2.56 -2.43 0.22 0.03119469 0.04603891 0.0177634 0.0447513
## 2 1926-07-31   2.64 -1.17  3.82 0.25 0.03119469 0.04603891 0.0177634 0.0447513
## 3 1926-08-31   0.36 -1.40  0.13 0.23 0.03119469 0.04603891 0.0177634 0.0447513
## 4 1926-09-30  -3.24 -0.09  0.70 0.32 0.03119469 0.04603891 0.0177634 0.0447513
## 5 1926-10-31   2.53 -0.10 -0.51 0.31 0.03119469 0.04603891 0.0177634 0.0447513
##           EFA        TLT        IYR        GLD
## 1 0.002667612 -0.0034247 0.05457073 0.03274822
## 2 0.002667612 -0.0034247 0.05457073 0.03274822
## 3 0.002667612 -0.0034247 0.05457073 0.03274822
## 4 0.002667612 -0.0034247 0.05457073 0.03274822
## 5 0.002667612 -0.0034247 0.05457073 0.03274822
tail(mergedata1,5)
##        date mkt_rf   smb    hml   rf        SPY        QQQ        EEM
## 203339 <NA>  23.66 13.18 -46.56 0.45 0.02883807 0.01870746 0.05190559
## 203340 <NA>  23.56 -3.89  25.53 0.04 0.02883807 0.01870746 0.05190559
## 203341 <NA> -21.60 -6.82  25.81 1.43 0.02883807 0.01870746 0.05190559
## 203342 <NA>     NA    NA     NA   NA 0.02883807 0.01870746 0.05190559
## 203343 <NA>     NA    NA     NA   NA 0.02883807 0.01870746 0.05190559
##               IWM        EFA          TLT        IYR          GLD
## 203339 0.06774699 0.03057898 -0.007759155 0.02927976 -0.001535838
## 203340 0.06774699 0.03057898 -0.007759155 0.02927976 -0.001535838
## 203341 0.06774699 0.03057898 -0.007759155 0.02927976 -0.001535838
## 203342 0.06774699 0.03057898 -0.007759155 0.02927976 -0.001535838
## 203343 0.06774699 0.03057898 -0.007759155 0.02927976 -0.001535838
data_m3 <- na.omit(mergedata1)
head(data_m3,6)
##         date mkt_rf   smb   hml   rf        SPY        QQQ       EEM       IWM
## 1 1926-06-30   2.96 -2.56 -2.43 0.22 0.03119469 0.04603891 0.0177634 0.0447513
## 2 1926-07-31   2.64 -1.17  3.82 0.25 0.03119469 0.04603891 0.0177634 0.0447513
## 3 1926-08-31   0.36 -1.40  0.13 0.23 0.03119469 0.04603891 0.0177634 0.0447513
## 4 1926-09-30  -3.24 -0.09  0.70 0.32 0.03119469 0.04603891 0.0177634 0.0447513
## 5 1926-10-31   2.53 -0.10 -0.51 0.31 0.03119469 0.04603891 0.0177634 0.0447513
## 6 1926-11-30   2.62 -0.03 -0.05 0.28 0.03119469 0.04603891 0.0177634 0.0447513
##           EFA        TLT        IYR        GLD
## 1 0.002667612 -0.0034247 0.05457073 0.03274822
## 2 0.002667612 -0.0034247 0.05457073 0.03274822
## 3 0.002667612 -0.0034247 0.05457073 0.03274822
## 4 0.002667612 -0.0034247 0.05457073 0.03274822
## 5 0.002667612 -0.0034247 0.05457073 0.03274822
## 6 0.002667612 -0.0034247 0.05457073 0.03274822

6. Based on CAPM model, compute covariance matrix for the 8-asset portfolio by using past 60-month returns from 2010/02 - 2015/01.

data_m4 <- na.omit(data_m3)
head(data_m4,6)
##         date mkt_rf   smb   hml   rf        SPY        QQQ       EEM       IWM
## 1 1926-06-30   2.96 -2.56 -2.43 0.22 0.03119469 0.04603891 0.0177634 0.0447513
## 2 1926-07-31   2.64 -1.17  3.82 0.25 0.03119469 0.04603891 0.0177634 0.0447513
## 3 1926-08-31   0.36 -1.40  0.13 0.23 0.03119469 0.04603891 0.0177634 0.0447513
## 4 1926-09-30  -3.24 -0.09  0.70 0.32 0.03119469 0.04603891 0.0177634 0.0447513
## 5 1926-10-31   2.53 -0.10 -0.51 0.31 0.03119469 0.04603891 0.0177634 0.0447513
## 6 1926-11-30   2.62 -0.03 -0.05 0.28 0.03119469 0.04603891 0.0177634 0.0447513
##           EFA        TLT        IYR        GLD
## 1 0.002667612 -0.0034247 0.05457073 0.03274822
## 2 0.002667612 -0.0034247 0.05457073 0.03274822
## 3 0.002667612 -0.0034247 0.05457073 0.03274822
## 4 0.002667612 -0.0034247 0.05457073 0.03274822
## 5 0.002667612 -0.0034247 0.05457073 0.03274822
## 6 0.002667612 -0.0034247 0.05457073 0.03274822
data_m5 <- data_m4 %>% 
  filter(date >= ymd("2010-02-28") & date <= ymd("2014-12-31"))
head(data_m5,6)
##         date mkt_rf   smb   hml   rf        SPY        QQQ       EEM       IWM
## 1 2010-02-28   6.31  1.48  2.21 0.01 0.03119469 0.04603891 0.0177634 0.0447513
## 2 2010-03-31   2.00  4.87  2.89 0.01 0.03119469 0.04603891 0.0177634 0.0447513
## 3 2010-04-30  -7.89  0.09 -2.44 0.01 0.03119469 0.04603891 0.0177634 0.0447513
## 4 2010-05-31  -5.57 -1.82 -4.70 0.01 0.03119469 0.04603891 0.0177634 0.0447513
## 5 2010-06-30   6.93  0.22 -0.33 0.01 0.03119469 0.04603891 0.0177634 0.0447513
## 6 2010-07-31  -4.77 -2.98 -1.93 0.01 0.03119469 0.04603891 0.0177634 0.0447513
##           EFA        TLT        IYR        GLD
## 1 0.002667612 -0.0034247 0.05457073 0.03274822
## 2 0.002667612 -0.0034247 0.05457073 0.03274822
## 3 0.002667612 -0.0034247 0.05457073 0.03274822
## 4 0.002667612 -0.0034247 0.05457073 0.03274822
## 5 0.002667612 -0.0034247 0.05457073 0.03274822
## 6 0.002667612 -0.0034247 0.05457073 0.03274822

Create an empty list to store the results

result_list <- list()
y <- NULL
for (symbol in symbols) {
  diff <- data_m5[,symbol] - data_m5$rf
  result_name <- paste0(symbol, "_rf")
  assign(result_name, diff)
  y <- cbind(y, get(result_name))
}
#Calculating Beta
n <- nrow(y)
one_vec <- rep(1,n)

x <- NULL
x <- cbind(one_vec,data_m5$mkt_rf)
beta_hat = solve(t(x)%*%x)%*%t(x) %*% y
beta_hat
##                 [,1]         [,2]          [,3]         [,4]         [,5]
## one_vec 7.618268e-03 1.177616e-02 -9.633714e-05 6.253079e-03 1.997156e-03
##         9.118814e-05 9.118814e-05  9.118814e-05 9.118814e-05 9.118814e-05
##                 [,6]         [,7]         [,8]
## one_vec 5.486656e-05 4.691208e-03 9.027284e-04
##         9.118814e-05 9.118814e-05 9.118814e-05
E_hat = y - x %*% beta_hat

Excluding constant term

beta_hat = as.matrix(beta_hat[-1,])
diagD_hat = diag(t(E_hat) %*% E_hat)/(n-2)

Covariance matrix by single factor model

cov = as.numeric(var(data_m5$mkt_rf))*beta_hat%*%t(beta_hat) + diag(diagD_hat)
cov
##              [,1]         [,2]         [,3]         [,4]         [,5]
## [1,] 1.804109e-03 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07
## [2,] 1.261442e-07 2.595991e-03 1.261442e-07 1.261442e-07 1.261442e-07
## [3,] 1.261442e-07 1.261442e-07 2.906444e-03 1.261442e-07 1.261442e-07
## [4,] 1.261442e-07 1.261442e-07 1.261442e-07 3.159851e-03 1.261442e-07
## [5,] 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07 2.175131e-03
## [6,] 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07
## [7,] 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07
## [8,] 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07 1.261442e-07
##              [,6]         [,7]         [,8]
## [1,] 1.261442e-07 1.261442e-07 1.261442e-07
## [2,] 1.261442e-07 1.261442e-07 1.261442e-07
## [3,] 1.261442e-07 1.261442e-07 1.261442e-07
## [4,] 1.261442e-07 1.261442e-07 1.261442e-07
## [5,] 1.261442e-07 1.261442e-07 1.261442e-07
## [6,] 1.532394e-03 1.261442e-07 1.261442e-07
## [7,] 1.261442e-07 2.330579e-03 1.261442e-07
## [8,] 1.261442e-07 1.261442e-07 2.117136e-03

7. Based on FF 3-factor model, compute covariance matrix for the 8-asset portfolio by using past 60-month returns from 2010/02 - 2015/01.

t <- dim(data_m5)[1]
markets <- data_m5[,c(2,3,4)]
stocks1 <- data_m5[,c(-1,-2,-3,-4)]
head(stocks1,6)
##     rf        SPY        QQQ       EEM       IWM         EFA        TLT
## 1 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## 2 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## 3 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## 4 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## 5 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## 6 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
##          IYR        GLD
## 1 0.05457073 0.03274822
## 2 0.05457073 0.03274822
## 3 0.05457073 0.03274822
## 4 0.05457073 0.03274822
## 5 0.05457073 0.03274822
## 6 0.05457073 0.03274822
stocks3 <- as.matrix(stocks1)
head(stocks3,6)
##        rf        SPY        QQQ       EEM       IWM         EFA        TLT
## [1,] 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## [2,] 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## [3,] 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## [4,] 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## [5,] 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
## [6,] 0.01 0.03119469 0.04603891 0.0177634 0.0447513 0.002667612 -0.0034247
##             IYR        GLD
## [1,] 0.05457073 0.03274822
## [2,] 0.05457073 0.03274822
## [3,] 0.05457073 0.03274822
## [4,] 0.05457073 0.03274822
## [5,] 0.05457073 0.03274822
## [6,] 0.05457073 0.03274822
n <- dim(stocks3)[2]
one_vec <- rep(1,t)
p <- as.matrix(cbind(one_vec,markets))
beta <- solve(t(p)%*%p)%*%t(p)%*%stocks3
beta
##                    rf           SPY           QQQ           EEM           IWM
## one_vec  0.0037517546  1.112323e-02  1.528112e-02  3.408622e-03  9.758038e-03
## mkt_rf  -0.0002949038  2.721602e-17  3.738073e-17  8.335969e-18  2.387553e-17
## smb      0.0006417988 -2.585552e-17 -3.550304e-17 -8.028708e-18 -2.277942e-17
## hml      0.0002409029 -9.702339e-18 -1.326072e-17 -2.901935e-18 -8.414425e-18
##                   EFA           TLT           IYR           GLD
## one_vec  5.502115e-03  3.559826e-03  8.196167e-03  4.407688e-03
## mkt_rf   1.346782e-17  8.719119e-18  2.005456e-17  1.078100e-17
## smb     -1.276333e-17 -8.305191e-18 -1.902462e-17 -1.026538e-17
## hml     -4.748043e-18 -3.083306e-18 -7.090936e-18 -3.773161e-18
#Compute the residual
res <- stocks3-p%*%beta
diag.d <- diag(t(res)%*%res)/(t-6)
diag.d
##           rf          SPY          QQQ          EEM          IWM          EFA 
## 2.078442e-05 1.782448e-03 2.574663e-03 2.885247e-03 3.138761e-03 2.153626e-03 
##          TLT          IYR          GLD 
## 1.510618e-03 2.309140e-03 2.095607e-03
retvar <- apply(stocks3,2,var)
rsq <- 1-diag(t(res)%*%res)/((t-1)/retvar)
res.stdev <- sqrt(diag.d)
factor.cov <- var(stocks1)*t(beta)%*%beta+diag(diag.d)
stdev <- sqrt(diag(factor.cov))
factor.cor <- factor.cov/(stdev%*%t(stdev))
factor.cor
##                rf           SPY           QQQ           EEM           IWM
## rf   1.000000e+00  3.487705e-25 -1.113760e-24 -2.536661e-25  7.389493e-26
## SPY  3.487705e-25  1.000000e+00  1.556828e-04  2.724764e-05  9.606217e-05
## QQQ -1.113760e-24  1.556828e-04  1.000000e+00  3.396032e-05  1.145176e-04
## EEM -2.536661e-25  2.724764e-05  3.396032e-05  1.000000e+00  2.255752e-05
## IWM  7.389493e-26  9.606217e-05  1.145176e-04  2.255752e-05  1.000000e+00
## EFA  4.721642e-25  5.307188e-05  6.482837e-05  1.572667e-05  4.154175e-05
## TLT  9.363112e-26 -8.218969e-06 -4.792172e-06 -1.961608e-06 -1.084706e-05
## IYR -4.867952e-25  6.942932e-05  8.137362e-05  1.681643e-05  5.577784e-05
## GLD  1.887155e-25  4.942995e-06  8.757581e-06  4.512833e-06  1.695366e-06
##               EFA           TLT           IYR          GLD
## rf   4.721642e-25  9.363112e-26 -4.867952e-25 1.887155e-25
## SPY  5.307188e-05 -8.218969e-06  6.942932e-05 4.942995e-06
## QQQ  6.482837e-05 -4.792172e-06  8.137362e-05 8.757581e-06
## EEM  1.572667e-05 -1.961608e-06  1.681643e-05 4.512833e-06
## IWM  4.154175e-05 -1.084706e-05  5.577784e-05 1.695366e-06
## EFA  1.000000e+00 -4.145402e-06  3.138998e-05 3.726146e-06
## TLT -4.145402e-06  1.000000e+00  3.118175e-06 4.481842e-06
## IYR  3.138998e-05  3.118175e-06  1.000000e+00 7.051260e-06
## GLD  3.726146e-06  4.481842e-06  7.051260e-06 1.000000e+00
cov_mon <- cov(asset_returns_mon_xts)
one <- rep(1,8)
one_m <- matrix(one, ncol=1)
a2 <- inv(cov_mon)%*%one_m
b2 <- t(one_m)%*%inv(cov_mon)%*%one_m
mvp2 <- a2/as.vector(b2)
head(mvp2)
##            [,1]
## SPY  0.98019954
## QQQ -0.45610362
## EEM -0.02751396
## IWM  0.06621562
## EFA  0.08560161
## TLT  0.52383354

8. Compute global minimum variance portfolio weights based on question 6 and 7.

stocks_mean <- colMeans(stocks3,na.rm = TRUE)
cov.mat <- as.matrix(cov)
a6 <- inv(cov_mon)%*%one_m
b6 <- t(one_m)%*%inv(cov_mon)%*%one_m
mvp6 <- a6/as.vector(b6)
colnames(mvp6)="Weight"
mvp6
##          Weight
## SPY  0.98019954
## QQQ -0.45610362
## EEM -0.02751396
## IWM  0.06621562
## EFA  0.08560161
## TLT  0.52383354
## IYR -0.30024109
## GLD  0.12800837

9. Using SIT package to backtest the performance of GMV (global minimum variance) portfolios based on CAPM model and Fama-French three-factor model. You have to use historical six monthly returns (t-6 to t-1) to estimate the optimal weights which will be assigned to assets to construct portfolios for investment in next month (t). By repeating this process every month, you can derive the monthly returns of GMV portfolios based on CAPM and Fama-French three-factor model.

con = gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb'))
source(con)
close(con)

tickers = spl('SPY,QQQ,EEM,IWM,EFA,TLT,IYR,GLD')
prices
##                  SPY       QQQ      EEM       IWM      EFA       TLT      IYR
## 2010-01-04  88.11788  41.00547 32.42900  53.08977 37.99447  63.06118 28.77183
## 2010-01-05  88.35115  41.00547 32.66440  52.90724 38.02797  63.46839 28.84091
## 2010-01-06  88.41334  40.75814 32.73274  52.85745 38.18870  62.61876 28.82835
## 2010-01-07  88.78658  40.78463 32.54292  53.24745 38.04137  62.72409 29.08586
## 2010-01-08  89.08204  41.12030 32.80107  53.53788 38.34275  62.69599 28.89116
## 2010-01-11  89.20642  40.95247 32.73274  53.32212 38.65752  62.35199 29.02934
## 2010-01-12  88.37449  40.44010 32.20884  52.74128 38.20210  63.41926 28.53944
## 2010-01-13  89.12091  40.94363 32.30754  53.42171 38.52358  62.68195 29.07331
## 2010-01-14  89.36191  40.97896 32.22401  53.62088 38.81826  63.55969 28.97282
## 2010-01-15  88.35892  40.50196 31.85197  52.84085 38.20879  63.95290 28.70903
##        ...                                                                   
## 2023-05-26 420.01999 348.39999 38.69684 175.66353 70.84142 100.82204 81.06729
## 2023-05-30 420.17999 349.98001 38.25034 175.01534 70.12457 101.82936 81.41566
## 2023-05-31 417.85001 347.98999 37.89314 173.29012 69.39788 102.71700 81.84364
## 2023-06-01 421.82001 352.01001 38.56785 175.16490 70.42898 103.12000 81.89339
## 2023-06-02 427.92001 354.64999 39.23264 181.51733 71.34224 101.99000 83.72475
## 2023-06-05 427.10001 354.89999 39.22272 179.08406 70.92980 101.80000 83.16738
## 2023-06-06 428.03000 354.84000 39.57000 183.80099 71.51900 102.40000 83.88400
## 2023-06-07 426.54999 348.82001 39.40000 187.24001 70.89000 100.88000 85.20000
## 2023-06-08 429.13000 353.14999 39.68000 186.53999 71.64000 102.06000 84.76000
## 2023-06-09 429.89999 354.50000 39.86000 185.03000 71.52000 101.92000 84.24000
##               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
## 2010-01-12 110.49
## 2010-01-13 111.54
## 2010-01-14 112.03
## 2010-01-15 110.86
##        ...       
## 2023-05-26 180.92
## 2023-05-30 182.04
## 2023-05-31 182.32
## 2023-06-01 183.76
## 2023-06-02 181.05
## 2023-06-05 182.14
## 2023-06-06 182.34
## 2023-06-07 180.15
## 2023-06-08 182.53
## 2023-06-09 182.04
asset_returns_mon_xts <- na.omit(Return.calculate(prices_monthly))
prices_q <- to.quarterly(prices, indexAt = "last", OHLC = FALSE)
asset_q <- na.omit(Return.calculate(prices_q))

head(asset_returns_mon_xts)
##                    SPY         QQQ          EEM         IWM          EFA
## 2010-02-26  0.03119469  0.04603891  0.017763395  0.04475130  0.002667612
## 2010-03-31  0.06087986  0.07710940  0.081109172  0.08230722  0.063853990
## 2010-04-30  0.01546983  0.02242504 -0.001662106  0.05678476 -0.028045713
## 2010-05-28 -0.07945438 -0.07392361 -0.093935742 -0.07536692 -0.111928099
## 2010-06-30 -0.05174124 -0.05975683 -0.013986171 -0.07743382 -0.020619113
## 2010-07-30  0.06830062  0.07258248  0.109324772  0.06730904  0.116104271
##                     TLT         IYR          GLD
## 2010-02-26 -0.003424700  0.05457073  0.032748219
## 2010-03-31 -0.020573519  0.09748442 -0.004386396
## 2010-04-30  0.033218499  0.06388128  0.058834363
## 2010-05-28  0.051083754 -0.05683509  0.030513147
## 2010-06-30  0.057978979 -0.04670171  0.023553189
## 2010-07-30 -0.009464066  0.09404807 -0.050871157
tail(asset_returns_mon_xts)
##                     SPY          QQQ          EEM          IWM         EFA
## 2023-01-31  0.062887396  0.106429242  0.091292802  0.098187522  0.09003651
## 2023-02-28 -0.025142710 -0.003597815 -0.075677020 -0.017234124 -0.03074776
## 2023-03-31  0.037077821  0.094927224  0.032173717 -0.048473419  0.03129052
## 2023-04-28  0.015974933  0.005079005 -0.008362893 -0.017937217  0.02936259
## 2023-05-31  0.004616194  0.078838024 -0.024022500 -0.008162042 -0.04007072
## 2023-06-09  0.028838070  0.018707463  0.051905590  0.067746988  0.03057898
##                     TLT          IYR          GLD
## 2023-01-31  0.076436435  0.099774250  0.057592574
## 2023-02-28 -0.048505534 -0.059617719 -0.053675964
## 2023-03-31  0.048393403 -0.019369783  0.079161282
## 2023-04-28  0.003383570  0.009187207  0.008623523
## 2023-05-31 -0.030152929 -0.040266046 -0.013419890
## 2023-06-09 -0.007759155  0.029279764 -0.001535838
head(asset_q)
##                      SPY          QQQ         EEM         IWM         EFA
## 2010-06-30 -0.1135806944 -0.109736684 -0.10809302 -0.09852540 -0.15463241
## 2010-09-30  0.1116161719  0.151601597  0.19962495  0.11080257  0.18082146
## 2010-12-31  0.1076081694  0.112043280  0.07301707  0.16435951  0.07006469
## 2011-03-31  0.0589736367  0.056023862  0.02162050  0.07803846  0.03194783
## 2011-06-30  0.0002587127 -0.004389145 -0.01220429 -0.01627687  0.02044919
## 2011-09-30 -0.1381722686 -0.078223734 -0.26260492 -0.21807571 -0.20552012
##                    TLT         IYR         GLD
## 2010-06-30  0.14896430 -0.04344573 0.116842622
## 2010-09-30  0.04658993  0.12985003 0.051199896
## 2010-12-31 -0.09557040  0.06966929 0.084512526
## 2011-03-31 -0.01453031  0.07072168 0.008217989
## 2011-06-30  0.03383297  0.02440122 0.043901039
## 2011-09-30  0.29631031 -0.15231108 0.082602723
tail(asset_q)
##                    SPY          QQQ         EEM         IWM         EFA
## 2022-03-31 -0.04614467 -0.087625454 -0.07574213 -0.07541704 -0.06456523
## 2022-06-30 -0.16110269 -0.225412986 -0.10430185 -0.17276598 -0.13216752
## 2022-09-30 -0.04931150 -0.044739828 -0.13017448 -0.02117924 -0.10369667
## 2022-12-30  0.07560925 -0.001281646  0.10314388  0.06211796  0.17663251
## 2023-03-31  0.07458221  0.207100892  0.04116087  0.02694574  0.08957940
## 2023-06-09  0.05009888  0.104602275  0.01805054  0.04003591  0.01833084
##                    TLT         IYR          GLD
## 2022-03-31 -0.10628835 -0.06431350  0.056679848
## 2022-06-30 -0.12593269 -0.14703214 -0.067478481
## 2022-09-30 -0.10284015 -0.10549777 -0.081859243
## 2022-12-30 -0.01879842  0.04334517  0.096786716
## 2023-03-31  0.07378896  0.01417583  0.080051886
## 2023-06-09 -0.03442204 -0.00308982 -0.006440388