DynamicNelsonSiegel.fit#

DynamicNelsonSiegel.fit()[source]#

Maximize the exact likelihood from the two-step warm start.

Builds the _NelsonSiegelObjective, maximizes it with the package’s likelihood driver, rebuilds the linear-Gaussian system at the optimum, smooths the panel for the factor paths, and packs the result; n_params is the length of the flat parameter vector, so it counts the decay only when it was free.

Return type:

DynamicNelsonSiegelResult

Returns:

A DynamicNelsonSiegelResult.

Example

Held at 0.6 the decay costs no parameter; left free it is recovered near the truth and costs one:

>>> import numpy as np
>>> from cultivars.engine._core._polynomials import _nelson_siegel_loadings
>>> rng = np.random.default_rng(0)
>>> taus = np.array([0.5, 2.0, 5.0, 10.0])
>>> basis = _nelson_siegel_loadings(taus, 0.6)
>>> mu = np.array([5.0, -1.5, 0.5])
>>> f = np.tile(mu, (40, 1))
>>> for t in range(1, 40):
...     f[t] = mu + 0.9 * (f[t - 1] - mu) + 0.2 * rng.standard_normal(3)
>>> curves = f @ basis.T + 0.05 * rng.standard_normal((40, 4))
>>> fixed = DynamicNelsonSiegel(curves, taus, decay=0.6).fit()
>>> free = DynamicNelsonSiegel(curves, taus).fit()
>>> fixed.n_params, free.n_params, bool(free.llf >= fixed.llf - 1e-6)
(16.0, 17.0, True)
>>> bool(0.3 < free.decay < 1.2), free.decay_fixed
(True, False)