Migration Guide#
skfolio follows semantic versioning. The public API remains
backward compatible within a major series. Deprecated functionality raises a
FutureWarning and is removed in the next major release.
This page documents the changes required to upgrade between major versions.
Preparing for 2.0#
The following deprecated APIs remain available throughout 1.x and will be removed in 2.0. Their replacements are available now.
Hierarchical Optimizer Imports#
Import HRP, HERC, Schur Complementary and NCO from skfolio.optimization or
skfolio.optimization.hierarchical:
from skfolio.cluster import HierarchicalClustering
from skfolio.optimization.hierarchical import (
HierarchicalEqualRiskContribution,
HierarchicalRiskParity,
NestedClustersOptimization,
SchurComplementary,
)
Imports from skfolio.optimization.cluster and
skfolio.optimization.cluster.hierarchical raise a FutureWarning and return
the same estimator classes. The skfolio.cluster module for clustering
estimators is unchanged.
HRP and Schur Ordering#
Configure hierarchical clustering through HierarchicalSeriation
on HRP and Schur Complementary.
Before:
model = HierarchicalRiskParity(
hierarchical_clustering_estimator=HierarchicalClustering()
)
After:
from skfolio.cluster import HierarchicalClustering
from skfolio.seriation import HierarchicalSeriation
model = HierarchicalRiskParity(
seriation_estimator=HierarchicalSeriation(
hierarchical_clustering_estimator=HierarchicalClustering()
)
)
The old parameter warns during fit or the first partial_fit of a learning
run. Supplying both estimators raises an error. The default ordering is unchanged.
After fitting, access the clustering estimator through
model.seriation_estimator_.hierarchical_clustering_estimator_. The old
model.hierarchical_clustering_estimator_ attribute raises a FutureWarning.
This alias is only available when the fitted seriator is hierarchical.
HERC’s hierarchical_clustering_estimator and NCO’s clustering_estimator
remain supported.
Custom Hierarchical Optimizers#
BaseHierarchicalOptimization is deprecated. Existing custom subclasses remain
supported throughout 1.x.
HRP, HERC and Schur Complementary no longer inherit from this base.
isinstance and issubclass checks against BaseHierarchicalOptimization
now return False for these estimators. Use BaseOptimization to recognize
portfolio optimizers generally, or a tuple of concrete optimizer classes to
recognize a specific family.
For new custom optimizers, inherit from
BaseOptimization and implement fit to set
weights_. When migrating an existing subclass, provide any risk calculations
and bound conversion previously inherited through _risk, _unitary_risks
and _convert_weights_bounds. The private seriation base and risk mixin are
implementation details, not supported replacements for the public base.
Migrating to 1.0#
Version 1.0 introduces the stable public API. The parameters and aliases deprecated during the 0.x series are removed in this release.
Exponentially Weighted Moments#
EWMu and EWCovariance no longer
accept alpha. Use half_life, the number of observations for a weight to decay
to 50%.
Before:
from skfolio.moments import EWCovariance, EWMu
EWMu(alpha=0.2)
EWCovariance(alpha=0.2)
After:
EWMu(half_life=3.11)
EWCovariance(half_life=3.11)
The half-life equivalent of a given alpha is
For example, alpha=0.2 corresponds to a half_life of approximately \(3.11\)
and alpha=0.02 to \(34.31\). The decay factor is
\(\lambda = 2^{-1/\text{half-life}}\), computed by
half_life_to_decay_factor.
Passing alpha raises a TypeError.
Walk-Forward Cross-Validation#
WalkForward no longer accepts expend_train. Use
expand_train, which has identical behavior.
Before:
from skfolio.model_selection import WalkForward
WalkForward(test_size=60, train_size=252, expend_train=True)
After:
WalkForward(test_size=60, train_size=252, expand_train=True)
Factor Models#
The FactorModel prior estimator is replaced by
TimeSeriesFactorModel, and factors is now a keyword-only
argument of fit.
Before:
from skfolio.optimization import MeanRisk
from skfolio.prior import FactorModel
model = MeanRisk(prior_estimator=FactorModel())
model.fit(X_train, y_train)
After:
from skfolio.optimization import MeanRisk
from skfolio.prior import TimeSeriesFactorModel
from skfolio.datasets import load_sp500_dataset, load_factors_dataset
from skfolio.preprocessing import prices_to_returns
X, factors = prices_to_returns(load_sp500_dataset(), load_factors_dataset())
X_train, factors_train = X.iloc[:252], factors.iloc[:252]
model = MeanRisk(prior_estimator=TimeSeriesFactorModel())
model.fit(X_train, factors=factors_train)
Warning
FactorModel now refers to a different object: the fitted factor model container
exposed on factor_model, holding the
loading matrix, the factor and idiosyncratic moments, and the realized factor
returns. The import therefore still resolves, and estimator arguments passed to
FactorModel raise a TypeError for unexpected keyword arguments rather than an
ImportError.
CharacteristicsFactorModel provides a cross-sectional
alternative, fitted from point-in-time asset characteristics rather than factor return
time series. See Factor Models.
Uncertainty Sets#
UncertaintySet now describes a general norm-ball
rather than an ellipsoid, which allows box and diamond sets to use the same
representation. The ellipsoid is the \(p = 2\) case.
The field names changed as follows:
Before |
After |
Description |
|---|---|---|
|
|
Size \(\kappa\) of the normalized uncertainty ball. |
|
|
Linear map \(L\) with \(S = L L^{T}\) for an ellipsoid with shape matrix \(S\). May be low-rank. |
not applicable |
|
Norm \(p\) selecting the shape, defaulting to \(2\) for an ellipsoid. |
This only affects code that constructs an UncertaintySet directly or reads the fitted
uncertainty_set_ attribute. Passing an uncertainty set estimator to
MeanRisk is unchanged.
Two factor-model estimators are added:
OrthogonalMuUncertaintySet and
OrthogonalCovarianceUncertaintySet. See
Uncertainty Set.
Scheduled for Removal in 2.0#
The following remain available throughout 1.x and raise a FutureWarning:
annualized_factor, onPortfolioandImpliedCovariance. Useannualization_factor.non_denominated_sort, as a function and as aPopulationmethod. Usenon_dominated_sort.