multi-asset principal component regression using...
TRANSCRIPT
Multi-Asset Principal Component Regression usingRcppParallel
Jason FosterCRAN - Package ‘roll’
May 21, 2016
CRAN - Package ‘roll’Functions use RcppParallel to parallelize rolling statistics of time-series data.Install the latest version from CRAN:
install.packages("roll")
Function Description
roll_mean Rolling meansroll_var Rolling variancesroll_sd Rolling standard deviationsroll_cov Rolling covariance matricesroll_cor Rolling correlation matricesroll_lm Rolling linear modelsroll_eigen Rolling eigenvalues and eigenvectorsroll_pcr Rolling principal component regressionsroll_vif Rolling variance inflation factors
Jason Foster CRAN - Package ’roll’ 2 / 16
Roll the Fama-French model for 1,000 portfolios!Full data set includes daily factor returns from Jul-1926 to Mar-2016. Adaily rolling window requires over 70 million calculations for 1,000 portfolios!
844 mins
4 mins0
245
490
735
980
0 250 500 750 1,000
Number of portfolios
Min
utes
R's lm
roll's roll_lm
From 14 hours to 4 mins!
Tested with 4 cores (8 threads) on a 2.5GHz laptop
Jason Foster CRAN - Package ’roll’ 3 / 16
R version
Download factor returns using Quandl:
library(Quandl)factors <- Quandl("KFRENCH/FACTORS_D")
Start with plain R and estimate a portfolio’s sensitivity to each factor byrolling the lm function:
lm_coef <- function(returns) {return(lm(formula = Portfolio ~., data = returns)$coef)
}
r_lm_coef <- rollapply(data = returns, width = 252,FUN = lm_coef, by.column = FALSE,align = "right")
Jason Foster CRAN - Package ’roll’ 4 / 16
RcppParallel version
Repeat the exercise and take advantage of parallel processing in C++ byusing the roll_lm function in the roll package:
library(roll)roll_lm_coef <- roll_lm(x = returns[ , factors],
y = returns[ , portfolio],width = 252)$coefficients
And test that the coefficients from the lm and roll_lm functions are equal:
all.equal(r_lm_coef, roll_lm_coef)
## [1] TRUE
Jason Foster CRAN - Package ’roll’ 5 / 16
Crowded positions
Here’s an excerpt from BlackRock’s Global Investment Outlook (Apr-2016):
Full report: https://www.blackrock.com/investing/insights/blackrock-investment-institute/outlook
Jason Foster CRAN - Package ’roll’ 6 / 16
Style analysis of multi-asset portfolios
Download daily returns for 100 portfolios in the Tactical Allocation categoryand apply a 15 asset-class factor model on a daily rolling window:
Stocks Bonds & Other
US Large Cap Value US Gov 1-10YUS Large Cap Growth US Gov 10Y+US Mid Cap Non-US GovUS Small Cap IG CorpEurope HY CorpJapan MBSPacific ex Japan CommoditiesEmerging Markets
Sharpe, William F. 1988. “Determining a Fund’s Effective Asset Mix.” Investment Management Review.
Jason Foster CRAN - Package ’roll’ 7 / 16
Identify trends in the markets
Daily returns are readily available and help make inferences about style:
191.9 secs
0.5 secs0
55
110
165
220
0 25 50 75 100
Number of portfolios
Sec
onds
R's lm
roll's roll_lm
414x over R version!
Speed test uses univariate betas
0.0
0.2
0.4
0.6
0.8
2012 2013 2014 2015 2016
Coe
ffici
ents
Median portfolio
Purple areas are stocks and green areas are bonds & other
Jason Foster CRAN - Package ’roll’ 8 / 16
What about market structure?
Asset classes can be strongly correlated to one another:
50.9 secs
0.1 secs0
15
30
45
60
2 5 8 12 15
Number of asset−classes
Sec
onds
R's lm
roll's roll_vif
351x over R version!
Speed test uses univariate betas
0
15
30
45
60
2012 2013 2014 2015 2016
Var
ianc
e in
flatio
n fa
ctor
s
Multicollinearity
Purple areas are stocks and green areas are bonds & other
Jason Foster CRAN - Package ’roll’ 9 / 16
Risk-on, risk-off
A market environment that isdriven by changes in investorrisk tolerance is often describedas "risk-on, risk-off"That is, during periods of low(high) risk appetite, investorsgravitate towards higher (lower)risk investments −0.2
−0.1
0.0
0.1
0.2
−10 −5 0 5 10
S&P 500 (%)
US
Gov
10Y
(%
)
Jason Foster CRAN - Package ’roll’ 10 / 16
Principal component analysis
The roll_eigen function shows a change in direction during the TaperTantrum, a scenario where both equities and bonds sold-off:
PC1
PC2
0
25
50
75
100
2012 2013 2014 2015 2016
Var
ianc
e ex
plai
ned
(%)
Eigenvalues
Speed test uses univariate betas
−1.2
0.0
1.2
2.4
3.6
2012 2013 2014 2015 2016
First eigenvector
Purple areas are stocks and green areas are bonds & other
Jason Foster CRAN - Package ’roll’ 11 / 16
Principal component regression
Principal component regression is a regression technique that uses principalcomponent analysis:
1 Perform principal component analysis on the correlation matrix ofasset-class returns
2 Select a subset of principal components and regress against amulti-asset portfolio’s returns
3 Transform coefficients back to get the dimension equal to the numberof asset-classes
Jason Foster CRAN - Package ’roll’ 12 / 16
Explanatory power by principal component
Explain the variance in each multi-asset portfolio’s returns using principalcomponent regression:
241.9 secs
1.1 secs0
70
140
210
280
0 25 50 75 100
Number of portfolios
Sec
onds
R's pcr
roll's roll_pcr
214x over R version!
Speed test uses univariate betas
PC1
PC2
0
25
50
75
100
2012 2013 2014 2015 2016
R−
squa
red
(%)
Median portfolio
Speed test uses univariate betas
Jason Foster CRAN - Package ’roll’ 13 / 16
R version
The R implementation of principal component regression by rolling the pcrfunction is given below:
library(pls)pcr_coef <- function(returns) {
return(coef(pcr(formula = Portfolio ~., data = returns,ncomp = 1, scale = TRUE),
intercept = TRUE))}
r_pcr_coef <- rollapply(data = returns, width = 252,FUN = pcr_coef, by.column = FALSE,align = "right")
Jason Foster CRAN - Package ’roll’ 14 / 16
RcppParallel version
Repeat the exercise and take advantage of parallel processing in C++ byusing the roll_pcr function in the roll package:
library(roll)roll_pcr_coef <- roll_pcr(x = returns[ , factors],
y = returns[ , portfolio],width = 252, comps = 1,scale_x = TRUE)$coefficients
And test that the coefficients from the pcr and roll_pcr functions areequal:
all.equal(r_pcr_coef, roll_pcr_coef)
## [1] TRUE
Jason Foster CRAN - Package ’roll’ 15 / 16
CRAN - Package ‘roll’
Get the released version from CRAN:
install.packages("roll")
Or the development version from GitHub:
# install.packages("devtools")devtools::install_github("jjf234/roll")
Jason Foster CRAN - Package ’roll’ 16 / 16