Learn R Programming

BayesianFactorZoo (version 0.0.0.3)

dirac_ss_sdf_pvalue: Hypothesis testing for risk prices (Bayesian p-values) with Dirac spike-and-slab prior

Description

This function tests the null hypothesis, \(H_0: \lambda = \lambda_0\), when \(\gamma=0\). When \(\lambda_0 = 0\), we compare factor models using the algorithm in Proposition 1 of bryzgalova2023bayesian;textualBayesianFactorZoo. When \(\lambda_0 \neq 0\), this function corresponds to Corollary 2 in Section II.A.2 of bryzgalova2023bayesian;textualBayesianFactorZoo. 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).

Usage

dirac_ss_sdf_pvalue(f, R, sim_length, lambda0, psi0 = 1, max_k = NULL)

Value

The return of dirac_ss_sdf_pvalue is a list of the following elements:

  • gamma_path: A sim_length\(\times k\) matrix of the posterior draws of \(\gamma\). Each row represents a draw. If \(\gamma_j = 1\) in one draw, factor \(j\) is included in the model in this draw and vice verse.

  • lambda_path: A sim_length\(\times (k+1)\) matrix of the risk prices \(\lambda\). Each row represents a draw. Note that the first column is \(\lambda_c\) corresponding to the constant term. The next \(k\) columns (i.e., the 2-th -- \((k+1)\)-th columns) are the risk prices of the \(k\) factors;

  • model_probs: A \(2^k \times (k+1)\) matrix of posterior model probabilities, where the first k columns are the model indices and the final column is a vector of model probabilities.

Arguments

f

A matrix of factors with dimension \(t \times k\), where \(k\) is the number of factors and \(t\) is the number of periods;

R

A matrix of test assets with dimension \(t \times N\), where \(t\) is the number of periods and \(N\) is the number of test assets;

sim_length

The length of Monte-Carlo simulations;

lambda0

A \(k \times 1\) vector of risk prices under the null hypothesis (\(\gamma=0\));

psi0

The hyper-parameter in the prior distribution of risk price \(\lambda\) (see Details);

max_k

The maximal number of factors in models (max_k is a positive integer or NULL if the user does not impose any restriction on the model dimension).

Details

Let \(D\) denote a diagonal matrix with elements \(c, \psi_1^{-1},..., \psi_K^{-1}\), and \(D_\gamma\) the submatrix of \(D\) corresponding to model \(\gamma\), where \(c\) is a small positive number corresponding to the common cross-sectional intercept (\(\lambda_c\)). The prior for the prices of risk (\(\lambda_\gamma\)) of model \(\gamma\) is then $$ \lambda_\gamma | \sigma^2, \gamma \sim N (0, \sigma^2, D_{\gamma}^{-1}). $$

We choose \( \psi_j = \psi \tilde{\rho}_j^\top \tilde{\rho}_j \), where \( \tilde{\rho}_j = \rho_j - (\frac{1}{N} \Sigma_{i=1}^{N} \rho_{j,i} ) \times 1_N \) is the cross-sectionally demeaned vector of factor \(j\)'s correlations with asset returns. In the codes, \(\psi\) is equal to the value of psi0.

References

bryzgalova2023bayesianBayesianFactorZoo

Examples

Run this code

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

Run the code above in your browser using DataLab