Repository navigation
ENH: Make the ADF t- and z-test critical values and p-values consistent - #1018
Merged
Merged
Conversation
Run adf_t_simulation_process.py on all 8,000 simulation files, 2,000 per trend with 250,000 draws each. P-values below 0.15 change by at most 0.00001 and the critical values by at most 0.00003. With "c" the cut-off moves from -1.72243 to -1.70276, which changes p by up to 0.0006.
bashtage
marked this pull request as ready for review
November 11, 2026 13:50
Regress every simulated quantile of the ADF z-statistic on a constant and powers of 1/nobs, where nobs = T - 1 is the number of observations in the regression, which ADF and PhillipsPerron pass to mackinnoncrit. The simulations were labeled with the series length T, so the critical values were those of a sample one observation smaller. The regressions of the 1%, 5% and 10% quantiles are the critical values, adf_z_cv_approx. The p-value is fit to the constants of all 124 regressions, the asymptotic quantiles, in place of the quantiles with T=2000, so the p-values of the asymptotic critical values are their sizes. Use estimate_response_surface, which drops the highest power of 1/nobs while it is insignificant and fits the regression again, in place of estimate_cv_regression, which set the 1/T**3 terms of the 5% and 10% critical values with "n" and "c" to 0 without refitting the others. The files are sorted so that the averages do not depend on the order of the directory, and the script takes --data-path, --output and --ex-size, and prints the errors of the fits, as adf_t_simulation_process.py does.
Run adf_z_simlation_process.py on the 2,000 simulation files of each trend (250,000 draws each). The critical values are fit in 1/nobs, and the p-value to the asymptotic quantiles, so the p-values of the asymptotic critical values are within 0.00008 of 1%, 5% and 10%, where they were as low as 0.0097, 0.0491 and 0.0987.
Check that the p-values of the asymptotic critical values are 1%, 5% and 10%, and that the critical values match the simulated quantiles with 24, 99 and infinitely many observations in the regression. The p-value reference quantiles are now the asymptotic quantiles.
The ADF z-test critical values are now fit to the same simulations as the p-values, and the p-values of the asymptotic critical values are 1%, 5% and 10%, as for the ADF t-test with one unit root.
The critical values are now fit to the same simulations as the p-values, in powers of 1/nobs, and the p-value to the asymptotic quantiles. Update the numbers of the ADF-Z entries, which compare with 8.0.
The Engle-Granger critical values are fit to simulations in the number of observations of the ADF regression of the residuals, which engle_granger passes. The docstring said the number of observations in the time series.
small_order may be 5. The junction constraints and the monotonicity checks already handle any order. Test a quartic fit and its constraints, and that orders 2 and 6 are rejected.
With a cubic, the p-values of the asymptotic 10% critical values were off by up to 7.6e-5. With a quartic they are within 4.2e-5 of 1%, 5% and 10% with "n" and within 5e-6 otherwise. The largest error of p-values below 0.15 falls from 2.0e-4 to 6.9e-5 with "n" and from 8.4e-5 to 1.4e-5 or less otherwise. In the body the largest error is 0.013 with "n" (0.012 with the cubic) and at most 0.0015 otherwise (0.0017). The critical values are unchanged.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1018 +/- ##
=======================================
Coverage 99.44% 99.44%
=======================================
Files 153 153
Lines 34259 34278 +19
Branches 2594 2595 +1
=======================================
+ Hits 34069 34088 +19
Misses 114 114
Partials 76 76
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the ADF t-test and z-test tables consistent with each other and with how the tests look them up:
PhillipsPerronpasses.1. ADF-t from the complete run
The output barely changes:
c, where the cut-off moves from -1.72243 to -1.70276. With the other trends, p changes by at most 0.00004.The p-values of the asymptotic 1%, 5% and 10% critical values are within 0.000012 of 1%, 5% and 10%. In the tail, the largest relative error of p-values at or below 0.15 is at most 0.06% (5.7 standard errors).
2. ADF-z made consistent
adf_z_simlation_process.pynow works likeadf_t_simulation_process.py:PhillipsPerron(test_type="rho") passes T − 1 tomackinnoncrit. So the critical values were those of a sample one observation shorter, off by up to 0.35 with 25 observations and 0.03 with 100.estimate_response_surface, which drops the highest power of 1/nobs while it's insignificant and then refits. On main,estimate_cv_regressionhad set the 1/T³ terms of the 5% and 10% values withnandcto 0 without refitting.fit_smooth_pval_modelacceptssmall_order=5, and its junction and monotonicity code already handled any order.--data-path,--outputand--ex-size, and it prints the errors of the fits.These are the p-values of the asymptotic 1%, 5% and 10% critical values:
ncctcttThe p-value fit: the quartic improves the tail for every trend. The largest relative error of p-values at or below 0.15 is at most 0.05% (0.13% with the cubic), against up to 6.0% in 8.0.
ncctcttThe only cost is a slightly larger body error with
n. The p-values of the asymptotic critical values are within 0.00005 withnand within 0.000005 otherwise. Withnthis is still looser than ADF-t (0.00002), because of the large-p cubic.The critical-value regressions: they're within 2.6 standard errors of the average simulated quantile at every nobs, except with
cttat nobs = 24, where they're off by up to 0.0075 (7 standard errors at 1%, 4 at 5%). A cubic in 1/nobs doesn't quite followcttin the smallest samples.Changes from 8.0 with a constant or a trend:
c.Changes with
n: the 1%, 5% and 10% values with 100 observations are -13.09, -7.79 and -5.56. The p-value of -8 is 0.0506.This part is the work of a separate session (branch
wip-adf-z-cv), whose commits are cherry-picked here. The quartic was added afterwards.3. Lookups
Each table and the nobs that is used to look it up:
ADF,PhillipsPerrontau)resols.nobsPhillipsPerronrho)resols.nobs(T − 1)resols.nobsresid.shape[0] - lags - 1z.shape[0](T)The
engle_granger_cvdocstring said that nobs is the number of observations in the time series. It's the number of observations in the ADF regression of the residuals, whichengle_grangerpasses.engle_grangerusesADF, which divides by n − k. In small samples this makes the critical values a little too far from 0, about 2% of the statistic with 24 observations.# DOF correction?comment in the code.DFGLSdivides by nobs − 1.Checks
adf_z_simlation_process.pyand thenadf_t_simulation_process.pyon this branch reproducesdickey_fuller.pybyte for byte.test_lower_case_options.pypass (8,300).--skip-slow(31,582 passed, 812 skipped).arch.unitrootpass.🤖 Generated with Claude Code