Package 'spantest'

Title: Mean-Variance Spanning Tests
Description: Provides a comprehensive suite of portfolio spanning tests for asset pricing, such as Huberman and Kandel (1987) <doi:10.1111/j.1540-6261.1987.tb03917.x>, Gibbons et al. (1989) <doi:10.2307/1913625>, Kempf and Memmel (2006) <doi:10.1007/BF03396737>, Pesaran and Yamagata (2024) <doi:10.1093/jjfinec/nbad002>, and Gungor and Luger (2016) <doi:10.1080/07350015.2015.1019510>.
Authors: David Ardia [aut, cre] (ORCID: <https://orcid.org/0000-0003-2823-782X>), Benjamin Seguin [aut], Rosnel Sessinou [ctb], Richard Luger [ctb]
Maintainer: David Ardia <[email protected]>
License: GPL-3
Version: 1.3-0
Built: 2026-07-13 23:39:29 UTC
Source: https://github.com/ardiad/spantest

Help Index


Ardia and Sessinou (2025) Subseries-Based Cauchy Combination Test (SCT) for Spanning

Description

Computes robust p-values for linear spanning restrictions using a residual-based subseries procedure with Cauchy Combination Test (CCT) aggregation. Supports high-dimensional inference for H0δH_0^\delta (variance/spread slopes), H0αH_0^\alpha (intercepts), and the joint null H0α,δH_0^{\alpha,\delta}.

Usage

span_as(bench, test, control = list())

Arguments

bench

Numeric matrix of benchmark returns, dimension T×KT \times K.

test

Numeric matrix of test-asset returns, dimension T×NT \times N.

control

Optional list passed to internal computation:

ks

Numeric vector of subseries exponents (block size approximately floor(T^k)); default c(1/3).

L

Numeric vector of perturbation scales for randomized projections; default c(0, 2).

Details

For each k in ks, data are partitioned into overlapping subseries of length floor(T^k). Residual perturbations controlled by L generate test statistics robust to serial and cross-sectional dependence and conditional heteroskedasticity. Resulting sub-p-values are aggregated by the Cauchy Combination Test (CCT), which remains valid under dependence and retains power in high dimensions.

Value

A named list of global (combined) p-values. Names encode hypothesis and settings:

  • CCTd_L{L}_k{i} — variance (slope) spanning, δ=0\delta = 0;

  • CCTa_L{L}_k{i} — alpha spanning, α=0\alpha = 0;

  • CCTad_L{L}_k{i} — joint mean–variance spanning, α=0, δ=0\alpha = 0,\ \delta = 0.

References

Ardia D, Sessinou R (2025). “Robust Inference in Large Panels and Markowitz Portfolios.” doi:10.2139/ssrn.5033399. Working paper.

See Also

Other Alpha Spanning Tests: span_bj(), span_f1(), span_gl_a(), span_grs(), span_py()

Other Variance Spanning Tests: span_f2(), span_km()

Other Joint Mean-Variance Spanning Tests: span_gl_ad(), span_hk()

Examples

set.seed(123)
bench <- matrix(rnorm(300), 100, 3)
test  <- matrix(rnorm(200), 100, 2)
out <- span_as(bench, test)
out$CCTa_L0_k1; out$CCTd_L0_k1; out$CCTad_L0_k1

Britten–Jones Tangency-Portfolio Spanning Test (1999)

Description

Tests whether the tangency (maximum Sharpe) portfolio of the augmented universe (benchmarks + test assets) is spanned by the benchmark assets alone. Following Britten–Jones (1999), the statistic arises from a regression of a constant on the raw asset returns (without an intercept) and yields an FF test of the tangency-spanning restriction.

Usage

span_bj(R1, R2)

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

Details

Following Britten–Jones (1999), the (unnormalized) tangency-portfolio weights are obtained by regressing a vector of ones on the raw asset returns without an intercept. The null that the benchmarks span the tangency portfolio is the restriction that the test assets carry zero weight, tested by comparing the residual sums of squares of the full and benchmark-only regressions. The statistic has an FN, TKNF_{N,\ T-K-N} reference distribution; finite-sample feasibility requires TKN1T-K-N \ge 1.

Value

A named list with components:

pval

P-value for the FF-statistic under the null.

stat

Britten–Jones FF-statistic.

H0

Null hypothesis description, "alpha = 0" (the test assets do not expand the tangency portfolio spanned by the benchmarks).

References

Britten-Jones M (1999). “The Sampling Error in Estimates of Mean-Variance Efficient Portfolio Weights.” The Journal of Finance, 54(2), 655–671.

See Also

Other Alpha Spanning Tests: span_as(), span_f1(), span_gl_a(), span_grs(), span_py()

Examples

set.seed(321)
R1 <- matrix(rnorm(300), 100, 3)  # benchmarks: T=100, K=3
R2 <- matrix(rnorm(200), 100, 2)  # tests:      T=100, N=2
out <- span_bj(R1, R2)
out$stat; out$pval; out$H0

F1 Alpha-Spanning Test (Intercepts Only)

Description

Tests the null H0: α=0H_0:\ \alpha = 0 that the intercepts of the test assets are jointly zero when regressed on the benchmark assets, i.e., benchmarks span the mean of the test assets. This is the F1 test of Kan & Zhou (2012).

Usage

span_f1(R1, R2)

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

Details

Under standard assumptions (i.i.d. returns, full-rank covariances), the reference distribution is FN, TKNF_{N,\ T-K-N}. Finite-sample feasibility requires TKN1T-K-N \ge 1.

Value

A named list with components:

pval

P-value for the FF-statistic under the null.

stat

F1 FF-statistic.

H0

Null hypothesis description, "alpha = 0".

References

Kan R, Zhou G (2012). “Tests of Mean-Variance Spanning.” Annals of Economics and Finance, 13(1), 145–193.

See Also

Other Alpha Spanning Tests: span_as(), span_bj(), span_gl_a(), span_grs(), span_py()

Examples

set.seed(123)
R1 <- matrix(rnorm(300), 100, 3)  # benchmarks: T=100, K=3
R2 <- matrix(rnorm(200), 100, 2)  # tests:      T=100, N=2
out <- span_f1(R1, R2)
out$stat; out$pval; out$H0

F2 Variance-Spanning Test (Slopes Only)

Description

Tests the null H0: δ=0H_0:\ \delta = 0 that adding test assets does not improve the minimum-variance frontier spanned by the benchmarks (variance spanning). The statistic compares frontier-defining quantities of the augmented (benchmark + test) universe to those of the benchmark subset.

Usage

span_f2(R1, R2)

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

Details

Under standard conditions (i.i.d. returns, full-rank covariances), the reference distribution is FN, TKN+1F_{N,\ T-K-N+1}. Finite-sample feasibility requires TKN+11T-K-N+1 \ge 1.

Value

A named list with components:

pval

P-value for the FF-statistic under the null.

stat

F2 FF-statistic.

H0

Null hypothesis description, "delta = 0".

References

Kan R, Zhou G (2012). “Tests of Mean-Variance Spanning.” Annals of Economics and Finance, 13(1), 145–193.

See Also

Other Variance Spanning Tests: span_as(), span_km()

Examples

set.seed(123)
R1 <- matrix(rnorm(300), 100, 3)  # benchmarks: T=100, K=3
R2 <- matrix(rnorm(200), 100, 2)  # tests:      T=100, N=2
out <- span_f2(R1, R2)
out$stat; out$pval; out$H0

Gungor–Luger Alpha-Only Spanning Test (2016)

Description

Tests the null H0: α=0H_0:\ \alpha = 0 that benchmark assets span the mean (intercepts) of the test assets. Following Gungor & Luger (2016), the procedure uses a Monte Carlo (MC) test based on an FmaxF_{\max} statistic with residual sign-flip simulations, yielding Least-Favorable (LMC) and Balanced (BMC) MC p-values and a three-way decision rule.

Usage

span_gl_a(R1, R2, control = list())

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

control

List of options:

totsim

Number of MC simulations (default 500).

pval_thresh

Significance level for decisions (default 0.05).

do_trace

Logical; print progress (default FALSE).

Details

Accept if pval_LMC > alpha; Reject if pval_BMC <= alpha; otherwise Inconclusive. The subseries sign-flip MC approach is robust to heteroskedasticity, serial dependence, and heavy tails, making it suitable for high-dimensional settings where classical alpha tests (e.g., GRS) may suffer from size distortions.

Value

A list with components:

pval_LMC

Least-Favorable MC p-value.

pval_BMC

Balanced MC p-value.

stat

Observed FmaxF_{\max} statistic.

Decisions

Decision code: 1 = Accept, 0 = Reject, NA = Inconclusive.

Decisions_string

Text label: "Accept", "Reject", or "Inconclusive".

H0

Null hypothesis description, "alpha = 0".

References

Gungor S, Luger R (2016). “Multivariate Tests of Mean-Variance Efficiency and Spanning With a Large Number of Assets and Time-Varying Covariances.” Journal of Business & Economic Statistics, 34(2), 161–175.

See Also

Other Alpha Spanning Tests: span_as(), span_bj(), span_f1(), span_grs(), span_py()

Examples

set.seed(1234)
R1 <- matrix(rnorm(300), 100, 3)
R2 <- matrix(rnorm(200), 100, 2)
out <- span_gl_a(R1, R2, control = list(totsim = 100, do_trace = FALSE))
out$Decisions_string; out$pval_LMC; out$pval_BMC

Gungor–Luger Joint Mean–Variance Spanning Test (2016)

Description

Tests the joint null H0: α=0, δ=0H_0:\ \alpha = 0,\ \delta = 0 that benchmark assets span both intercepts and slopes of the test assets, allowing for heteroskedasticity, serial dependence, and time-varying covariances. Following Gungor & Luger (2016), the procedure uses a Monte Carlo (MC) test based on an FmaxF_{\max} statistic with residual sign-flip simulations, yielding Least-Favorable (LMC) and Balanced (BMC) MC p-values and a three-way decision rule.

Usage

span_gl_ad(R1, R2, control = list())

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

control

List of options:

totsim

Number of MC simulations (default 500).

pval_thresh

Significance level for decisions (default 0.05).

do_trace

Logical; print progress (default FALSE).

Details

LMC/BMC follow Gungor & Luger’s MC framework with residual sign-flip draws under the null. The rule is: Accept if pval_LMC > alpha; Reject if pval_BMC <= alpha; otherwise Inconclusive. This approach is robust in high-dimensional and time-varying volatility settings where classical joint spanning tests can be unreliable.

Value

A list with components:

pval_LMC

Least-Favorable MC p-value.

pval_BMC

Balanced MC p-value.

stat

Observed FmaxF_{\max} statistic.

Decisions

Decision code: 1 = Accept, 0 = Reject, NA = Inconclusive.

Decisions_string

Text label: "Accept", "Reject", or "Inconclusive".

H0

Null hypothesis description, "alpha = 0 and delta = 0".

References

Gungor S, Luger R (2016). “Multivariate Tests of Mean-Variance Efficiency and Spanning With a Large Number of Assets and Time-Varying Covariances.” Journal of Business & Economic Statistics, 34(2), 161–175.

See Also

Other Joint Mean-Variance Spanning Tests: span_as(), span_hk()

Examples

set.seed(123)
R1 <- matrix(rnorm(300), 100, 3)
R2 <- matrix(rnorm(200), 100, 2)
out <- span_gl_ad(R1, R2, control = list(totsim = 100, do_trace = FALSE))
out$Decisions_string; out$pval_LMC; out$pval_BMC

Gibbons–Ross–Shanken (GRS) Alpha Spanning Test (1989)

Description

Implements the GRS test of the joint null H0: α=0H_0:\ \alpha = 0 in the multivariate regression of test-asset returns on benchmark portfolios (with an intercept). The statistic assumes homoskedastic, normally distributed errors and is most reliable when TT is large relative to KK (benchmarks) and NN (test assets).

Usage

span_grs(R1, R2)

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

Details

Under standard conditions, the reference distribution is FN, TNKF_{N,\ T-N-K}. Finite-sample feasibility requires TNK1T-N-K \ge 1.

Value

A named list with components:

pval

P-value for the FF-statistic under the null.

stat

GRS FF-statistic.

H0

Null hypothesis description, "alpha = 0".

References

Gibbons MR, Ross SA, Shanken J (1989). “A Test of the Efficiency of a Given Portfolio.” Econometrica, 57(5), 1121–1152.

See Also

Other Alpha Spanning Tests: span_as(), span_bj(), span_f1(), span_gl_a(), span_py()

Examples

set.seed(42)
R1 <- matrix(rnorm(300), 100, 3)  # benchmarks: T=100, K=3
R2 <- matrix(rnorm(200), 100, 2)  # tests:      T=100, N=2
out <- span_grs(R1, R2)
out$stat; out$pval; out$H0

Huberman–Kandel Joint Mean–Variance Spanning Test (1987)

Description

Tests the joint null H0: α=0, δ=0H_0:\ \alpha = 0,\ \delta = 0 that the benchmark assets span the mean–variance frontier of the augmented (benchmark + test) universe. Following Huberman & Kandel (1987), the statistic compares the frontiers with and without the additional assets.

Usage

span_hk(R1, R2)

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

Details

The test evaluates whether adding the test assets changes the efficient frontier implied by the benchmarks. Under standard regularity conditions, the statistic has an FF reference with (2N, 2(TKN))(2N,\ 2(T-K-N)) degrees of freedom. Finite-sample feasibility requires TKN1T-K-N \ge 1.

Value

A named list with components:

pval

P-value for the FF-statistic under the null.

stat

FF-statistic value.

H0

Null hypothesis description, "alpha = 0 and delta = 0".

References

Huberman G, Kandel S (1987). “Mean-Variance Spanning.” The Journal of Finance, 42(4), 873–888.

See Also

Other Joint Mean-Variance Spanning Tests: span_as(), span_gl_ad()

Examples

set.seed(123)
R1 <- matrix(rnorm(300), 100, 3)  # benchmarks: T=100, K=3
R2 <- matrix(rnorm(200), 100, 2)  # tests:      T=100, N=2
out <- span_hk(R1, R2)
out$stat; out$pval; out$H0

Kempf–Memmel GMVP Spanning Test

Description

Tests whether the Global Minimum Variance Portfolio (GMVP) of the combined (benchmark + test) universe equals the GMVP of the benchmark assets alone. Following Kempf & Memmel (2006), the null assesses whether adding new assets improves the minimum-variance frontier.

Usage

span_km(R1, R2)

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

Details

The null hypothesis H0H_0 is that augmenting the benchmark set with the test assets does not change the GMVP weights (Δ=0\Delta = 0), i.e., the GMVP of the full universe coincides with that of the benchmark subset. The test is implemented via a linear restriction on coefficients in an equivalent regression representation, yielding an FF-statistic.

Value

A named list with components:

pval

P-value for the F-statistic under the null.

stat

F-statistic value.

H0

Null hypothesis description, "delta = 0" (equivalently, GMVP of the benchmark set equals GMVP of the full universe).

References

Kempf A, Memmel C (2006). “Estimating the Global Minimum Variance Portfolio.” Schmalenbach Business Review, 58(4), 332–348.

See Also

Other Variance Spanning Tests: span_as(), span_f2()

Examples

set.seed(123)
R1 <- matrix(rnorm(300), 100, 3)  # benchmarks: T=100, K=3
R2 <- matrix(rnorm(200), 100, 2)  # test assets: T=100, N=2
ans <- span_km(R1, R2)
ans$pval; ans$stat; ans$H0

Pesaran–Yamagata Alpha Spanning Test (2024)

Description

Implements the Pesaran–Yamagata test for the joint null that all intercepts are zero in a multi-factor spanning regression with possible cross-sectional dependence across test assets.

Usage

span_py(R1, R2)

Arguments

R1

Numeric matrix of benchmark returns, dimension T×KT \times K.

R2

Numeric matrix of test-asset returns, dimension T×NT \times N.

Details

The null hypothesis is that all intercepts are zero (α=0\alpha = 0), meaning the benchmark assets span the expected returns of the test assets. The statistic adjusts for cross-sectional dependence via the residual covariance and has an asymptotic N(0,1)\mathcal{N}(0,1) reference under large T,NT,N. Finite-sample safeguards require TK1>4T-K-1 > 4 and at least two test assets (N2N \ge 2); otherwise pval and stat are returned as NA.

Value

A named list with components:

pval

P-value under the standard normal reference distribution.

stat

Standardized test statistic.

H0

Null hypothesis description, "alpha = 0".

References

Pesaran MH, Yamagata T (2024). “Testing for alpha in linear factor pricing models with a large number of securities.” Journal of Financial Econometrics, 22(2), 407–460.

See Also

Other Alpha Spanning Tests: span_as(), span_bj(), span_f1(), span_gl_a(), span_grs()

Examples

set.seed(123)
R1 <- matrix(rnorm(300), 100, 3)  # benchmarks: T=100, K=3
R2 <- matrix(rnorm(200), 100, 2)  # tests:      T=100, N=2
out <- span_py(R1, R2)
out$pval; out$stat; out$H0

Simulate Benchmark and Test-Asset Returns for Spanning Studies

Description

Generates a panel of benchmark returns R1R_1 (n×Kn \times K) and test-asset returns R2R_2 (n×Nn \times N) from a factor model with a controllable mean-variance spanning violation, matching the data-generating processes used in the size/power study of Ardia and Sessinou (2025). It is a fast, self-contained replacement for ad-hoc fGarch::garchSim() loops: the innovations are drawn in one vectorised call and the AR / GARCH dynamics are applied with a lightweight recursion.

Usage

span_simulate(
  n,
  K,
  N,
  ncp = 0,
  rho_factor = 0.8,
  rho_error = 0.5,
  innovation = c("normal", "t", "skew-t"),
  dynamics = c("iid", "ar", "garch", "ar-garch"),
  sparse = FALSE,
  df = 5,
  xi = 0.9,
  ar = 0.2,
  garch = c(omega = 0.1, alpha = 0.1, beta = 0.8),
  standardize = TRUE,
  dgp = NULL,
  burnin = 500L
)

Arguments

n

Integer, number of time periods (sample size).

K

Integer, number of benchmark assets.

N

Integer, number of test assets.

ncp

Non-centrality controlling the spanning violation (0 = null).

rho_factor, rho_error

Toeplitz correlation decays for the factors and the idiosyncratic terms, in [0,1)[0, 1).

innovation

Marginal law of the innovations: "normal", "t", or "skew-t". Ignored if dgp is supplied.

dynamics

Serial structure: "iid", "ar", "garch", or "ar-garch". Ignored if dgp is supplied.

sparse

Logical; if TRUE, zero the first N/2\lfloor N/2\rfloor intercepts (sparse alternative).

df

Degrees of freedom for the Student-/skew-tt innovations.

xi

Skewness parameter for the skew-tt innovations.

ar

AR(1) coefficient (used by "ar" and "ar-garch").

garch

Named numeric vector c(omega, alpha, beta) for the GARCH(1,1) variance recursion.

standardize

Logical; standardise tt innovations to unit variance.

dgp

Optional integer in 1:12; selects a preset process (see Details) and overrides innovation/dynamics/df/xi/ standardize.

burnin

Integer, number of initial observations discarded to remove the AR/GARCH transient.

Details

The latent factors zz are KK innovation series, cross-sectionally correlated through the Cholesky factor of a Toeplitz matrix with decay rho_factor; the idiosyncratic terms are NN innovation series with Toeplitz decay rho_error. Test assets are

R2=α+zB+ε,B=(1+ncp)1K×N,αj=ncp,R_2 = \alpha + z B + \varepsilon, \qquad B = (1+\text{ncp})\,\mathbf{1}_{K\times N},\quad \alpha_j = \text{ncp},

and the benchmarks are R1=[z1,  z1+z1]R_1 = [\,z_1,\; z_{-1}+z_1\,]. Under ncp = 0 the benchmarks span the test assets (α=0\alpha = 0); larger |ncp| moves the intercepts and loadings away from the spanning null. With sparse = TRUE the first N/2\lfloor N/2 \rfloor intercepts are set to zero (a sparse alternative); α\alpha is added column-wise, i.e. asset jj receives αj\alpha_j.

Each innovation series is defined by innovation (marginal law) and dynamics (serial structure): "iid", an AR(1) with coefficient ar, a GARCH(1,1) with parameters garch, or their "ar-garch" combination. Student-tt innovations are standardised to unit variance when standardize = TRUE; skew-tt innovations (standardised Fernandez-Steel skew-tt) are always unit-variance, so standardize has no effect on them.

dgp is a convenience argument selecting one of the twelve processes of Ardia and Sessinou (2025); when supplied it overrides innovation, dynamics, df, xi and standardize:

1 normal, iid 7 normal, AR-GARCH
2 Student-t(5), iid (raw) 8 Student-t(4), AR-GARCH
3 skew-t(4, 0.9), iid 9 skew-t(4, 0.9), AR-GARCH
4 normal, GARCH 10 normal, AR
5 Student-t(4), GARCH 11 Student-t(5), AR (raw)
6 skew-t(4, 0.9), GARCH 12 skew-t(4, 0.9), AR

DGPs 2 and 11 use raw (non-standardised) t5t_5 innovations, as in the original study; all other heavy-tailed processes are standardised.

Value

A list with components R1 (n×Kn \times K benchmark returns) and R2 (n×Nn \times N test-asset returns), suitable as the R1/R2 arguments of the spanning tests in this package.

Note

Set the RNG state with set.seed beforehand for reproducibility.

References

Ardia D, Sessinou R (2025). “Robust Inference in Large Panels and Markowitz Portfolios.” doi:10.2139/ssrn.5033399. Working paper.
Gungor S, Luger R (2016). “Multivariate Tests of Mean-Variance Efficiency and Spanning With a Large Number of Assets and Time-Varying Covariances.” Journal of Business & Economic Statistics, 34(2), 161–175.

See Also

span_grs(), span_gl_ad(), span_as()

Examples

set.seed(1)
sim <- span_simulate(n = 250, K = 3, N = 10, ncp = 0)       # spanning null
span_grs(sim$R1, sim$R2)$pval

sim2 <- span_simulate(n = 250, K = 3, N = 10, ncp = 0.2)    # alternative
span_grs(sim2$R1, sim2$R2)$pval