Title: | Bayesian Solutions for the Factor Zoo: We Just Ran Two Quadrillion Models |
---|---|
Description: | Contains the functions to use the econometric methods in the paper Bryzgalova, Huang, and Julliard (2023) <doi:10.1111/jofi.13197>. In this package, we provide a novel Bayesian framework for analyzing linear asset pricing models: simple, robust, and applicable to high-dimensional problems. For a stand-alone model, we provide functions including BayesianFM() and BayesianSDF() to deliver reliable price of risk estimates for both tradable and nontradable factors. For competing factors and possibly nonnested models, we provide functions including continuous_ss_sdf(), continuous_ss_sdf_v2(), and dirac_ss_sdf_pvalue() to analyze high-dimensional models. If you use this package, please cite the paper. We are thankful to Yunan Ding and Jingtong Zhang for their research assistance. Any errors or omissions are the responsibility of the authors. |
Authors: | Svetlana Bryzgalova [aut], Jiantao Huang [cre], Christian Julliard [aut] |
Maintainer: | Jiantao Huang <[email protected]> |
License: | GPL-3 |
Version: | 0.0.0.3 |
Built: | 2024-12-04 07:01:59 UTC |
Source: | CRAN |
This function provides the Bayesian Fama-MacBeth regression.
BayesianFM(f, R, sim_length)
BayesianFM(f, R, sim_length)
f |
A matrix of factors with dimension |
R |
A matrix of test assets with dimension |
sim_length |
The length of MCMCs; |
BayesianFM
is similar to another twin function in this package, BayesianSDF
,
except that we estimate factors' risk premia rather than risk prices in this function.
Unlike BayesianSDF
, we use factor loadings, , instead of covariance exposures,
,
in the Fama-MacBeth regression. In particular, after we obtain the posterior draws of
and
(details can be found in the section introducing
BayesianSDF
function),
we calculate as follows:
, and
.
Bayesian Fama-MacBeth (BFM)
The posterior distribution of conditional on
,
, and the data, is a Dirac distribution at
.
Bayesian Fama-MacBeth GLS (BFM-GLS)
The posterior distribution of conditional on
,
, and the data, is a Dirac distribution at
.
The return of BayesianFM
is a list of the following elements:
lambda_ols_path
: A sim_length
matrix of OLS risk premia estimates (Each row represents a draw.
Note that the first column is
corresponding to the constant term.
The next
columns are the risk premia estimates of the
factors);
lambda_gls_path
: A sim_length
matrix of the risk premia estimates
(GLS);
R2_ols_path
: A sim_length
matrix of the
;
R2_gls_path
: A sim_length
matrix of the
.
## <--------------------------------------------------------------------------------> ## Example: Bayesian Fama-MacBeth ## <--------------------------------------------------------------------------------> library(reshape2) library(ggplot2) # Load Data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## <-------------------Case 1: strong factor----------------------------------------> # the Frequentist Fama-MacBeth # sim_f: simulated factor, sim_R: simulated return # sim_f is the useful (i.e., strong) factor results.fm <- Two_Pass_Regression(sim_f, sim_R) # the Bayesian Fama-MacBeth with 10000 simulations results.bfm <- BayesianFM(sim_f, sim_R, 2000) # Note that the first element correspond to lambda of the constant term # So we choose k=2 to get lambda of the strong factor k <- 2 m1 <- results.fm$lambda[k] sd1 <- sqrt(results.fm$cov_lambda[k,k]) bfm<-results.bfm$lambda_ols_path[1001:2000,k] fm<-rnorm(20000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("Frequentist FM", "Bayesian FM") data.long<-melt(data) p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=1) + geom_vline(xintercept = lambda_ols[2], linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk premium ("~lambda[strong]~")")) + ylab("Density" ) ## <-------------------Case 2: useless factor---------------------------------------> # uf is the useless factor # the Frequentist Fama-MacBeth results.fm <- Two_Pass_Regression(uf, sim_R) # the Bayesian Fama-MacBeth with 10000 simulations results.bfm <- BayesianFM(uf, sim_R, 2000) # Note that the first element correspond to lambda of the constant term # So we choose k=2 to get lambda of the useless factor k <- 2 m1 <- results.fm$lambda[k] sd1 <- sqrt(results.fm$cov_lambda[k,k]) bfm<-results.bfm$lambda_ols_path[1001:2000,k] fm<-rnorm(20000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("Frequentist FM", "Bayesian FM") data.long<-melt(data) p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=1) + geom_vline(xintercept = lambda_ols[2], linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk premium ("~lambda[strong]~")")) + ylab("Density" )
## <--------------------------------------------------------------------------------> ## Example: Bayesian Fama-MacBeth ## <--------------------------------------------------------------------------------> library(reshape2) library(ggplot2) # Load Data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## <-------------------Case 1: strong factor----------------------------------------> # the Frequentist Fama-MacBeth # sim_f: simulated factor, sim_R: simulated return # sim_f is the useful (i.e., strong) factor results.fm <- Two_Pass_Regression(sim_f, sim_R) # the Bayesian Fama-MacBeth with 10000 simulations results.bfm <- BayesianFM(sim_f, sim_R, 2000) # Note that the first element correspond to lambda of the constant term # So we choose k=2 to get lambda of the strong factor k <- 2 m1 <- results.fm$lambda[k] sd1 <- sqrt(results.fm$cov_lambda[k,k]) bfm<-results.bfm$lambda_ols_path[1001:2000,k] fm<-rnorm(20000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("Frequentist FM", "Bayesian FM") data.long<-melt(data) p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=1) + geom_vline(xintercept = lambda_ols[2], linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk premium ("~lambda[strong]~")")) + ylab("Density" ) ## <-------------------Case 2: useless factor---------------------------------------> # uf is the useless factor # the Frequentist Fama-MacBeth results.fm <- Two_Pass_Regression(uf, sim_R) # the Bayesian Fama-MacBeth with 10000 simulations results.bfm <- BayesianFM(uf, sim_R, 2000) # Note that the first element correspond to lambda of the constant term # So we choose k=2 to get lambda of the useless factor k <- 2 m1 <- results.fm$lambda[k] sd1 <- sqrt(results.fm$cov_lambda[k,k]) bfm<-results.bfm$lambda_ols_path[1001:2000,k] fm<-rnorm(20000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("Frequentist FM", "Bayesian FM") data.long<-melt(data) p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=1) + geom_vline(xintercept = lambda_ols[2], linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk premium ("~lambda[strong]~")")) + ylab("Density" )
This function provides the Bayesian estimates of factors' risk prices. The estimates with the flat prior are given by Definitions 1 and 2 in Bryzgalova et al. (2023). The estimates with the normal prior are used in Table I (see the footnote of Table I).
BayesianSDF( f, R, sim_length = 10000, intercept = TRUE, type = "OLS", prior = "Flat", psi0 = 5, d = 0.5 )
BayesianSDF( f, R, sim_length = 10000, intercept = TRUE, type = "OLS", prior = "Flat", psi0 = 5, d = 0.5 )
f |
A |
R |
A |
sim_length |
The length of MCMCs |
intercept |
If |
type |
If |
prior |
If |
psi0 |
The hyper-parameter of the prior distribution of risk prices |
d |
The hyper-parameter of the prior distribution of risk prices |
Intercept
Consider the cross-sectional step. If one includes the intercept, the model is
where and
.
If one doesn't include the intercept, the model is
where and
.
Bayesian Estimation
Let . Conditional on the data
, we can draw
and
from the Normal-inverse-Wishart system
where is the inverse-Wishart distribution.
We do not standardize
in the time-series regression.
In the empirical implementation, after obtaining posterior draws for
and
,
we calculate
and
as the standardized expected returns of test assets and correlation
between test assets and factors. It follows that
is a matrix containing a vector of ones and
.
The prior distribution of risk prices is either the flat prior or the normal prior.
With prior = 'Flat'
and type = 'OLS'
, for each draw, the risk price estimate is
With prior = 'Flat'
and type = 'GLS'
, for each draw, the risk price estimate is
If one chooses prior = 'Normal'
, the prior of factor 's risk price is
where is the cross-sectionally
demeaned vector of factor
's correlations with asset returns. Equivalently,
where is a small positive number corresponding to the common cross-sectional intercept (
).
Default values for
(
psi0
) and (
d
) are 5 and 0.5, respectively.
With prior = 'Normal'
and type = 'OLS'
, for each draw, the risk price estimate is
With prior = 'Normal'
and type = 'GLS'
, for each draw, the risk price estimate is
The return of BayesianSDF
is a list that contains the following elements:
lambda_path
: A sim_length
matrix if the intercept is included.
NOTE: the first column
corresponds to the intercept. The next
columns (i.e., the 2th –
-th columns)
are the risk prices of
factors. If the intercept is excluded, the dimension of
lambda_path
is sim_length
.
R2_path
: A sim_length
matrix, which contains the posterior draws of the OLS or GLS
.
Bryzgalova S, Huang J, Julliard C (2023). “Bayesian solutions for the factor zoo: We just ran two quadrillion models <https://doi.org/10.1111/jofi.13197>.” Journal of Finance, 78(1), 487–557.
## <--------------------------------------------------------------------------------> ## Example: Bayesian estimates of risk prices and R2 ## This example is from the paper (see Section III. Simulation) ## <--------------------------------------------------------------------------------> library(reshape2) library(ggplot2) # Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf W_ols <- BFactor_zoo_example$W_ols cat("Load the simulated example \n") cat("Cross-section: Fama-French 25 size and value portfolios \n") cat("True pricing factor in simulations: HML \n") cat("Pseudo-true cross-sectional R-squared:", R2.ols.true, "\n") cat("Pseudo-true (monthly) risk price:", lambda_ols[2], "\n") cat("----------------------------- Bayesian SDF ----------------------------\n") cat("------------------------ See definitions 1 and 2 ----------------------\n") cat("--------------------- Bayesian SDF: Strong factor ---------------------\n") sim_result <- SDF_gmm(sim_R, sim_f, W_ols) # GMM estimation # sim_result$lambda_gmm # sqrt(sim_result$Avar_hat[2,2]) # sim_result$R2_adj ## Now estimate the model using Bayesian method two_step <- BayesianSDF(sim_f, sim_R, sim_length = 2000, psi0 = 5, d = 0.5) # apply(X = two_step$lambda_path, FUN = quantile, MARGIN = 2, probs = c(0.05, 0.95)) # quantile(two_step$R2_path, probs = c(0.05, 0.5, 0.95)) # Note that the first element correspond to lambda of the constant term # So we choose k=2 to get lambda of the strong factor k <- 2 m1 <- sim_result$lambda_gmm[k] sd1 <- sqrt(sim_result$Avar_hat[k,k]) bfm<-two_step$lambda_path[1001:2000, k] fm<-rnorm(5000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("GMM-OLS", "BSDF-OLS") data.long<-melt(data) # ### Figure 1(c) # p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=1) + geom_vline(xintercept = lambda_ols[2], linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk price ("~lambda[strong]~")")) + ylab("Density" ) cat("--------------------- Bayesian SDF: Useless factor --------------------\n") sim_result <- SDF_gmm(sim_R, uf, W_ols) # sim_result$lambda_gmm # sqrt(sim_result$Avar_hat[2,2]) # sim_result$R2_adj two_step <- BayesianSDF(uf, sim_R, sim_length = 2000, psi0 = 5, d = 0.5) #apply(X = two_step$lambda_path, FUN = quantile, MARGIN = 2, probs = c(0.05, 0.95)) ## Posterior (Asymptotic) Distribution of lambda k <- 2 m1 <- sim_result$lambda[k] sd1 <- sqrt(sim_result$Avar_hat[k,k]) bfm<-two_step$lambda_path[1001:2000, k] fm<-rnorm(5000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("GMM-OLS", "BSDF-OLS") data.long<-melt(data) # ### Figure 1(a) # p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=2) + geom_vline(xintercept = 0, linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk price ("~lambda[spurious]~")")) + ylab("Density" )
## <--------------------------------------------------------------------------------> ## Example: Bayesian estimates of risk prices and R2 ## This example is from the paper (see Section III. Simulation) ## <--------------------------------------------------------------------------------> library(reshape2) library(ggplot2) # Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf W_ols <- BFactor_zoo_example$W_ols cat("Load the simulated example \n") cat("Cross-section: Fama-French 25 size and value portfolios \n") cat("True pricing factor in simulations: HML \n") cat("Pseudo-true cross-sectional R-squared:", R2.ols.true, "\n") cat("Pseudo-true (monthly) risk price:", lambda_ols[2], "\n") cat("----------------------------- Bayesian SDF ----------------------------\n") cat("------------------------ See definitions 1 and 2 ----------------------\n") cat("--------------------- Bayesian SDF: Strong factor ---------------------\n") sim_result <- SDF_gmm(sim_R, sim_f, W_ols) # GMM estimation # sim_result$lambda_gmm # sqrt(sim_result$Avar_hat[2,2]) # sim_result$R2_adj ## Now estimate the model using Bayesian method two_step <- BayesianSDF(sim_f, sim_R, sim_length = 2000, psi0 = 5, d = 0.5) # apply(X = two_step$lambda_path, FUN = quantile, MARGIN = 2, probs = c(0.05, 0.95)) # quantile(two_step$R2_path, probs = c(0.05, 0.5, 0.95)) # Note that the first element correspond to lambda of the constant term # So we choose k=2 to get lambda of the strong factor k <- 2 m1 <- sim_result$lambda_gmm[k] sd1 <- sqrt(sim_result$Avar_hat[k,k]) bfm<-two_step$lambda_path[1001:2000, k] fm<-rnorm(5000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("GMM-OLS", "BSDF-OLS") data.long<-melt(data) # ### Figure 1(c) # p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=1) + geom_vline(xintercept = lambda_ols[2], linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk price ("~lambda[strong]~")")) + ylab("Density" ) cat("--------------------- Bayesian SDF: Useless factor --------------------\n") sim_result <- SDF_gmm(sim_R, uf, W_ols) # sim_result$lambda_gmm # sqrt(sim_result$Avar_hat[2,2]) # sim_result$R2_adj two_step <- BayesianSDF(uf, sim_R, sim_length = 2000, psi0 = 5, d = 0.5) #apply(X = two_step$lambda_path, FUN = quantile, MARGIN = 2, probs = c(0.05, 0.95)) ## Posterior (Asymptotic) Distribution of lambda k <- 2 m1 <- sim_result$lambda[k] sd1 <- sqrt(sim_result$Avar_hat[k,k]) bfm<-two_step$lambda_path[1001:2000, k] fm<-rnorm(5000,mean = m1, sd=sd1) data<-data.frame(cbind(fm, bfm)) colnames(data)<-c("GMM-OLS", "BSDF-OLS") data.long<-melt(data) # ### Figure 1(a) # p <- ggplot(aes(x=value, colour=variable, linetype=variable), data=data.long) p+ stat_density(aes(x=value, colour=variable), geom="line",position="identity", size = 2, adjust=2) + geom_vline(xintercept = 0, linetype="dotted", color = "#8c8c8c", size=1.5)+ guides(colour = guide_legend(override.aes=list(size=2), title.position = "top", title.hjust = 0.5, nrow=1,byrow=TRUE))+ theme_bw()+ labs(color=element_blank()) + labs(linetype=element_blank()) + theme(legend.key.width=unit(4,"line")) + theme(legend.position="bottom")+ theme(text = element_text(size = 26))+ xlab(bquote("Risk price ("~lambda[spurious]~")")) + ylab("Density" )
A simulated dataset used in Figure 1 of Bryzgalova et al. (2023).
data("BFactor_zoo_example")
data("BFactor_zoo_example")
A list consisting of the following variables:
High-minus-low value factor, from Ken French Website
Hypothetical true risk prices of factors in simulations
Hypothetical true OLS R-squared in simulations
Simulated strong factor
Simulated test asset returns
Simulated weak/unspanned factor
Weighting matrix used in GMM OLS estimations
Section III in Bryzgalova et al. (2023).
Bryzgalova S, Huang J, Julliard C (2023). “Bayesian solutions for the factor zoo: We just ran two quadrillion models <https://doi.org/10.1111/jofi.13197>.” Journal of Finance, 78(1), 487–557.
data(BFactor_zoo_example) HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf W_ols <- BFactor_zoo_example$W_ols cat("Load the simulated example \n") cat("Cross-section: Fama-French 25 size and value portfolios \n") cat("True pricing factor in simulations: HML \n") cat("Misspecified model with pseudo-true R-squared:", R2.ols.true, "\n") cat("Pseudo-true (monthly) risk price:", lambda_ols[2], "\n")
data(BFactor_zoo_example) HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf W_ols <- BFactor_zoo_example$W_ols cat("Load the simulated example \n") cat("Cross-section: Fama-French 25 size and value portfolios \n") cat("True pricing factor in simulations: HML \n") cat("Misspecified model with pseudo-true R-squared:", R2.ols.true, "\n") cat("Pseudo-true (monthly) risk price:", lambda_ols[2], "\n")
This function provides the SDF model selection procedure using the continuous spike-and-slab prior. See Propositions 3 and 4 in Bryzgalova et al. (2023).
continuous_ss_sdf( f, R, sim_length, psi0 = 1, r = 0.001, aw = 1, bw = 1, type = "OLS", intercept = TRUE )
continuous_ss_sdf( f, R, sim_length, psi0 = 1, r = 0.001, aw = 1, bw = 1, type = "OLS", intercept = TRUE )
f |
A matrix of factors with dimension |
R |
A matrix of test assets with dimension |
sim_length |
The length of monte-carlo simulations; |
psi0 |
The hyper-parameter in the prior distribution of risk prices (see Details); |
r |
The hyper-parameter related to the prior of risk prices (see Details); |
aw |
The hyper-parameter related to the prior of |
bw |
The hyper-parameter related to the prior of |
type |
If |
intercept |
If |
To model the variable selection procedure, we introduce a vector of binary latent variables ,
where
. When
, factor
(with associated loadings
) should be included
in the model and vice verse.
The continuous spike-and-slab prior of risk prices is
When the factor is included, we have
.
When the factor is excluded from the model,
.
Hence, the Dirac "spike" is replaced by a Gaussian spike, which is extremely concentrated at zero
(the default value for
is 0.001).
If
intercept = TRUE
, we choose ,
where
is the cross-sectionally demeaned vector of factor
's correlations with asset returns.
Instead, if
intercept = FALSE
, we choose .
In the codes,
is equal to the value of
psi0
.
The prior encoded the belief about the sparsity of the true model using the prior distribution
. Following the literature on the variable selection, we set
Different hyperparameters and
determine whether one a priori favors more parsimonious models or not.
We choose
(
aw
) and (
bw
) as the default values.
For each posterior draw of factors' risk prices , we can define the SDF as
.The Bayesian model averaging of the SDF (BMA-SDF)
over
draws is
The return of continuous_ss_sdf
is a list of the following elements:
gamma_path
: A sim_length
matrix of the posterior draws of
. Each row represents
a draw. If
in one draw, factor
is included in the model in this draw and vice verse.
lambda_path
: A sim_length
matrix of the risk prices
if
intercept = TRUE
. Each row represents
a draw. Note that the first column is corresponding to the constant term. The next
columns (i.e., the 2-th –
-th columns)
are the risk prices of the
factors. If
intercept = FALSE
, lambda_path
is a sim_length
matrix of the risk prices,
without the estimates of
.
sdf_path
: A sim_length
matrix of posterior draws of SDFs. Each row represents a draw.
bma_sdf
: BMA-SDF.
Bryzgalova S, Huang J, Julliard C (2023). “Bayesian solutions for the factor zoo: We just ran two quadrillion models <https://doi.org/10.1111/jofi.13197>.” Journal of Finance, 78(1), 487–557.
## Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## sim_f: simulated strong factor ## uf: simulated useless factor psi_hat <- psi_to_priorSR(sim_R, cbind(sim_f,uf), priorSR=0.1) shrinkage <- continuous_ss_sdf(cbind(sim_f,uf), sim_R, 5000, psi0=psi_hat, r=0.001, aw=1, bw=1) cat("Null hypothesis: lambda =", 0, "for each factor", "\n") cat("Posterior probabilities of rejecting the above null hypotheses are:", colMeans(shrinkage$gamma_path), "\n") ## We also have the posterior draws of SDF: m(t) = 1 - lambda_g %*% (f(t) - mu_f) sdf_path <- shrinkage$sdf_path ## We also provide the Bayesian model averaging of the SDF (BMA-SDF) bma_sdf <- shrinkage$bma_sdf
## Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## sim_f: simulated strong factor ## uf: simulated useless factor psi_hat <- psi_to_priorSR(sim_R, cbind(sim_f,uf), priorSR=0.1) shrinkage <- continuous_ss_sdf(cbind(sim_f,uf), sim_R, 5000, psi0=psi_hat, r=0.001, aw=1, bw=1) cat("Null hypothesis: lambda =", 0, "for each factor", "\n") cat("Posterior probabilities of rejecting the above null hypotheses are:", colMeans(shrinkage$gamma_path), "\n") ## We also have the posterior draws of SDF: m(t) = 1 - lambda_g %*% (f(t) - mu_f) sdf_path <- shrinkage$sdf_path ## We also provide the Bayesian model averaging of the SDF (BMA-SDF) bma_sdf <- shrinkage$bma_sdf
This function provides the SDF model selection procedure using the continuous spike-and-slab prior.
See Propositions 3 and 4 in Bryzgalova et al. (2023).
Unlike continuous_ss_sdf
, tradable factors are treated as test assets in this function.
continuous_ss_sdf_v2( f1, f2, R, sim_length, psi0 = 1, r = 0.001, aw = 1, bw = 1, type = "OLS", intercept = TRUE )
continuous_ss_sdf_v2( f1, f2, R, sim_length, psi0 = 1, r = 0.001, aw = 1, bw = 1, type = "OLS", intercept = TRUE )
f1 |
A matrix of nontradable factors with dimension |
f2 |
A matrix of tradable factors with dimension |
R |
A matrix of test assets with dimension |
sim_length |
The length of monte-carlo simulations; |
psi0 |
The hyper-parameter in the prior distribution of risk prices (see Details); |
r |
The hyper-parameter related to the prior of risk prices (see Details); |
aw |
The hyper-parameter related to the prior of |
bw |
The hyper-parameter related to the prior of |
type |
If |
intercept |
If |
See the description in the twin function continuous_ss_sdf
.
The return of continuous_ss_sdf_v2
is a list of the following elements:
gamma_path
: A sim_length
matrix of the posterior draws of
(
). Each row represents
a draw. If
in one draw, factor
is included in the model in this draw and vice verse.
lambda_path
: A sim_length
matrix of the risk prices
if
intercept = TRUE
. Each row represents
a draw. Note that the first column is corresponding to the constant term. The next
columns (i.e., the 2-th –
-th columns)
are the risk prices of the
factors. If
intercept = FALSE
, lambda_path
is a sim_length
matrix of the risk prices,
without the estimates of
.
sdf_path
: A sim_length
matrix of posterior draws of SDFs. Each row represents a draw.
bma_sdf
: BMA-SDF.
Bryzgalova S, Huang J, Julliard C (2023). “Bayesian solutions for the factor zoo: We just ran two quadrillion models <https://doi.org/10.1111/jofi.13197>.” Journal of Finance, 78(1), 487–557.
library(timeSeries) ## Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## sim_f: simulated strong factor ## uf: simulated useless factor psi_hat <- psi_to_priorSR(sim_R, cbind(sim_f,uf,sim_R[,1]), priorSR=0.1) ## We include the first test asset, sim_R[,1], into factors, so f2 = sim_R[,1,drop=FALSE]. ## Also remember excluding sim_R[,1,drop=FALSE] from test assets, so R = sim_R[,-1]. shrinkage <- continuous_ss_sdf_v2(cbind(sim_f,uf), sim_R[,1,drop=FALSE], sim_R[,-1], 1000, psi0=psi_hat, r=0.001, aw=1, bw=1) cat("Null hypothesis: lambda =", 0, "for each of these three factors", "\n") cat("Posterior probabilities of rejecting the above null hypotheses are:", colMeans(shrinkage$gamma_path), "\n") ## We also have the posterior draws of SDF: m(t) = 1 - lambda_g %*% (f(t) - mu_f) sdf_path <- shrinkage$sdf_path ## We also provide the Bayesian model averaging of the SDF (BMA-SDF) bma_sdf <- shrinkage$bma_sdf ## We can further estimate the posterior distributions of model-implied Sharpe ratios: cat("The 5th, 50th, and 95th quantiles of model-implied Sharpe ratios:", quantile(colSds(t(sdf_path)), probs=c(0.05, 0.5, 0.95)), "\n") ## Finally, we can estimate the posterior distribution of model dimensions: cat("The posterior distribution of model dimensions (= 0, 1, 2, 3):", prop.table(table(rowSums(shrinkage$gamma_path))), "\n") ## We now use the 17th test asset, sim_R[,17,drop=FALSE], as the tradable factor, ## so f2 = sim_R[,17,drop=FALSE]. ## Also remember excluding sim_R[,17,drop=FALSE] from test assets, so R = sim_R[,-17]. psi_hat <- psi_to_priorSR(sim_R, cbind(sim_f,uf,sim_R[,17]), priorSR=0.1) shrinkage <- continuous_ss_sdf_v2(cbind(sim_f,uf), sim_R[,17,drop=FALSE], sim_R[,-17], 1000, psi0=psi_hat, r=0.001, aw=1, bw=1) cat("Null hypothesis: lambda =", 0, "for each of these three factors", "\n") cat("Posterior probabilities of rejecting the above null hypotheses are:", colMeans(shrinkage$gamma_path), "\n")
library(timeSeries) ## Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## sim_f: simulated strong factor ## uf: simulated useless factor psi_hat <- psi_to_priorSR(sim_R, cbind(sim_f,uf,sim_R[,1]), priorSR=0.1) ## We include the first test asset, sim_R[,1], into factors, so f2 = sim_R[,1,drop=FALSE]. ## Also remember excluding sim_R[,1,drop=FALSE] from test assets, so R = sim_R[,-1]. shrinkage <- continuous_ss_sdf_v2(cbind(sim_f,uf), sim_R[,1,drop=FALSE], sim_R[,-1], 1000, psi0=psi_hat, r=0.001, aw=1, bw=1) cat("Null hypothesis: lambda =", 0, "for each of these three factors", "\n") cat("Posterior probabilities of rejecting the above null hypotheses are:", colMeans(shrinkage$gamma_path), "\n") ## We also have the posterior draws of SDF: m(t) = 1 - lambda_g %*% (f(t) - mu_f) sdf_path <- shrinkage$sdf_path ## We also provide the Bayesian model averaging of the SDF (BMA-SDF) bma_sdf <- shrinkage$bma_sdf ## We can further estimate the posterior distributions of model-implied Sharpe ratios: cat("The 5th, 50th, and 95th quantiles of model-implied Sharpe ratios:", quantile(colSds(t(sdf_path)), probs=c(0.05, 0.5, 0.95)), "\n") ## Finally, we can estimate the posterior distribution of model dimensions: cat("The posterior distribution of model dimensions (= 0, 1, 2, 3):", prop.table(table(rowSums(shrinkage$gamma_path))), "\n") ## We now use the 17th test asset, sim_R[,17,drop=FALSE], as the tradable factor, ## so f2 = sim_R[,17,drop=FALSE]. ## Also remember excluding sim_R[,17,drop=FALSE] from test assets, so R = sim_R[,-17]. psi_hat <- psi_to_priorSR(sim_R, cbind(sim_f,uf,sim_R[,17]), priorSR=0.1) shrinkage <- continuous_ss_sdf_v2(cbind(sim_f,uf), sim_R[,17,drop=FALSE], sim_R[,-17], 1000, psi0=psi_hat, r=0.001, aw=1, bw=1) cat("Null hypothesis: lambda =", 0, "for each of these three factors", "\n") cat("Posterior probabilities of rejecting the above null hypotheses are:", colMeans(shrinkage$gamma_path), "\n")
This function tests the null hypothesis, , when
.
When
, we compare factor models using the algorithm in Proposition 1 of Bryzgalova et al. (2023).
When
, this function corresponds to Corollary 2 in Section II.A.2 of Bryzgalova et al. (2023).
The function can also be used to compute the posterior probabilities of all possible models with up to a
given maximum number of factors (see examples).
dirac_ss_sdf_pvalue(f, R, sim_length, lambda0, psi0 = 1, max_k = NULL)
dirac_ss_sdf_pvalue(f, R, sim_length, lambda0, psi0 = 1, max_k = NULL)
f |
A matrix of factors with dimension |
R |
A matrix of test assets with dimension |
sim_length |
The length of Monte-Carlo simulations; |
lambda0 |
A |
psi0 |
The hyper-parameter in the prior distribution of risk price |
max_k |
The maximal number of factors in models ( |
Let denote a diagonal matrix with elements
, and
the submatrix of
corresponding to model
, where
is a small positive number corresponding to the common cross-sectional intercept
(
). The prior for the prices of risk (
) of model
is then
We choose
, where
is the cross-sectionally
demeaned vector of factor
's correlations with asset returns. In the codes,
is equal to the value of
psi0
.
The return of dirac_ss_sdf_pvalue
is a list of the following elements:
gamma_path
: A sim_length
matrix of the posterior draws of
. Each row represents
a draw. If
in one draw, factor
is included in the model in this draw and vice verse.
lambda_path
: A sim_length
matrix of the risk prices
. Each row represents
a draw. Note that the first column is
corresponding to the constant term. The next
columns (i.e., the 2-th –
-th columns) are the risk prices of the
factors;
model_probs
: A matrix of posterior model probabilities, where the first k columns are the model indices and the final column is a vector of model probabilities.
Bryzgalova S, Huang J, Julliard C (2023). “Bayesian solutions for the factor zoo: We just ran two quadrillion models <https://doi.org/10.1111/jofi.13197>.” Journal of Finance, 78(1), 487–557.
## <--------------------------------------------------------------------------------> ## Example: Bayesian p-value (with the dirac spike-and-slab prior) ## <--------------------------------------------------------------------------------> # Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ### Now we estimate the Bayesian p-values defined in Corollary 2. # ### Prior Sharpe ratio of factor model for different values of psi: see equation (27): # cat("--------------- Choose psi based on prior Sharpe ratio ----------------\n") cat("if psi = 1, prior Sharpe ratio is", psi_to_priorSR(sim_R, sim_f, psi0=1), "\n") cat("if psi = 2, prior Sharpe ratio is", psi_to_priorSR(sim_R, sim_f, psi0=2), "\n") cat("if psi = 5, prior Sharpe ratio is", psi_to_priorSR(sim_R, sim_f, psi0=5), "\n") ## Test whether factors' risk prices equal 'matrix(lambda_ols[2]*sd(HML),ncol=1)' ## Bayesian p-value is given by mean(shrinkage$gamma_path) shrinkage <- dirac_ss_sdf_pvalue(sim_f, sim_R, 1000, matrix(lambda_ols[2]*sd(HML),ncol=1)) cat("Null hypothesis: lambda =", matrix(lambda_ols[2]*sd(HML)), "\n") cat("Posterior probability of rejecting the above null hypothesis is:", mean(shrinkage$gamma_path), "\n") ## Test whether the risk price of factor 'sim_f' is equal to 0 shrinkage <- dirac_ss_sdf_pvalue(sim_f, sim_R, 1000, 0, psi0=1) cat("Null hypothesis: lambda =", 0, "\n") cat("Posterior probability of rejecting the above null hypothesis is:", mean(shrinkage$gamma_path), "\n") ## One can also put more than one factor into the test two_f = cbind(sim_f,uf) # sim_f is the strong factor while uf is the useless factor # Test1: lambda of sim_f = 0, Test2: lambda of uf = 0 lambda0_null_vec = t(cbind(0,0)) # 2x1 vector shrinkage <- dirac_ss_sdf_pvalue(two_f, sim_R, 1000, lambda0_null_vec, psi0=1) cat("Null hypothesis: lambda =", 0, "for each factor", "\n") cat("Posterior probabilities of rejecting the above null hypothesis are:", colMeans(shrinkage$gamma_path), "\n") ## We can also print the posterior model probabilities: cat('Posterior model probabilities are:\n') print(shrinkage$model_probs) ## One can compute the posterior probabilities of all possible models with up to ## a given maximum number of factors. For example, we consider two factors, but ## the number of factors is restricted to be less than two. lambda0_null_vec = t(cbind(0,0)) # 2x1 vector shrinkage <- dirac_ss_sdf_pvalue(two_f, sim_R, 1000, lambda0_null_vec, psi0=1, max_k=1) cat('Posterior model probabilities are:\n') print(shrinkage$model_probs) ## Comment: You may notice that the model with index (1, 1) has a posterior probability ## of exactly zero since the maximal number of factors is one.
## <--------------------------------------------------------------------------------> ## Example: Bayesian p-value (with the dirac spike-and-slab prior) ## <--------------------------------------------------------------------------------> # Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ### Now we estimate the Bayesian p-values defined in Corollary 2. # ### Prior Sharpe ratio of factor model for different values of psi: see equation (27): # cat("--------------- Choose psi based on prior Sharpe ratio ----------------\n") cat("if psi = 1, prior Sharpe ratio is", psi_to_priorSR(sim_R, sim_f, psi0=1), "\n") cat("if psi = 2, prior Sharpe ratio is", psi_to_priorSR(sim_R, sim_f, psi0=2), "\n") cat("if psi = 5, prior Sharpe ratio is", psi_to_priorSR(sim_R, sim_f, psi0=5), "\n") ## Test whether factors' risk prices equal 'matrix(lambda_ols[2]*sd(HML),ncol=1)' ## Bayesian p-value is given by mean(shrinkage$gamma_path) shrinkage <- dirac_ss_sdf_pvalue(sim_f, sim_R, 1000, matrix(lambda_ols[2]*sd(HML),ncol=1)) cat("Null hypothesis: lambda =", matrix(lambda_ols[2]*sd(HML)), "\n") cat("Posterior probability of rejecting the above null hypothesis is:", mean(shrinkage$gamma_path), "\n") ## Test whether the risk price of factor 'sim_f' is equal to 0 shrinkage <- dirac_ss_sdf_pvalue(sim_f, sim_R, 1000, 0, psi0=1) cat("Null hypothesis: lambda =", 0, "\n") cat("Posterior probability of rejecting the above null hypothesis is:", mean(shrinkage$gamma_path), "\n") ## One can also put more than one factor into the test two_f = cbind(sim_f,uf) # sim_f is the strong factor while uf is the useless factor # Test1: lambda of sim_f = 0, Test2: lambda of uf = 0 lambda0_null_vec = t(cbind(0,0)) # 2x1 vector shrinkage <- dirac_ss_sdf_pvalue(two_f, sim_R, 1000, lambda0_null_vec, psi0=1) cat("Null hypothesis: lambda =", 0, "for each factor", "\n") cat("Posterior probabilities of rejecting the above null hypothesis are:", colMeans(shrinkage$gamma_path), "\n") ## We can also print the posterior model probabilities: cat('Posterior model probabilities are:\n') print(shrinkage$model_probs) ## One can compute the posterior probabilities of all possible models with up to ## a given maximum number of factors. For example, we consider two factors, but ## the number of factors is restricted to be less than two. lambda0_null_vec = t(cbind(0,0)) # 2x1 vector shrinkage <- dirac_ss_sdf_pvalue(two_f, sim_R, 1000, lambda0_null_vec, psi0=1, max_k=1) cat('Posterior model probabilities are:\n') print(shrinkage$model_probs) ## Comment: You may notice that the model with index (1, 1) has a posterior probability ## of exactly zero since the maximal number of factors is one.
(psi0
) to the prior Sharpe ratio of factors (priorSR
), and vice versa.This function provides the one-to-one mapping between and the prior Sharpe ratio of factors.
See Section II.A.3 in Bryzgalova et al. (2023).
psi_to_priorSR(R, f, psi0 = NULL, priorSR = NULL, aw = 1, bw = 1)
psi_to_priorSR(R, f, psi0 = NULL, priorSR = NULL, aw = 1, bw = 1)
R |
A matrix of test assets with dimension |
f |
A matrix of factors with dimension |
psi0 |
The hyper-parameter in the prior distribution of risk prices (see Details in the function |
priorSR |
The prior Sharpe ratio of all factors (see Details); |
aw |
The hyper-parameter in the prior of |
bw |
The hyper-parameter in the prior of |
According to equation (27) in Bryzgalova et al. (2023), we learn that
where and
denote the Sharpe ratios of all factors (
) and of the pricing errors
(
), and
denotes prior expectations.
The prior encodes the belief about the sparsity of the true model using the prior distribution
We further integrate out
in
and show the following:
Since we can decompose the Sharpe ratios of all test assets, , into
and
(i.e.,
), we can
represent
as follows:
We define the prior Sharpe ratio implied by the factor models as .
Given
,
,
, and the observed
Sharpe ratio of test assets, we have one-to-one mapping between
and
.
If the user aims to convert to the prior Sharpe ratio, she should input only
psi0
.
In contrast, if she wants to convert the prior Sharpe ratio to ,
priorSR
should be entered.
The return of psi_to_priorSR
is:
psi0
or priorSR
.
Bryzgalova S, Huang J, Julliard C (2023). “Bayesian solutions for the factor zoo: We just ran two quadrillion models <https://doi.org/10.1111/jofi.13197>.” Journal of Finance, 78(1), 487–557.
## Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## If the user aims to convert \eqn{\psi} to the prior Sharpe ratio: print(psi_to_priorSR(sim_R, sim_f, priorSR=0.1)) ## If the user wants to convert the prior Sharpe ratio to \eqn{\psi}: psi0_to_map <- psi_to_priorSR(sim_R, sim_f, priorSR=0.1) print(psi_to_priorSR(sim_R, sim_f, psi0=psi0_to_map)) ## If we enter both psi0 and priorSR (or forget to input them simultaneously), ## a warning will be printed: print(psi_to_priorSR(sim_R, sim_f)) print(psi_to_priorSR(sim_R, sim_f, priorSR=0.1, psi0=2))
## Load the example data data("BFactor_zoo_example") HML <- BFactor_zoo_example$HML lambda_ols <- BFactor_zoo_example$lambda_ols R2.ols.true <- BFactor_zoo_example$R2.ols.true sim_f <- BFactor_zoo_example$sim_f sim_R <- BFactor_zoo_example$sim_R uf <- BFactor_zoo_example$uf ## If the user aims to convert \eqn{\psi} to the prior Sharpe ratio: print(psi_to_priorSR(sim_R, sim_f, priorSR=0.1)) ## If the user wants to convert the prior Sharpe ratio to \eqn{\psi}: psi0_to_map <- psi_to_priorSR(sim_R, sim_f, priorSR=0.1) print(psi_to_priorSR(sim_R, sim_f, psi0=psi0_to_map)) ## If we enter both psi0 and priorSR (or forget to input them simultaneously), ## a warning will be printed: print(psi_to_priorSR(sim_R, sim_f)) print(psi_to_priorSR(sim_R, sim_f, priorSR=0.1, psi0=2))
This function provides the GMM estimates of factors' risk prices under the linear SDF framework (including the common intercept).
SDF_gmm(R, f, W)
SDF_gmm(R, f, W)
R |
A matrix of test assets with dimension |
f |
A matrix of factors with dimension |
W |
Weighting matrix in GMM estimation (see Details). |
We follow the notations in Section I of Bryzgalova et al. (2023).
Suppose that there are factors,
.
The returns of
test assets are denoted by
.
Consider linear SDFs (), that is, models of the form
.
The model is estimated via GMM with moment conditions
and the corresponding sample analog function . Different weighting matrices deliver different point estimates. Two popular choices are
where is the covariance matrix of returns and
is a large constant so that
.
The asymptotic covariance matrix of risk premia estimates, Avar_hat
, is based on the assumption that
is independent over time.
The return of SDF_gmm
is a list of the following elements:
lambda_gmm
: Risk price estimates;
mu_f
: Sample means of factors;
Avar_hat
: Asymptotic covariance matrix of GMM estimates (see Details);
R2_adj
: Adjusted cross-sectional ;
S_hat
: Spectral matrix.
Bryzgalova S, Huang J, Julliard C (2023). “Bayesian solutions for the factor zoo: We just ran two quadrillion models <https://doi.org/10.1111/jofi.13197>.” Journal of Finance, 78(1), 487–557.
This function provides the frequentist Fama-MacBeth Two-Pass Regression.
Two_Pass_Regression(f, R)
Two_Pass_Regression(f, R)
f |
A matrix of factors with dimension |
R |
A matrix of test assets with dimension |
See Chapter 12.2 in Cochrane (2009). t_stat
and t_stat_gls
are t-statistics of OLS and GLS risk premia estimates based on the asymptotic standard errors in equation (12.19) in
Cochrane (2009).
The return of Two_Pass_Regression
is a list of the following elements:
lambda: Risk premia estimates in the OLS two-pass regression;
lambda_gls: Risk premia estimates in the GLS two-pass regression;
t_stat: The t-statistics of risk premia estimates in the OLS two-pass regression;
t_stat_gls: The t-statistics of risk premia estimates in the GLS two-pass regression;
R2_adj: Adjusted in the OLS two-pass regression;
R2_adj_GLS: Adjusted in the GLS two-pass regression.
Cochrane J (2009). Asset pricing: Revised edition. Princeton University Press.