Skip to content

moments

optimizer.moments

Moment estimation and prior construction.

CovEstimatorType

Bases: str, Enum

Covariance estimator selection.

MomentEstimationConfig dataclass

Immutable configuration for moment estimation and prior construction.

All parameters map 1:1 to skfolio estimator constructor arguments, making the config serialisable and suitable for hyperparameter sweeps.

Parameters

mu_estimator : MuEstimatorType Which expected return estimator to use. shrinkage_method : ShrinkageMethod Shrinkage flavour when mu_estimator is SHRUNK. ew_mu_alpha : float Exponential weighting decay for EWMu. risk_aversion : float Risk-aversion coefficient for EquilibriumMu. cov_estimator : CovEstimatorType Which covariance estimator to use. ew_cov_alpha : float Exponential weighting decay for EWCovariance. shrunk_cov_shrinkage : float Shrinkage intensity for ShrunkCovariance. gerber_threshold : float Threshold for GerberCovariance. is_log_normal : bool Whether returns are log-normal (for multi-period scaling in EmpiricalPrior). investment_horizon : float or None Investment horizon forwarded to EmpiricalPrior. use_factor_model : bool If True, wrap the prior in a FactorModel. residual_variance : bool Whether to include residual variance in FactorModel.

for_equilibrium_ledoitwolf() classmethod

Black-Litterman-ready prior: EquilibriumMu + LedoitWolf.

for_shrunk_denoised() classmethod

Conservative prior: ShrunkMu (James-Stein) + DenoiseCovariance.

for_adaptive() classmethod

Responsive prior: EW on both mu and covariance.

for_hmm_blended(n_states=2) classmethod

HMM-blended prior: regime-probability-weighted mu and covariance.

MuEstimatorType

Bases: str, Enum

Expected return estimator selection.

ShrinkageMethod

Bases: str, Enum

Shrinkage method for :class:ShrunkMu.

Maps to :class:skfolio.moments.expected_returns._shrunk_mu.ShrunkMuMethods.

HMMBlendedCovariance

Bases: BaseCovariance

Covariance estimator that blends regime covariances via HMM.

Fits a Gaussian HMM with :func:fit_hmm and computes the blended covariance matrix using the full law of total variance formula::

Σ = Σ_s p(z_T=s | r_{1:T}) · [Σ_s + (μ_s - μ)(μ_s - μ)ᵀ]

The second term (μ_s - μ)(μ_s - μ)ᵀ is the cross-state mean dispersion contribution, which the simpler blend in :func:blend_moments_by_regime omits.

Conforms to the skfolio BaseCovariance API: exposes covariance_ (ndarray of shape (n_assets, n_assets)) after fit.

Parameters

hmm_config : HMMConfig or None, default=None HMM hyper-parameters. None falls back to HMMConfig(). nearest : bool, default=True Project the blended covariance to the nearest positive-definite matrix if it is not already PSD. higham : bool, default=False Use the Higham (2002) algorithm for the PSD projection instead of eigenvalue clipping. higham_max_iteration : int, default=100 Maximum iterations for the Higham algorithm.

Attributes

covariance_ : ndarray of shape (n_assets, n_assets) Blended covariance matrix (with mean-dispersion term). hmm_result_ : HMMResult The fitted HMM result. n_features_in_ : int Number of assets seen during fit. feature_names_in_ : ndarray of shape (n_features_in_,) Asset names seen during fit (only when input is a DataFrame with string column names).

fit(X, y=None)

Fit the HMM and compute the blended covariance matrix.

Parameters

X : array-like of shape (n_observations, n_assets) Linear returns of the assets. y : ignored

Returns

self

HMMBlendedMu

Bases: BaseMu

Expected-return estimator that blends regime-conditional means via HMM.

Fits a Gaussian HMM with :func:fit_hmm and computes the probability-weighted blended expected return vector::

μ = Σ_s p(z_T=s | r_{1:T}) · μ_s

where the weights are the smoothed posterior at the final observation.

Conforms to the skfolio BaseMu API: exposes mu_ (ndarray of shape (n_assets,)) after fit.

Parameters

hmm_config : HMMConfig or None, default=None HMM hyper-parameters. None falls back to HMMConfig() (2 states, full covariance, 100 EM iterations).

Attributes

mu_ : ndarray of shape (n_assets,) Probability-weighted blended expected return vector. hmm_result_ : HMMResult The fitted HMM result (for inspection or downstream use). n_features_in_ : int Number of assets seen during fit. feature_names_in_ : ndarray of shape (n_features_in_,) Asset names seen during fit (only when input is a DataFrame with string column names).

fit(X, y=None)

Fit the HMM and compute the blended expected return vector.

Parameters

X : array-like of shape (n_observations, n_assets) Linear returns of the assets. y : ignored

Returns

self

HMMConfig dataclass

Configuration for the Gaussian HMM.

Attributes

n_states : int Number of latent regimes (hidden states). n_iter : int Maximum number of Baum-Welch EM iterations. tol : float Convergence tolerance on log-likelihood improvement. covariance_type : str Covariance structure: "full", "diag", "tied", or "spherical". random_state : int or None Seed for reproducible initialisation.

HMMResult dataclass

Result of fitting a Gaussian HMM to return data.

Attributes

transition_matrix : ndarray, shape (n_states, n_states) Row-stochastic transition probability matrix A[i, j] = P(z_t=j | z_{t-1}=i). regime_means : pd.DataFrame, shape (n_states, n_assets) Per-regime mean return vectors. Index is integer state label (0, 1, ..., n_states-1); columns are asset tickers. regime_covariances : ndarray, shape (n_states, n_assets, n_assets) Per-regime covariance matrices. Axis-0 indexes the state. filtered_probs : pd.DataFrame, shape (n_dates, n_states) Forward-only filtered state probabilities α_t(s) ∝ P(r_t | z_t=s) · Σ_{s'} A[s', s] · α_{t-1}(s'), conditioned only on past and current observations r_{1:t}. These are causal (no look-ahead bias) and suitable for online blending in backtests. Rows sum to 1.0. smoothed_probs : pd.DataFrame, shape (n_dates, n_states) Baum-Welch smoothed posterior probabilities γ_t(s) = P(z_t=s | r_{1:T}) conditioned on the entire sequence. Use for diagnostics and regime labeling, but NOT for causal blending in backtests. log_likelihood : float Log-likelihood of the data under the fitted model.

DMMConfig dataclass

Hyper-parameters for the Deep Markov Model.

Attributes

z_dim : int Dimension of the continuous latent state z_t. emission_dim : int Hidden layer size of the Emitter MLP. transition_dim : int Hidden layer size of the GatedTransition MLP. rnn_dim : int GRU hidden state size for the backward inference network. num_epochs : int Number of SVI training epochs. learning_rate : float Initial learning rate for ClippedAdam. annealing_epochs : int Epochs over which the KL weight is linearly annealed from minimum_annealing_factor to 1.0. minimum_annealing_factor : float Starting KL annealing weight (prevents posterior collapse). random_state : int or None Seed for reproducible initialisation.

DMMResult dataclass

Result of fitting a Deep Markov Model.

Attributes

latent_means : pd.DataFrame, shape (T, z_dim) Variational posterior means for each time step. latent_stds : pd.DataFrame, shape (T, z_dim) Variational posterior standard deviations. elbo_history : list[float] ELBO value (= −SVI loss) per training epoch. model : Any Trained DMM nn.Module instance. tickers : list[str] Asset names, in training order. input_mean : ndarray, shape (n_assets,) Per-asset mean used for input standardisation. input_std : ndarray, shape (n_assets,) Per-asset std used for input standardisation.

build_cov_estimator(config)

Build a skfolio covariance estimator from config.

Parameters

config : MomentEstimationConfig Moment estimation configuration.

Returns

BaseCovariance A fitted-ready skfolio covariance estimator.

build_mu_estimator(config)

Build a skfolio expected return estimator from config.

Parameters

config : MomentEstimationConfig Moment estimation configuration.

Returns

BaseMu A fitted-ready skfolio expected return estimator.

build_prior(config=None)

Build a complete prior estimator from config.

Composes expected return and covariance estimators into an EmpiricalPrior, optionally wrapping it in a FactorModel when config.use_factor_model is True.

Parameters

config : MomentEstimationConfig or None Moment estimation configuration. Defaults to MomentEstimationConfig() (EmpiricalMu + LedoitWolf).

Returns

BasePrior A fitted-ready skfolio prior estimator.

blend_moments_by_regime(result)

Compute probability-weighted moments from the last filtered time step.

Uses the smoothed posterior at the final observation γ_T(s) to produce a single blended expected-return vector and covariance matrix:

μ = Σ_s γ_T(s) · μ_s
Σ = Σ_s γ_T(s) · Σ_s
Parameters

result : HMMResult Output of :func:fit_hmm.

Returns

tuple[pd.Series, pd.DataFrame] (mu, cov) — blended expected returns (indexed by ticker) and blended covariance matrix (tickers × tickers).

Notes

This function computes only the within-regime weighted covariance Σ = Σ_s γ(s) · Σ_s and omits the cross-state mean-dispersion term Σ_s γ(s) · (μ_s − μ)(μ_s − μ)ᵀ from the full law of total variance. As a result, the blended covariance will under-estimate total uncertainty when regime means differ materially.

For optimizer inputs that require the full variance decomposition, use :class:HMMBlendedCovariance instead, which includes both the within-regime and between-regime components.

fit_hmm(returns, config=None)

Fit a Gaussian HMM to a panel of asset returns.

Uses the Baum-Welch (EM) algorithm implemented by hmmlearn to estimate the transition matrix, regime-conditional means and covariances, and the smoothed filtered probabilities.

Parameters

returns : pd.DataFrame Dates × assets matrix of linear returns. Rows with any NaN are dropped before fitting. config : HMMConfig or None Model hyper-parameters. Defaults to HMMConfig() (2 states, full covariance, 100 EM iterations).

Returns

HMMResult Fitted HMM parameters and smoothed state probabilities.

Raises

ValueError If fewer than 2 assets or fewer than n_states + 1 observations remain after dropping NaN rows.

select_hmm_n_states(returns, candidate_n_states=(2, 3, 4), criterion='bic', hmm_config=None)

Select the optimal number of HMM states via AIC or BIC.

For each candidate state count, fits an HMM via :func:fit_hmm and computes the information criterion. Returns the candidate that minimises the chosen criterion.

Free parameters per state count S with d assets::

k = S*(S-1) + S*d + S*d*(d+1)//2

where the three terms correspond to transition matrix rows (each row sums to 1, so S-1 free per row), per-regime means, and per-regime full covariance (lower triangle).

Parameters

returns : pd.DataFrame Dates x assets matrix of linear returns. candidate_n_states : Sequence[int] State counts to evaluate (default (2, 3, 4)). criterion : str "aic" or "bic" (default "bic"). hmm_config : HMMConfig or None Base HMM config. n_states is overridden per candidate.

Returns

int The state count that minimises the chosen criterion.

Raises

ValueError If criterion is not "aic" or "bic". DataError If no candidate succeeds.

apply_lognormal_correction(mu, cov, horizon, method='exact')

Scale daily log-return moments to a multi-period horizon.

Expected return (Jensen's inequality correction, same for both methods):

.. math::

E[R_T] = \exp(\mu T + \tfrac{1}{2}\,\mathrm{diag}(\Sigma) T) - 1

Covariance — method="exact" (exact log-normal result):

.. math::

\mathrm{Cov}[R_T^i, R_T^j]
= \exp\!\bigl((\mu_i + \mu_j)T
  + \tfrac{1}{2}(\sigma_i^2 + \sigma_j^2)T\bigr)
  \cdot \bigl(\exp(\sigma_{ij}\,T) - 1\bigr)

Covariance — method="linear" (delta-method approximation):

.. math::

\Sigma_T \approx \Sigma \cdot T
Parameters

mu : pd.Series Daily log-return expected values, indexed by asset ticker. cov : pd.DataFrame Daily log-return covariance matrix. Must be square and share the same index/columns as mu. horizon : int Investment horizon in trading days (e.g. 21 for monthly, 63 for quarterly, 252 for annual). method : {"exact", "linear"}, default "exact" Covariance scaling method. "exact" applies the full log-normal formula; "linear" uses the simpler Sigma * T approximation (retained for backwards compatibility).

Returns

tuple[pd.Series, pd.DataFrame] (mu_T, cov_T) — horizon-scaled expected returns and covariance.

Raises

ValueError If horizon is not a positive integer, if mu and cov do not share the same ticker index, or if method is not recognised.

scale_moments_to_horizon(mu, cov, daily_horizon, method='exact')

Validate inputs and apply the log-normal moment correction.

A higher-level wrapper around :func:apply_lognormal_correction that validates array shapes and non-negativity of the covariance diagonal before delegating to the core scaling function.

Parameters

mu : pd.Series Daily log-return expected values, indexed by asset ticker. cov : pd.DataFrame Daily log-return covariance matrix. daily_horizon : int Investment horizon in trading days. method : {"exact", "linear"}, default "exact" Covariance scaling method. See :func:apply_lognormal_correction.

Returns

tuple[pd.Series, pd.DataFrame] (mu_T, cov_T) — horizon-scaled expected returns and covariance.

Raises

ValueError If inputs are not aligned, the covariance matrix is not square, the diagonal contains negative values, or daily_horizon < 1.

blend_moments_dmm(result, n_mc_samples=500, seed=None)

Project the last latent state through the generative model via MC sampling.

Draws n_mc_samples from the variational posterior q(z_T), propagates each through the transition p(z_{T+1} | z_T) and emission p(x_{T+1} | z_{T+1}), then applies the law of total variance to produce the blended mean and covariance.

Parameters

result : DMMResult Output of :func:fit_dmm. n_mc_samples : int, default=500 Number of Monte Carlo samples for posterior-predictive estimation. seed : int or None, default=None Random seed for reproducibility.

Returns

tuple[pd.Series, pd.DataFrame] (mu, cov) — expected returns and covariance matrix in the original (un-standardised) return scale.

fit_dmm(returns, config=None)

Fit a Deep Markov Model to a panel of asset returns.

Uses Pyro SVI with ClippedAdam and KL annealing. Input returns are standardised to zero mean / unit variance per asset before fitting.

Parameters

returns : pd.DataFrame Dates × assets matrix of linear returns. NaN rows are dropped. config : DMMConfig or None Model hyper-parameters. Defaults to DMMConfig().

Returns

DMMResult