skfolio.optimization.StackingOptimization#

class skfolio.optimization.StackingOptimization(estimators, final_estimator=None, cv=None, quantile=0.5, quantile_measure=Sharpe Ratio, n_jobs=None, verbose=0, portfolio_params=None, fallback=None, previous_weights=None, raise_on_failure=True)[source]#

Stack of optimizations with a final optimization.

Stacking Optimization is an ensemble method that consists in stacking the output of individual portfolio optimizations with a final portfolio optimization.

The weights are the dot-product of individual optimizations weights with the final optimization weights.

Stacking allows to use the strength of each individual portfolio optimization by using their output as input of a final portfolio optimization.

To avoid data leakage, out-of-sample estimates are used to fit the outer optimization.

Note that estimators_ are fitted on the full X while final_estimator_ is trained using cross-validated predictions of the base estimators using cross_val_predict.

Parameters:
estimatorslist[tuple[str, BaseOptimization]]

Optimization estimators which will be stacked together. Each element of the list is defined as a tuple of string (i.e. name) and an optimization estimator.

final_estimatorBaseOptimization, optional

A final optimization estimator which will be used to combine the base estimators. The default (None) is to use MeanRisk.

cvBaseCrossValidator | BaseCombinatorialCV | int | “prefit” | “ignore”, optional

Determines the cross-validation splitting strategy used in cross_val_predict to train the final_estimator. The default (None) is to use the 5-fold cross validation KFold(). Possible inputs for cv are:

  • “ignore”: no cross-validation is used (note that it will likely lead to data leakage with a high risk of overfitting)

  • integer, to specify the number of folds in a KFold

  • An object to be used as a cross-validation generator

  • An iterable yielding train, test splits

  • “prefit” to assume the estimators are prefit, and skip cross validation

  • A CombinatorialPurgedCV

If a CombinatorialCV cross-validator is used, each cluster out-of-sample outputs becomes a collection of multiple paths instead of one single path. The selected out-of-sample path among this collection of paths is chosen according to the quantile and quantile_measure parameters.

If “prefit” is passed, it is assumed that all estimators have been fitted already. The final_estimator_ is trained on the estimators predictions on the full training set and are not cross validated predictions. Please note that if the models have been trained on the same data to train the stacking model, there is a very high risk of overfitting.

n_jobsint, optional

The number of jobs to run in parallel for fit of all estimators. The value -1 means using all processors. The default (None) means 1 unless in a joblib.parallel_backend context.

quantilefloat, default=0.5

Quantile for a given measure (quantile_measure) of the out-of-sample inner-estimator paths when the cv parameter is a CombinatorialPurgedCV cross-validator. The default value is 0.5 corresponding to the path with the median measure. (see cv)

quantile_measurePerfMeasure or RatioMeasure or RiskMeasure or ExtraRiskMeasure, default=RatioMeasure.SHARPE_RATIO

Measure used for the quantile path selection (see quantile and cv). The default is RatioMeasure.SHARPE_RATIO.

verboseint, default=0

The verbosity level. The default value is 0.

portfolio_paramsdict, optional

Portfolio parameters forwarded to the resulting Portfolio in predict. If not provided and if available on the estimator, the following attributes are propagated to the portfolio by default: name, transaction_costs, management_fees, previous_weights and risk_free_rate.

fallbackBaseOptimization | “previous_weights” | list[BaseOptimization | “previous_weights”], optional

Fallback estimator or a list of estimators to try, in order, when the primary optimization raises during fit. Alternatively, use "previous_weights" (alone or in a list) to fall back to the estimator’s previous_weights. When a fallback succeeds, its fitted weights_ are copied back to the primary estimator so that fit still returns the original instance. For traceability, fallback_ stores the successful estimator (or the string "previous_weights")

and fallback_chain_ stores each attempt with the associated outcome.

previous_weightsfloat | dict[str, float] | array-like of shape (n_assets,), optional

When fallback="previous_weights", failures will fall back to these weights if provided.

raise_on_failurebool, default=True

Controls error handling when fitting fails. If True, any failure during fit is raised immediately, no weights_ are set and subsequent calls to predict will raise a NotFittedError. If False, errors are not raised; instead, a warning is emitted, weights_ is set to None and subsequent calls to predict will return a FailedPortfolio. When fallbacks are specified, this behavior applies only after all fallbacks have been exhausted.

Attributes:
weights_ndarray of shape (n_assets,)

Weights of the assets.

estimators_list[BaseOptimization]

The elements of the estimators parameter, having been fitted on the training data. When cv="prefit", estimators_ is set to estimators and is not fitted again.

named_estimators_dict[str, BaseOptimization]

Attribute to access any fitted sub-estimators by name.

final_estimator_BaseOptimization

The fitted final_estimator.

n_features_in_int

Number of assets seen during fit.

feature_names_in_ndarray of shape (n_features_in_,)

Names of assets seen during fit. Defined only when X has assets names that are all strings.

fallback_BaseOptimization | “previous_weights” | None

The fallback estimator instance, or the string "previous_weights", that produced the final result. None if no fallback was used.

fallback_chain_list[tuple[str, str]] | None

Sequence describing the optimization fallback attempts. Each element is a pair (estimator_repr, outcome) where estimator_repr is the string representation of the primary estimator or a fallback (e.g. "EqualWeighted()", "previous_weights"), and outcome is "success" if that step produced a valid solution, otherwise the stringified error message. For successful fits without any fallback, this is None.

error_str | list[str] | None

Captured error message(s) when fit fails. For multi-portfolio outputs (weights_ is 2D), this is a list aligned with portfolios.

Methods

fit(X[, y])

Fit the Stacking Optimization estimator.

fit_predict(X)

Perform fit on X and returns the predicted Portfolio or Population of Portfolio on X based on the fitted weights.

get_metadata_routing()

Get metadata routing of this object.

get_params([deep])

Get the parameters of an estimator from the ensemble.

predict(X)

Predict the Portfolio or a Population of portfolios on X.

score(X[, y])

Prediction score using the Sharpe Ratio.

set_params(**params)

Set the parameters of an estimator from the ensemble.

Notes

All estimators should specify all parameters as explicit keyword arguments in __init__ (no *args or **kwargs), following scikit-learn conventions.

fit(X, y=None, **fit_params)[source]#

Fit the Stacking Optimization estimator.

Parameters:
Xarray-like of shape (n_observations, n_assets)

Price returns of the assets.

yarray-like of shape (n_observations, n_targets), optional

Price returns of factors or a target benchmark. The default is None.

**fit_paramsdict

Parameters to pass to the underlying estimators. Only available if enable_metadata_routing=True, which can be set by using sklearn.set_config(enable_metadata_routing=True). See Metadata Routing User Guide for more details.

Returns:
selfStackingOptimization

Fitted estimator.

fit_predict(X)#

Perform fit on X and returns the predicted Portfolio or Population of Portfolio on X based on the fitted weights. For factor models, use fit(X, y) then predict(X) separately.

If fitting fails and raise_on_failure=False, this returns a FailedPortfolio.

Parameters:
Xarray-like of shape (n_observations, n_assets)

Price returns of the assets.

Returns:
Portfolio | Population

The predicted Portfolio or Population based on the fitted weights.

get_metadata_routing()[source]#

Get metadata routing of this object.

Please check User Guide on how the routing mechanism works.

Returns:
routingMetadataRequest

A MetadataRequest encapsulating routing information.

get_params(deep=True)[source]#

Get the parameters of an estimator from the ensemble.

Returns the parameters given in the constructor as well as the estimators contained within the estimators parameter.

Parameters:
deepbool, default=True

Setting it to True gets the various estimators and the parameters of the estimators as well.

Returns:
paramsdict

Parameter and estimator names mapped to their values or parameter names mapped to their values.

property named_estimators#

Dictionary to access any fitted sub-estimators by name.

Returns:
Bunch
property needs_previous_weights#

Whether previous_weights must be propagated between folds/rebalances.

Used by cross_val_predict to decide whether to run sequentially and pass the weights from the previous rebalancing to the next. This is True when transaction costs, a maximum turnover, or a fallback depending on previous_weights are present.

predict(X)#

Predict the Portfolio or a Population of portfolios on X.

Optimization estimators can return a 1D or a 2D array of weights. For a 1D array, the prediction is a single Portfolio. For a 2D array, the prediction is a Population of Portfolio.

If name is not provided in the portfolio parameters, the estimator class name is used.

Parameters:
Xarray-like of shape (n_observations, n_assets) | ReturnDistribution

Asset returns or a ReturnDistribution carrying returns and optional sample weights.

Returns:
Portfolio | Population

The predicted Portfolio or Population based on the fitted weights.

score(X, y=None)#

Prediction score using the Sharpe Ratio. If the prediction is a single Portfolio, the score is its Sharpe Ratio. If the prediction is a Population, the score is the mean Sharpe Ratio across portfolios.

Parameters:
Xarray-like of shape (n_observations, n_assets)

Price returns of the assets.

yIgnored

Not used, present here for API consistency by convention.

Returns:
scorefloat

The Sharpe Ratio of the portfolio if the prediction is a single Portfolio or the mean of all the portfolios Sharpe Ratios if the prediction is a Population of Portfolio.

set_params(**params)[source]#

Set the parameters of an estimator from the ensemble.

Valid parameter keys can be listed with get_params(). Note that you can directly set the parameters of the estimators contained in estimators.

Parameters:
**paramskeyword arguments

Specific parameters using e.g. set_params(parameter_name=new_value). In addition, to setting the parameters of the estimator, the individual estimator of the estimators can also be set, or can be removed by setting them to ‘drop’.

Returns:
selfobject

Estimator instance.