library(quantmod)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Version 0.4-0 included new data defaults. See ?getSymbols.
library(plyr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:plyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
## 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(PerformanceAnalytics)
## 
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
library(tidyverse)
## -- Attaching packages -------------- tidyverse 1.3.0 --
## v ggplot2 3.3.0     v purrr   0.3.3
## v tibble  2.1.3     v stringr 1.4.0
## v tidyr   1.0.0     v forcats 0.4.0
## v readr   1.3.1
## -- Conflicts ----------------- tidyverse_conflicts() --
## x dplyr::arrange()   masks plyr::arrange()
## x purrr::compact()   masks plyr::compact()
## x dplyr::count()     masks plyr::count()
## x dplyr::failwith()  masks plyr::failwith()
## x dplyr::filter()    masks stats::filter()
## x dplyr::first()     masks xts::first()
## x dplyr::id()        masks plyr::id()
## x dplyr::lag()       masks stats::lag()
## x dplyr::last()      masks xts::last()
## x dplyr::mutate()    masks plyr::mutate()
## x dplyr::rename()    masks plyr::rename()
## x dplyr::summarise() masks plyr::summarise()
## x dplyr::summarize() masks plyr::summarize()
library(tidyr)
tickers <- c("SPY", "QQQ", "EEM", "IWM", "EFA", "TLT", "IYR", "GLD")
n <- length(tickers)
data <- new.env()
getSymbols(tickers, src="yahoo", from = "2010-01-01", to = "2018-12-30", env = data, auto.assign = T)
## '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"
con = gzcon(url('http://www.systematicportfolio.com/sit.gz','rb'))
source(con)
close(con)
bt.prep(data, align = 'remove.na', fill.gaps = T)
names(data)
##  [1] "GLD"             "prices"          "IWM"            
##  [4] "dates"           "IYR"             "TLT"            
##  [7] "weight"          "QQQ"             ".getSymbols"    
## [10] "symbolnames"     "execution.price" "EEM"            
## [13] "SPY"             "EFA"
prices <- data$prices
n <- ncol(prices)
ret <- prices/mlag(prices) - 1
ret.sample = ret[-1, ]
head(ret.sample)
##                     EEM           EFA           GLD           IWM
## 2010-01-05  0.007258277  0.0008813503 -0.0009108014 -0.0034386058
## 2010-01-06  0.002092073  0.0042268581  0.0164995902 -0.0009409818
## 2010-01-07 -0.005799118 -0.0038583129 -0.0061878037  0.0073782887
## 2010-01-08  0.007932804  0.0079225530  0.0049630301  0.0054542467
## 2010-01-11 -0.002083333  0.0082096245  0.0132889913 -0.0040296809
## 2010-01-12 -0.016005636 -0.0117810116 -0.0209127164 -0.0108932614
##                     IYR           QQQ          SPY           TLT
## 2010-01-05  0.002401157  0.0000000000  0.002647093  0.0064580894
## 2010-01-06 -0.000435453 -0.0060318615  0.000704057 -0.0133864256
## 2010-01-07  0.008932440  0.0006501734  0.004221291  0.0016820139
## 2010-01-08 -0.006694040  0.0082304747  0.003327769 -0.0004477891
## 2010-01-11  0.004782630 -0.0040815898  0.001396552 -0.0054877141
## 2010-01-12 -0.016875854 -0.0125108280 -0.009326235  0.0171170828

Q1

mean(ret.sample)
## [1] 0.0002573027
median(ret.sample)
## [1] 0.0006250431
quantile(ret.sample)
##            0%           25%           50%           75%          100% 
## -0.0878082616 -0.0050807725  0.0006250431  0.0061394001  0.0925586359
sd(ret.sample)
## [1] 0.0110936
skewness(ret.sample)
##                 EEM        EFA        GLD        IWM        IYR       QQQ
## Skewness -0.1802524 -0.4722765 -0.4821824 -0.2216965 -0.1176579 -0.295904
##                 SPY        TLT
## Skewness -0.3951384 -0.1026327
kurtosis(ret.sample)
##                      EEM      EFA      GLD      IWM      IYR      QQQ
## Excess Kurtosis 2.789026 5.568187 5.296673 3.740159 6.318948 3.109242
##                      SPY      TLT
## Excess Kurtosis 4.312212 1.556317

Q2

avg.ret <- colMeans(coredata(ret.sample))
cov.d <- cov(coredata(ret.sample))
ones.vec <- matrix(rep(1,n), ncol = 1)
numerator <- solve(cov.d) %*% ones.vec
denominator <- t(ones.vec)%*%numerator
mvp.d <- numerator / as.numeric(denominator)
mvp.d
##            [,1]
## EEM -0.12060731
## EFA  0.05284383
## GLD  0.13170178
## IWM -0.05588057
## IYR -0.09957534
## QQQ -0.19637470
## SPY  0.84908458
## TLT  0.43880774

Q3

ret.sample1 <- ret['2010-01-01/2013-12-30', ]
ret.sample.w <-   ret.sample1 %>% to.weekly(indexAt = "lastof", OHLC = FALSE)
## Warning in to.period(x, "weeks", name = name, ...): missing values removed
## from data
avg.ret.w <- colMeans(coredata(ret.sample.w))
cov.d.w <- cov(coredata(ret.sample.w))
numerator.w <- solve(cov.d.w) %*% ones.vec
denominator.w <- t(ones.vec)%*%numerator.w
mvp.w <- numerator.w / as.numeric(denominator.w)
mvp.w
##            [,1]
## EEM -0.08352460
## EFA  0.01952054
## GLD  0.07442507
## IWM -0.15410052
## IYR -0.10224186
## QQQ -0.20279976
## SPY  1.03898880
## TLT  0.40973232

Q4

ret.sample.m <-   ret.sample1 %>% to.monthly(indexAt = "lastof", OHLC = FALSE)
## Warning in to.period(x, "months", indexAt = indexAt, name = name, ...):
## missing values removed from data
avg.ret.m <- colMeans(coredata(ret.sample.m))
cov.d.m <- cov(coredata(ret.sample.m))
numerator.m <- solve(cov.d.m) %*% ones.vec
denominator.m <- t(ones.vec)%*%numerator.m
mvp.m <- numerator.m / as.numeric(denominator.m)
mvp.m
##            [,1]
## EEM -0.13936904
## EFA -0.08733580
## GLD -0.01354903
## IWM -0.34925503
## IYR -0.04351678
## QQQ  0.04773161
## SPY  1.15577650
## TLT  0.42951757

Q5.

n <- length(tickers)
constraints = new.constraints(n, lb=-Inf, ub=+Inf)
constraints <- add.constraints(rep(1,n),1, type = "=", constraints)
ia.weekly <- create.historical.ia(ret.sample.w, 250)
weight.weekly <- min.risk.portfolio(ia.weekly,constraints)
## Loading required package: kernlab
## 
## Attaching package: 'kernlab'
## The following object is masked _by_ '.GlobalEnv':
## 
##     cross
## The following object is masked from 'package:purrr':
## 
##     cross
## The following object is masked from 'package:ggplot2':
## 
##     alpha
ia.monthly <- create.historical.ia(ret.sample.m, 250)
weight.monthly <- min.risk.portfolio(ia.monthly,constraints)

Q6.

options(digits=5)
firm_data1 = read.csv("~/FamaFrench_mon_69_98_3stocks.csv")
head(firm_data1)
##     date Mkt.RF   SMB   HML   RF      ge     ibm    mobil    CRSP
## 1 196901  -1.20 -0.80  1.57 0.53 -1.1984 -5.9524  -1.4043 -0.6714
## 2 196902  -5.82 -3.90  0.93 0.46 -6.0377 -0.7004  -7.8431 -5.3641
## 3 196903   2.59 -0.28 -0.45 0.46  6.6474  7.0303  21.5130  3.0505
## 4 196904   1.52 -0.85  0.06 0.53  5.9621  4.4586   2.9961  2.0528
## 5 196905   0.02 -0.27  0.74 0.48 -3.5806 -2.5000   2.6667  0.5038
## 6 196906  -7.25 -5.31 -1.15 0.51 -3.8196  5.8777 -12.9870 -6.7388
attach(firm_data1)
library("Ecdat")
## Loading required package: Ecfun
## 
## Attaching package: 'Ecfun'
## The following object is masked from 'package:base':
## 
##     sign
## 
## Attaching package: 'Ecdat'
## The following object is masked from 'package:datasets':
## 
##     Orange
library("robust")
## Loading required package: fit.models
stocks5=cbind(N=Mkt.RF,SMB,HML)
fit = lm(cbind(Mkt.RF,SMB,HML)~RF)
options(digits=3)
pairs(cbind(Mkt.RF, SMB, HML))

cor(fit$residuals)
##        Mkt.RF    SMB    HML
## Mkt.RF  1.000  0.323 -0.411
## SMB     0.323  1.000 -0.140
## HML    -0.411 -0.140  1.000
covRob(fit$residuals,cor=F)
## Call:
## covRob(data = fit$residuals, corr = F)
## 
## Robust Estimate of Covariance: 
##        Mkt.RF   SMB   HML
## Mkt.RF  16.02  3.48 -3.99
## SMB      3.48  6.08 -1.96
## HML     -3.99 -1.96  5.86
## 
## Robust Estimate of Location: 
##  Mkt.RF     SMB     HML 
##  0.1124  0.0491 -0.2154
cor.test(fit$residuals[,1], fit$residuals[,2])
## 
##  Pearson's product-moment correlation
## 
## data:  fit$residuals[, 1] and fit$residuals[, 2]
## t = 6, df = 358, p-value = 3e-10
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.227 0.413
## sample estimates:
##   cor 
## 0.323
cor.test(fit$residuals[,1], fit$residuals[,3])
## 
##  Pearson's product-moment correlation
## 
## data:  fit$residuals[, 1] and fit$residuals[, 3]
## t = -9, df = 358, p-value = 4e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.494 -0.322
## sample estimates:
##    cor 
## -0.411
cor.test(fit$residuals[,2], fit$residuals[,3])
## 
##  Pearson's product-moment correlation
## 
## data:  fit$residuals[, 2] and fit$residuals[, 3]
## t = -3, df = 358, p-value = 0.008
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.2399 -0.0372
## sample estimates:
##   cor 
## -0.14
pairs(fit$residuals)

n=dim(firm_data1)[1]
sigF = as.matrix(var(cbind(Mkt.RF,SMB,HML)))
sigF
##        Mkt.RF   SMB   HML
## Mkt.RF  21.15  4.23 -5.10
## SMB      4.23  8.18 -1.08
## HML     -5.10 -1.08  7.18
bbeta = as.matrix(fit$coef)
bbeta = t( bbeta[-1,])
bbeta
##      Mkt.RF   SMB   HML
## [1,]  -2.66 -0.14 0.655
resig2 = apply((fit$resid)^2, 2, sum)/(n-3-1)
resig2 = diag(resig2)
cov_ff3 = sigF
cov_ff3
##        Mkt.RF   SMB   HML
## Mkt.RF  21.15  4.23 -5.10
## SMB      4.23  8.18 -1.08
## HML     -5.10 -1.08  7.18
cov2cor(cov_ff3)
##        Mkt.RF    SMB    HML
## Mkt.RF  1.000  0.322 -0.414
## SMB     0.322  1.000 -0.140
## HML    -0.414 -0.140  1.000
cov_hist = cov(stocks5)
cov2cor(cov_hist)
##          N    SMB    HML
## N    1.000  0.322 -0.414
## SMB  0.322  1.000 -0.140
## HML -0.414 -0.140  1.000
one.vec=rep(1,3)
a = solve(cov_ff3)%*%one.vec
b = t(one.vec)%*%a
mvp.w =a / as.numeric(b)
mvp.w
##         [,1]
## Mkt.RF 0.191
## SMB    0.279
## HML    0.529
a1 = solve(cov_hist)%*%one.vec
b1 = t(one.vec)%*%a1
mvp.w1 =a1 / as.numeric(b1)
mvp.w1
##      [,1]
## N   0.191
## SMB 0.279
## HML 0.529