cultivars.spectral.filters#
Trend-cycle filters: four answers to “what is the trend”, each with its bill.
A trend-cycle decomposition is a definition, not a discovery, and the four here define the trend differently. Hodrick-Prescott and Butterworth are penalized low-pass filters: the trend is the minimizer of
whose two-sided gain \(\bigl[1 + (\sin(\omega/2)/\sin(\omega_c/2))^{2n} \bigr]^{-1}\) is one half at the cutoff \(\omega_c = 2\pi/P\), with \(\lambda = (2\sin(\pi/P))^{-2n}\); HP is the case \(n = 2\) stated by weight (1600 quarterly is \(P = 39.7\)), Butterworth the same family stated by period and order. Hamilton’s regression filter defines the trend as the fitted value of \(y_{t+h}\) on a constant and \(y_t, \dots, y_{t-p+1}\), so the cycle is what the level’s own recent history could not predict two years ahead; it exists because HP manufactures dynamics – a spurious cycle from a random walk, larger than the increments themselves; end-point values that change as data arrive; a penalty with no rationale at other frequencies – and the HP result prints that critique rather than assuming the user knows it. Beveridge-Nelson is model-based: for a fitted ARIMA(p, 1, q) the trend is the level the long-horizon forecast settles on net of drift,
evaluated exactly in companion form, so the cycle is minus the forecastable momentum of the differences – which is why a BN cycle is small, noisy, and negatively correlated with growth where the others are smooth. Not a bug; a different question.
Two commitments shape the surface. First, every method’s bill is
carried on the result: DecompositionFilterResult records the
rows a one-sided method lost (offset) and flags the rows a two-sided
method will revise (provisional, the first and last cutoff
observations of a penalized filter), and its summary prints the cycle’s
standard deviation against that of the input’s growth – the diagnostic
on which Hamilton’s critique rests – followed by the method’s own
caveats. Second, nothing here estimates a model: the three filters that
touch data are linear operations on a panel, column by column, and the
Beveridge-Nelson decomposition reads its answer off an ARIMA someone
else fitted, so a decomposition is never confused with an inference.
Layout. HodrickPrescottFilter, ButterworthFilter and
HamiltonFilter take a panel through filter;
BeveridgeNelsonDecomposition takes a fitted
ARIMA result through
compute; all four return DecompositionFilterResult, whose
_penalized_result classmethod is the shared path of the first two.
The numerics live in _core: _penalized_trend solves
\((I + \lambda D'D)\tau = y\) in banded form,
_butterworth_penalty and _penalty_cutoff_period convert between
weight and cutoff period, _hamilton_regression runs the one-column
OLS, _beveridge_nelson forms the companion-form forecast sum,
_METHOD_TITLES names the methods in summaries, and
validate_endog_matrix and validate_order guard the inputs.
_SummaryMixin from _internals gives the result its printed
form. The band-pass filters that isolate a cycle band rather than
remove a trend are in band_pass, and the
dating of the cycle those filters produce in
cycles.
References
Hodrick, R. J., & Prescott, E. C. (1997). Postwar U.S. business cycles: An empirical investigation. Journal of Money, Credit and Banking, 29(1), 1-16.
Ravn, M. O., & Uhlig, H. (2002). On adjusting the Hodrick-Prescott filter for the frequency of observations. Review of Economics and Statistics, 84(2), 371-376.
Hamilton, J. D. (2018). Why you should never use the Hodrick-Prescott filter. Review of Economics and Statistics, 100(5), 831-843.
Gomez, V. (2001). The use of Butterworth filters for trend and cycle estimation in economic time series. Journal of Business & Economic Statistics, 19(3), 365-373.
Beveridge, S., & Nelson, C. R. (1981). A new approach to decomposition of economic time series into permanent and transitory components. Journal of Monetary Economics, 7(2), 151-174.
Morley, J. C. (2002). A state-space approach to calculating the Beveridge-Nelson decomposition. Economics Letters, 75(1), 123-127.
Example
The same random walk through three definitions. HP finds a cycle larger than the increments and flags 80 of 200 rows as provisional; Hamilton loses eleven rows and reports the eight-step forecast error; Beveridge-Nelson, told the truth about the process, finds no cycle at all:
>>> import numpy as np
>>> from cultivars.univariate.box_jenkins import ARIMA
>>> rng = np.random.default_rng(0)
>>> y = np.cumsum(rng.standard_normal(200))
>>> hp = HodrickPrescottFilter().filter(y)
>>> round(float(hp.cycle.std() / np.diff(y).std()), 1), int(hp.provisional.sum())
(1.5, 80)
>>> ham = HamiltonFilter().filter(y)
>>> ham.offset, bool(abs(ham.cycle.std() / np.sqrt(8) - 1.0) < 0.1)
(11, True)
>>> bn = BeveridgeNelsonDecomposition(ARIMA(y, order=(0, 1, 0)).fit()).compute()
>>> float(np.abs(bn.cycle).max())
0.0
Classes#
The Beveridge-Nelson decomposition of a fitted ARIMA(p, 1, q). |
|
Gomez's (2001) Butterworth sine low-pass filter, stated by cutoff period and order. |
|
A trend-cycle decomposition of a panel, with the bookkeeping the method needs. |
|
Hamilton's (2018) regression filter. |
|
The Hodrick-Prescott filter, with Hamilton's critique on the result. |