LongMemorySV#

class cultivars.multivariate.structural.stochastic_volatility.LongMemorySV(endog, *, mean='constant', short_memory=False)[source]#

Long-memory stochastic volatility, Breidt, Crato, and de Lima (1998).

\[y_t = c + e^{h_t/2} \epsilon_t, \qquad h_t = \mu + v_t, \qquad (1 - \phi L)(1 - L)^d v_t = \eta_t,\]

the log variance is fractionally integrated, so its shocks decay hyperbolically – the persistence that squared and absolute returns show at long lags and that no finite-order AR(1) log variance can produce. Estimation is Whittle in the frequency domain, the natural home of a process with no finite state: the periodogram of \(\log (y_t - c)^2\) against the ARFIMA spectrum plus the \(\pi^2/2\) floor of \(\log \epsilon_t^2\), consistent for \((d, \sigma^2, \phi)\) and computed in one FFT. The price is a quasi-likelihood on the linearized model, and the summary says so. The constructor is inherited from _LongMemoryVolatilityModel.

Parameters:
  • endog (ArrayLike) – The observed series (returns, typically), at least 100 observations.

  • mean (str) – "constant" to remove the sample mean, "zero" to fix the observation mean at zero.

  • short_memory (bool) – Whether the log variance carries an AR(1) factor as well as the fractional one.

Raises:
Variables:
  • _endog – The validated series.

  • _mean_spec – "constant" or "zero".

  • _short_memory – Whether phi is estimated.

See also

References

Breidt, F. J., Crato, N., & de Lima, P. (1998). The detection and estimation of long memory in stochastic volatility. Journal of Econometrics, 83(1-2), 325-348.

Harvey, A. C., Ruiz, E., & Shephard, N. (1994). Multivariate stochastic variance models. Review of Economic Studies, 61(2), 247-264.

Example

Fractional noise with d = 0.4 in the log variance; the pure fractional law recovers it, and adding the short-memory factor lets the AR(1) absorb most of the persistence – d collapses toward zero while phi rises – with the likelihood-ratio test unable to separate the two:

>>> import numpy as np
>>> from cultivars.engine._core._transforms import _fractional_difference_weights
>>> rng = np.random.default_rng(0)
>>> n, burn = 1500, 2000
>>> eta = 0.5 * rng.standard_normal(n + burn)
>>> weights = _fractional_difference_weights(-0.4, n + burn)
>>> v = np.convolve(eta, weights)[burn : n + burn]
>>> y = np.exp((-1.0 + v) / 2) * rng.standard_normal(n)
>>> pure = LongMemorySV(y, mean="zero").fit()
>>> bool(0.2 < pure.d <= 0.5)
True
>>> mixed = LongMemorySV(y, mean="zero", short_memory=True).fit()
>>> round(mixed.d, 2), round(mixed.phi, 2), mixed.n_params
(0.01, 0.86, 3.0)
>>> bool(pure.likelihood_ratio_test(mixed).pvalue > 0.05)
True
>>> LongMemorySV(y, mean="median")
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: mean must be 'constant' or 'zero'; got 'median'.

Attributes#

endog

The validated endogenous series.

mean_spec

Whether the observation mean is removed or fixed at zero.

short_memory

Whether the log variance carries an AR(1) factor.

Methods#

fit()

Estimate by Whittle quasi-likelihood and smooth the log variance.