Skip to content
exuber

Beyond PSY

Alternative paradigms

Tests built on different ideas from the recursive ADF: locally best invariant, stochastic-coefficient and quantile tests.

library(exuber)

Why not just use radf()

The GSADF statistic in radf() tests against one specific alternative, an explosive AR(1) root that stays fixed. lbi_test(), ssu_test() and quantile_test() are standalone hypothesis tests. They do not use the recursive core of radf() and they do not feed into the summary(), datestamp(), tidy() and autoplot() pipeline (see the results, tidying and plotting page). Each targets a different alternative, one where GSADF-style tests can lose power.

FunctionPaperAlternative it targets
lbi_test()Breitung & Diegel (2025)A fixed explosive root, tested with the locally best invariant statistic for that alternative, so it can have more power than GSADF in exactly that case.
ssu_test()Kurozumi & Nishi (2025)A stochastically varying explosive coefficient: the root has a random component and is not a fixed value.
quantile_test()Wu, Shi & Wu (2025)Explosiveness in the tau-th conditional quantile of y_t given y_{t-1}, instead of in the conditional mean.

A fixed root, which lbi_test() detects

y <- sim_psy1(n = 60, te = 1, tf = 60, c = 0.03, alpha = 0, seed = 1) # fixed rho = 1.03 throughout
lbi_test(y)
#> 
#> ── lbi_test (n = 60, sig_lvl = 95%) ────────────────────────────────────────────
#> 
#>    series  stat   crit  detected
#>   series1  6.12  1.645      TRUE

A varying root, which ssu_test() detects and lbi_test() misses

ssu_test() is designed for a root that varies stochastically over time. The coef_noise and coef_a arguments of sim_psy1() generate this alternative, with rho_t = 1 + c/n + coef_a * u_t / sqrt(n), so the root is random and not fixed:

y <- sim_psy1(n = 150, te = 75, tf = 150, c = 3, alpha = 1, seed = 2001,
              coef_noise = rnorm(149), coef_a = 4)
ssu_test(y, sig_lvl = 95)
#> 
#> ── ssu_test (SSU, n = 150, minw = 23, sig_lvl = 95%, crit = 3.3) ───────────────
#> 
#>    series   sadf  detected
#>   series1  15.02      TRUE
lbi_test(y)
#> 
#> ── lbi_test (n = 150, sig_lvl = 95%) ───────────────────────────────────────────
#> 
#>    series    stat   crit  detected
#>   series1  0.3121  1.645     FALSE

On this draw ssu_test() detects the bubble and lbi_test(), which is built for a fixed root, does not. This is not a defect of lbi_test(). Each test is the (locally) most powerful one against its own alternative, and neither dominates the other everywhere, which is why both exist.

Testing a quantile instead of the mean

quantile_test() picks a quantile tau (or takes one from you) and tests for explosiveness there instead of in the conditional mean. This pays off with heavy-tailed innovations, where the conditional-mean regression is least reliable, so the example below drives the PSY bubble with t(3) shocks:

y_t3 <- sim_psy1(n = 100, seed = 1, e = sim_innov(99, dist = "t", df = 3))
quantile_test(y_t3, nrep = 100, seed = 1)
#> 
#> ── quantile_test (n = 100, sig_lvl = 95%) ──────────────────────────────────────
#> 
#>    series   tau  tstat    crit  delta  detected
#>   series1  0.25  4.684  0.6824  0.379      TRUE

By default (tau = "optimal") the function searches tau_grid and reports the quantile with the strongest signal. The example above fixes the quantile at a specific value so that it runs faster and can be reproduced.

Which to reach for

  • If you believe the explosive root is fixed and want more power than GSADF in that case, use lbi_test().
  • If you suspect the explosive root is noisy or varies over time, use ssu_test().
  • If you suspect explosiveness shows up in the tails of the distribution, or at a specific quantile, more than in the mean, use quantile_test().
  • If you are unsure which alternative applies, or want the most widely used benchmark, start with the GSADF test in radf().