DecompositionFilterResult#

class cultivars.spectral.filters.DecompositionFilterResult(*, trend, cycle, method, offset, penalty=None, order=None, cutoff=None, horizon=None, lags=None, provisional=<factory>)[source]#

A trend-cycle decomposition of a panel, with the bookkeeping the method needs.

One container for four definitions of the trend. The penalized filters (Hodrick-Prescott, Butterworth) take the trend to be the minimizer of

\[\sum_t (y_t - \tau_t)^2 + \lambda \sum_t (\Delta^n \tau_t)^2,\]

a two-sided low-pass whose gain is one half at the period recorded in cutoff. Hamilton’s filter takes the trend to be the fitted value of the regression 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 \(h\) steps ahead. The Beveridge-Nelson decomposition takes the trend of an ARIMA(p, 1, q) to be the level its long-horizon forecast settles on net of drift,

\[\tau_t = y_t + \sum_{k \ge 1}\bigl(E_t \Delta y_{t+k} - \mu\bigr),\]

so the cycle is minus the forecastable momentum of the differences. Whatever the definition, trend + cycle reproduces the input over the rows kept, and the result records which rows are missing (offset) and which will change as data arrive (provisional).

The summary prints the cycle’s standard deviation per series, in levels and relative to the standard deviation of the input’s first difference, followed by the method’s own caveats: the HP and Butterworth notes say how many rows are provisional and restate Hamilton’s (2018) critique; the Hamilton note says the filter is one-sided; the Beveridge-Nelson note explains why its cycle is small.

Variables:
  • trend – (rows, k) trend component; the first row aligns with observation offset of the input.

  • cycle – (rows, k) cycle, the input minus the trend over the same rows.

  • method – "hodrick-prescott", "butterworth", "hamilton" or "beveridge-nelson".

  • offset – Input observations lost before the first row.

  • penalty – The smoothing weight of a penalized filter; None otherwise.

  • order – Differences penalized, or the ARMA (p, q) of a Beveridge-Nelson decomposition; None for Hamilton.

  • cutoff – Period at which a penalized filter’s gain is one half; None otherwise.

  • horizon – Hamilton’s forecast horizon; None otherwise.

  • lags – Hamilton’s regressors; None otherwise.

  • provisional – (rows,) flags marking rows a two-sided filter will revise as data arrive – the ends of a penalized filter, within cutoff observations of either edge; all False for the one-sided Hamilton and Beveridge-Nelson.

Note

The ratio the summary prints is the diagnostic Hamilton (2018) builds his case on. A random walk has no cycle, yet the HP cycle of a random walk has a standard deviation larger than that of its increments (about 1.5 times at the quarterly penalty), because the filter manufactures a smooth component from the level’s wandering. The same series through the Hamilton filter reports a cycle whose scale is the eight-step forecast error, which is what a random walk’s unpredictable component actually is. Neither number is wrong; they answer different questions, and the ratio makes the question visible.

provisional is a strong statement about the penalized filters: at HP’s quarterly 1600 the cutoff is 39.7 periods, so the first and last forty observations of any sample – ten years at each end of a fifty-year quarterly history – are flagged. When the sample is shorter than twice the cutoff every row is provisional.

See also

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.

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.

Example

>>> rng = np.random.default_rng(0)
>>> y = np.cumsum(rng.standard_normal(200))
>>> hp = HodrickPrescottFilter().filter(y)
>>> hp.method, hp.offset, hp.n_series, int(hp.provisional.sum())
('hodrick-prescott', 0, 1, 80)
>>> bool(np.allclose(hp.trend + hp.cycle, y[:, None]))
True

The random walk has no cycle; HP finds one larger than the increments, Hamilton reports the forecast error instead:

>>> round(float(hp.cycle.std() / np.diff(y).std()), 1)
1.5
>>> ham = HamiltonFilter().filter(y)
>>> ham.offset, ham.trend.shape, bool(ham.provisional.any())
(11, (189, 1), False)
>>> print(hp)
                   Hodrick-Prescott Trend-Cycle Decomposition
===...
Method:               hodrick-prescott  Rows:                              200
Penalty:                          1600  Cutoff period:                    39.7
Order:                               2
---...
             cycle sd   cycle sd / growth sd
series 1       1.4437                  1.498
===...
Two-sided; the 80 rows flagged `provisional` lie within the cutoff period of an
edge and will be revised as data arrive.
Hamilton (2018): ...

Attributes#

trend

(rows, k) trend component.

cycle

(rows, k) cycle, the input minus the trend.

method

Which definition of the trend produced the rows.

offset

Input observations lost before the first row.

penalty

Smoothing weight of a penalized filter; None otherwise.

order

Differences penalized, or the ARMA (p, q); None for Hamilton.

cutoff

Period at which a penalized filter's gain is one half; None otherwise.

horizon

Hamilton's forecast horizon; None otherwise.

lags

Hamilton's regressors; None otherwise.

provisional

(rows,) flags for rows a two-sided filter will revise.

n_series

Number of series filtered.

Methods#

summary()

The estimation summary, renderable as text, HTML, or a dataframe.