*! version 1.0.0 29may2026

Title

qqtest -- Formal tests on the QQR surface β(τ,θ) (joint bootstrap)

Syntax

qqtest using drawsfile [, test(name) dim(name)]

where drawsfile is the long-format bootstrap-draws dataset written by
qqr ..., bsave(drawsfile) (variables
rep tau theta beta).

test(name) hypothesis to test: zero (default), symmetry, constancy

dim(name) for constancy only: tau (default) or theta

Description

qqtest turns the quantile-on-quantile picture into formal
inference. A single QQR run gives an M×L grid of slopes β(τ,θ); the eye
can suggest that the surface is non-zero, asymmetric, or varies across
quantiles, but a hypothesis test is needed to make the claim. qqtest
provides three families of tests, each evaluated with three complementary
test statistics, using the joint bootstrap draws so that the
correlation across cells of the surface is respected.

The joint bootstrap is the key design choice: a single resample index is
reused across the whole grid in each replication, so the B draws
preserve the cross-cell covariance of β(τ,θ). This is what makes a
simultaneous (sup-type) test over the surface valid, rather than testing
each cell in isolation.

Workflow

qqtest never re-estimates anything; it consumes a draws file. Produce
that file once with qqr:

. qqr y x, tau(0.1(0.1)0.9) theta(0.1(0.1)0.9) nboot(500) ///

. bci bsave(draws.dta) saving(qq.dta) replace

then run as many tests as you like against draws.dta. The same file
also feeds qqribbon and qqdiff. More bootstrap
replications (nboot() in qqr) give more stable bootstrap
p-values; 500–1000 is recommended for final results.

The hypotheses

test(zero) H0: β(τ,θ) = 0 for every (τ,θ). A global test
that the predictor has no quantile-on-quantile effect anywhere on the grid.
Rejection means there is some region of the (τ,θ) plane with a genuine
effect. (q = M·L restrictions.)

test(symmetry) H0: β(τ,θ) = β(1−τ,θ). Tests whether the
effect is symmetric in the response quantile about the median. Rejection is
evidence of tail asymmetry — e.g. the predictor matters more in the
lower tail of y than in the upper tail. (q = ⌊M/2⌋·L restrictions.)

test(constancy) H0: the slope does not vary along one quantile
dimension. With dim(tau) it tests β(τ,θ) = β(τ′,θ) for all τ
within each θ (no variation across response quantiles); with
dim(theta) it tests constancy across predictor quantiles. Rejection
means the relationship is genuinely quantile-dependent — the central
justification for using QQR over a single quantile or OLS regression.
(q = (M−1)·L or M·(L−1) restrictions.)

The statistics

Each hypothesis is written as a set of linear restrictions Rβ = 0 and
evaluated three ways. Reading several together guards against any one
statistic's quirks:

KS (sup-t) the largest standardised restriction,
max|Rβ/sd|. A sup-type statistic — sensitive to a strong
violation in even a single region. p-value from the re-centred bootstrap.

Cramér–von Mises the sum of squared standardised
restrictions. An integrated statistic — sensitive to many small,
diffuse violations spread over the surface. p-value from the bootstrap.

Wald the quadratic form (Rβ)′ V⁻¹ (Rβ) using the full
bootstrap covariance V of the restrictions. Reported with both a
bootstrap p-value and the χ²(q) asymptotic p-value.

In every case a small p-value rejects H0. Prefer the bootstrap
p-values; the χ² column is a convenience cross-check for the Wald statistic
and can be unreliable when q is large relative to B.

Options

test(name) selects the hypothesis: zero (default), symmetry,
or constancy.

dim(name) applies only to test(constancy) and picks the dimension
held constant under H0: tau (default, vary the response quantile) or
theta (vary the predictor quantile).

Stored results

qqtest stores the following in r():

Scalars

r(q) number of restrictions

r(KS) KS sup-t statistic

r(p_KS) bootstrap p-value for KS

r(CvM) Cramér–von Mises statistic

r(p_CvM) bootstrap p-value for CvM

r(Wald) Wald statistic

r(p_Wald_boot) bootstrap p-value for Wald

r(p_Wald_chi2) χ²(q) asymptotic p-value for Wald

Macros

r(test) the hypothesis tested

r(dim) the constancy dimension

Examples

Build the draws file once, then test

. qqr y x, tau(0.1(0.1)0.9) theta(0.1(0.1)0.9) nboot(500) bsave(draws.dta) replace

. qqtest using draws.dta, test(zero)

. qqtest using draws.dta, test(symmetry)

. qqtest using draws.dta, test(constancy) dim(tau)

. qqtest using draws.dta, test(constancy) dim(theta)

Grab a stored p-value

. qqtest using draws.dta, test(zero)

. display "reject no-effect? " (r(p_Wald_boot) < 0.05)

References

Sim, N. and Zhou, H. (2015). Oil prices, US stock return, and the
dependence between their quantiles. Journal of Banking & Finance 55:1-12.

Koenker, R. (2005). Quantile Regression. Cambridge University Press.

Author

Merwan Roudane. merwanroudane920@gmail.com

See also

qqr, qqribbon, qqdiff, qqheat,
qqsurf3d, qqr_package