skfolio 0.7.0__py3-none-any.whl → 0.8.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- skfolio/__init__.py +2 -2
- skfolio/cluster/__init__.py +1 -1
- skfolio/cluster/_hierarchical.py +1 -1
- skfolio/datasets/__init__.py +1 -1
- skfolio/datasets/_base.py +2 -2
- skfolio/datasets/data/__init__.py +1 -0
- skfolio/distance/__init__.py +1 -1
- skfolio/distance/_base.py +2 -2
- skfolio/distance/_distance.py +4 -4
- skfolio/distribution/__init__.py +56 -0
- skfolio/distribution/_base.py +203 -0
- skfolio/distribution/copula/__init__.py +35 -0
- skfolio/distribution/copula/_base.py +456 -0
- skfolio/distribution/copula/_clayton.py +539 -0
- skfolio/distribution/copula/_gaussian.py +407 -0
- skfolio/distribution/copula/_gumbel.py +560 -0
- skfolio/distribution/copula/_independent.py +196 -0
- skfolio/distribution/copula/_joe.py +609 -0
- skfolio/distribution/copula/_selection.py +111 -0
- skfolio/distribution/copula/_student_t.py +486 -0
- skfolio/distribution/copula/_utils.py +509 -0
- skfolio/distribution/multivariate/__init__.py +11 -0
- skfolio/distribution/multivariate/_base.py +241 -0
- skfolio/distribution/multivariate/_utils.py +632 -0
- skfolio/distribution/multivariate/_vine_copula.py +1254 -0
- skfolio/distribution/univariate/__init__.py +19 -0
- skfolio/distribution/univariate/_base.py +308 -0
- skfolio/distribution/univariate/_gaussian.py +136 -0
- skfolio/distribution/univariate/_johnson_su.py +152 -0
- skfolio/distribution/univariate/_normal_inverse_gaussian.py +153 -0
- skfolio/distribution/univariate/_selection.py +85 -0
- skfolio/distribution/univariate/_student_t.py +144 -0
- skfolio/exceptions.py +6 -6
- skfolio/measures/__init__.py +1 -1
- skfolio/measures/_enums.py +7 -7
- skfolio/measures/_measures.py +4 -7
- skfolio/metrics/__init__.py +2 -0
- skfolio/metrics/_scorer.py +4 -4
- skfolio/model_selection/__init__.py +2 -2
- skfolio/model_selection/_combinatorial.py +15 -12
- skfolio/model_selection/_validation.py +2 -2
- skfolio/model_selection/_walk_forward.py +3 -3
- skfolio/moments/covariance/_base.py +1 -1
- skfolio/moments/covariance/_denoise_covariance.py +1 -1
- skfolio/moments/covariance/_detone_covariance.py +1 -1
- skfolio/moments/covariance/_empirical_covariance.py +1 -1
- skfolio/moments/covariance/_ew_covariance.py +1 -1
- skfolio/moments/covariance/_gerber_covariance.py +1 -1
- skfolio/moments/covariance/_graphical_lasso_cv.py +1 -1
- skfolio/moments/covariance/_implied_covariance.py +2 -7
- skfolio/moments/covariance/_ledoit_wolf.py +1 -1
- skfolio/moments/covariance/_oas.py +1 -1
- skfolio/moments/covariance/_shrunk_covariance.py +1 -1
- skfolio/moments/expected_returns/_base.py +1 -1
- skfolio/moments/expected_returns/_empirical_mu.py +1 -1
- skfolio/moments/expected_returns/_equilibrium_mu.py +1 -1
- skfolio/moments/expected_returns/_ew_mu.py +1 -1
- skfolio/moments/expected_returns/_shrunk_mu.py +2 -2
- skfolio/optimization/__init__.py +2 -0
- skfolio/optimization/_base.py +2 -2
- skfolio/optimization/cluster/__init__.py +2 -0
- skfolio/optimization/cluster/_nco.py +7 -7
- skfolio/optimization/cluster/hierarchical/__init__.py +2 -0
- skfolio/optimization/cluster/hierarchical/_base.py +1 -2
- skfolio/optimization/cluster/hierarchical/_herc.py +2 -2
- skfolio/optimization/cluster/hierarchical/_hrp.py +2 -2
- skfolio/optimization/convex/__init__.py +2 -0
- skfolio/optimization/convex/_base.py +8 -8
- skfolio/optimization/convex/_distributionally_robust.py +4 -4
- skfolio/optimization/convex/_maximum_diversification.py +5 -5
- skfolio/optimization/convex/_mean_risk.py +5 -6
- skfolio/optimization/convex/_risk_budgeting.py +3 -3
- skfolio/optimization/ensemble/__init__.py +2 -0
- skfolio/optimization/ensemble/_base.py +2 -2
- skfolio/optimization/ensemble/_stacking.py +1 -1
- skfolio/optimization/naive/__init__.py +2 -0
- skfolio/optimization/naive/_naive.py +1 -1
- skfolio/population/__init__.py +2 -0
- skfolio/population/_population.py +35 -9
- skfolio/portfolio/_base.py +42 -8
- skfolio/portfolio/_multi_period_portfolio.py +3 -2
- skfolio/portfolio/_portfolio.py +4 -4
- skfolio/pre_selection/__init__.py +2 -0
- skfolio/pre_selection/_drop_correlated.py +2 -2
- skfolio/pre_selection/_select_complete.py +25 -26
- skfolio/pre_selection/_select_k_extremes.py +2 -2
- skfolio/pre_selection/_select_non_dominated.py +2 -2
- skfolio/pre_selection/_select_non_expiring.py +2 -2
- skfolio/preprocessing/__init__.py +2 -0
- skfolio/preprocessing/_returns.py +2 -2
- skfolio/prior/__init__.py +4 -0
- skfolio/prior/_base.py +2 -2
- skfolio/prior/_black_litterman.py +5 -3
- skfolio/prior/_empirical.py +3 -1
- skfolio/prior/_factor_model.py +8 -4
- skfolio/prior/_synthetic_data.py +239 -0
- skfolio/synthetic_returns/__init__.py +1 -0
- skfolio/typing.py +1 -1
- skfolio/uncertainty_set/__init__.py +2 -0
- skfolio/uncertainty_set/_base.py +2 -2
- skfolio/uncertainty_set/_bootstrap.py +1 -1
- skfolio/uncertainty_set/_empirical.py +1 -1
- skfolio/utils/__init__.py +1 -0
- skfolio/utils/bootstrap.py +2 -2
- skfolio/utils/equations.py +13 -10
- skfolio/utils/sorting.py +2 -2
- skfolio/utils/stats.py +7 -7
- skfolio/utils/tools.py +76 -12
- {skfolio-0.7.0.dist-info → skfolio-0.8.1.dist-info}/METADATA +99 -24
- skfolio-0.8.1.dist-info/RECORD +120 -0
- {skfolio-0.7.0.dist-info → skfolio-0.8.1.dist-info}/WHEEL +1 -1
- skfolio-0.7.0.dist-info/RECORD +0 -95
- {skfolio-0.7.0.dist-info → skfolio-0.8.1.dist-info/licenses}/LICENSE +0 -0
- {skfolio-0.7.0.dist-info → skfolio-0.8.1.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-portfolio, Copyright (c) 2022, Carlo Nicolini, Licensed under MIT Licence.
|
8
8
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
@@ -26,7 +26,7 @@ from skfolio.utils.tools import fit_and_predict, safe_split
|
|
26
26
|
|
27
27
|
def _routing_enabled():
|
28
28
|
"""Return whether metadata routing is enabled.
|
29
|
-
Returns
|
29
|
+
Returns.
|
30
30
|
-------
|
31
31
|
enabled : bool
|
32
32
|
Whether metadata routing is enabled. If the config is not set, it
|
@@ -1,8 +1,8 @@
|
|
1
|
-
"""Walk Forward cross-validator"""
|
1
|
+
"""Walk Forward cross-validator."""
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-portfolio, Copyright (c) 2022, Carlo Nicolini, Licensed under MIT Licence.
|
8
8
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
@@ -273,7 +273,7 @@ class WalkForward(sks.BaseCrossValidator):
|
|
273
273
|
)
|
274
274
|
|
275
275
|
def get_n_splits(self, X=None, y=None, groups=None) -> int:
|
276
|
-
"""
|
276
|
+
"""Return the number of splitting iterations in the cross-validator.
|
277
277
|
|
278
278
|
Parameters
|
279
279
|
----------
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -286,11 +286,7 @@ class ImpliedCovariance(BaseCovariance):
|
|
286
286
|
n_assets=n_assets,
|
287
287
|
fill_value=np.nan,
|
288
288
|
dim=1,
|
289
|
-
assets_names=(
|
290
|
-
self.feature_names_in_
|
291
|
-
if hasattr(self, "feature_names_in_")
|
292
|
-
else None
|
293
|
-
),
|
289
|
+
assets_names=getattr(self, "feature_names_in_", None),
|
294
290
|
name="volatility_risk_premium_adj",
|
295
291
|
)
|
296
292
|
|
@@ -417,7 +413,6 @@ def _compute_implied_vol(implied_vol: np.ndarray, window_size: int) -> np.ndarra
|
|
417
413
|
def check_implied_vol(implied_vol: npt.ArrayLike, X: npt.ArrayLike) -> np.ndarray:
|
418
414
|
"""Validate implied volatilities.
|
419
415
|
|
420
|
-
|
421
416
|
Parameters
|
422
417
|
----------
|
423
418
|
implied_vol : array-like of shape (n_observations, n_assets)
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
|
8
8
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
@@ -21,7 +21,7 @@ from skfolio.utils.tools import AutoEnum, check_estimator
|
|
21
21
|
|
22
22
|
|
23
23
|
class ShrunkMuMethods(AutoEnum):
|
24
|
-
"""Shrinkage methods for the ShrunkMu estimator
|
24
|
+
"""Shrinkage methods for the ShrunkMu estimator.
|
25
25
|
|
26
26
|
Parameters
|
27
27
|
----------
|
skfolio/optimization/__init__.py
CHANGED
skfolio/optimization/_base.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
"""Base Optimization estimator."""
|
2
2
|
|
3
3
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
4
|
-
# License: BSD
|
4
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
5
5
|
|
6
6
|
from abc import ABC, abstractmethod
|
7
7
|
|
@@ -16,7 +16,7 @@ from skfolio.portfolio import Portfolio
|
|
16
16
|
|
17
17
|
# Copyright (c) 2023
|
18
18
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
19
|
-
# License: BSD
|
19
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
20
20
|
# Implementation derived from:
|
21
21
|
# scikit-portfolio, Copyright (c) 2022, Carlo Nicolini, Licensed under MIT Licence.
|
22
22
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
|
8
8
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
@@ -312,9 +312,9 @@ class NestedClustersOptimization(BaseOptimization):
|
|
312
312
|
w[cluster_ids] = fitted_inner_estimator.weights_
|
313
313
|
inner_weights.append(w)
|
314
314
|
inner_weights = np.array(inner_weights)
|
315
|
-
assert not any(
|
316
|
-
|
317
|
-
)
|
315
|
+
assert not any(fitted_inner_estimators), (
|
316
|
+
"fitted_inner_estimator iterator must be empty"
|
317
|
+
)
|
318
318
|
|
319
319
|
# Outer cluster weights
|
320
320
|
# To train the outer-estimator using the most data as possible, we use
|
@@ -380,9 +380,9 @@ class NestedClustersOptimization(BaseOptimization):
|
|
380
380
|
X_pred.append(np.asarray(pred))
|
381
381
|
X_pred = np.array(X_pred).T
|
382
382
|
if cv_predictions is None:
|
383
|
-
assert not any(
|
384
|
-
|
385
|
-
)
|
383
|
+
assert not any(fitted_inner_estimators), (
|
384
|
+
"fitted_inner_estimator iterator must be empty"
|
385
|
+
)
|
386
386
|
else:
|
387
387
|
assert not any(cv_predictions), "cv_predictions iterator must be empty"
|
388
388
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
|
8
8
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
@@ -349,7 +349,6 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
349
349
|
max_weights : ndarray of shape (n_assets,)
|
350
350
|
The weight upper bound 1D array.
|
351
351
|
"""
|
352
|
-
|
353
352
|
if self.min_weights is None:
|
354
353
|
min_weights = np.zeros(n_assets)
|
355
354
|
else:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Weight constraints is a novel implementation, see docstring for more details.
|
7
7
|
|
8
8
|
import numpy as np
|
@@ -347,7 +347,7 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
347
347
|
if self.risk_measure in [ExtraRiskMeasure.SKEW, ExtraRiskMeasure.KURTOSIS]:
|
348
348
|
# Because Skew and Kurtosis can take negative values
|
349
349
|
raise ValueError(
|
350
|
-
f"risk_measure {self.risk_measure} currently not supported
|
350
|
+
f"risk_measure {self.risk_measure} currently not supported in HERC"
|
351
351
|
)
|
352
352
|
|
353
353
|
self.prior_estimator_ = check_estimator(
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# The risk measure generalization and constraint features are derived
|
7
7
|
# from Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
|
8
8
|
|
@@ -299,7 +299,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
299
299
|
if self.risk_measure in [ExtraRiskMeasure.SKEW, ExtraRiskMeasure.KURTOSIS]:
|
300
300
|
# Because Skew and Kurtosis can take negative values
|
301
301
|
raise ValueError(
|
302
|
-
f"risk_measure {self.risk_measure} currently not supported
|
302
|
+
f"risk_measure {self.risk_measure} currently not supported in HRP"
|
303
303
|
)
|
304
304
|
|
305
305
|
self.prior_estimator_ = check_estimator(
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# The optimization features are derived
|
7
7
|
# from Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
|
8
8
|
|
@@ -144,7 +144,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
144
144
|
all weights). `None` means no budget constraints.
|
145
145
|
The default value is `1.0` (fully invested portfolio).
|
146
146
|
|
147
|
-
|
147
|
+
For example:
|
148
148
|
|
149
149
|
* `budget = 1` --> fully invested portfolio.
|
150
150
|
* `budget = 0` --> market neutral portfolio.
|
@@ -329,7 +329,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
329
329
|
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
330
330
|
assets names in columns.
|
331
331
|
|
332
|
-
|
332
|
+
For example:
|
333
333
|
|
334
334
|
* "SPX >= 0.10" --> SPX weight must be greater than 10% (note that you can also use `min_weights`)
|
335
335
|
* "SX5E + TLT >= 0.2" --> the sum of SX5E and TLT weights must be greater than 20%
|
@@ -343,7 +343,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
343
343
|
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
344
344
|
DataFrame with the assets names in columns.
|
345
345
|
|
346
|
-
|
346
|
+
For example:
|
347
347
|
|
348
348
|
* groups = {"SX5E": ["Equity", "Europe"], "SPX": ["Equity", "US"], "TLT": ["Bond", "US"]}
|
349
349
|
* groups = [["Equity", "Equity", "Bond"], ["Europe", "US", "US"]]
|
@@ -657,7 +657,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
657
657
|
)
|
658
658
|
|
659
659
|
def _clear_models_cache(self):
|
660
|
-
"""CLear the cache of CVX models"""
|
660
|
+
"""CLear the cache of CVX models."""
|
661
661
|
self._cvx_cache = {}
|
662
662
|
|
663
663
|
def _get_weight_constraints(
|
@@ -989,7 +989,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
989
989
|
self._scale_constraints = cp.Constant(self.scale_constraints)
|
990
990
|
|
991
991
|
def _get_custom_objective(self, w: cp.Variable) -> cp.Expression:
|
992
|
-
"""
|
992
|
+
"""Return the CVXPY expression evaluated by calling the `add_objective`
|
993
993
|
function if provided, otherwise returns the CVXPY constant `0`.
|
994
994
|
|
995
995
|
Parameters
|
@@ -1010,7 +1010,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
1010
1010
|
)
|
1011
1011
|
|
1012
1012
|
def _get_custom_constraints(self, w: cp.Variable) -> list[cp.Expression]:
|
1013
|
-
"""
|
1013
|
+
"""Return the list of CVXPY expressions evaluated by calling the
|
1014
1014
|
`add_constraint`s function if provided, otherwise returns an empty list.
|
1015
1015
|
|
1016
1016
|
Parameters
|
@@ -1037,7 +1037,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
1037
1037
|
def _cvx_expected_return(
|
1038
1038
|
self, prior_model: PriorModel, w: cp.Variable
|
1039
1039
|
) -> cp.Expression:
|
1040
|
-
"""Expected Return expression"""
|
1040
|
+
"""Expected Return expression."""
|
1041
1041
|
if self.overwrite_expected_return is None:
|
1042
1042
|
expected_return = prior_model.mu @ w
|
1043
1043
|
else:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
|
7
7
|
import cvxpy as cp
|
8
8
|
import numpy as np
|
@@ -94,7 +94,7 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
94
94
|
all weights). `None` means no budget constraints.
|
95
95
|
The default value is `1.0` (fully invested portfolio).
|
96
96
|
|
97
|
-
|
97
|
+
For example:
|
98
98
|
|
99
99
|
* `budget = 1` --> fully invested portfolio.
|
100
100
|
* `budget = 0` --> market neutral portfolio.
|
@@ -134,7 +134,7 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
134
134
|
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
135
135
|
assets names in columns.
|
136
136
|
|
137
|
-
|
137
|
+
For example:
|
138
138
|
|
139
139
|
* "SPX >= 0.10" --> SPX weight must be greater than 10% (note that you can also use `min_weights`)
|
140
140
|
* "SX5E + TLT >= 0.2" --> the sum of SX5E and TLT weights must be greater than 20%
|
@@ -148,7 +148,7 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
148
148
|
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
149
149
|
DataFrame with the assets names in columns.
|
150
150
|
|
151
|
-
|
151
|
+
For example:
|
152
152
|
|
153
153
|
* groups = {"SX5E": ["Equity", "Europe"], "SPX": ["Equity", "US"], "TLT": ["Bond", "US"]}
|
154
154
|
* groups = [["Equity", "Equity", "Bond"], ["Europe", "US", "US"]]
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
|
7
7
|
import numpy as np
|
8
8
|
import numpy.typing as npt
|
@@ -77,7 +77,7 @@ class MaximumDiversification(MeanRisk):
|
|
77
77
|
all weights). `None` means no budget constraints.
|
78
78
|
The default value is `1.0` (fully invested portfolio).
|
79
79
|
|
80
|
-
|
80
|
+
For example:
|
81
81
|
|
82
82
|
* `budget = 1` --> fully invested portfolio.
|
83
83
|
* `budget = 0` --> market neutral portfolio.
|
@@ -210,7 +210,7 @@ class MaximumDiversification(MeanRisk):
|
|
210
210
|
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
211
211
|
assets names in columns.
|
212
212
|
|
213
|
-
|
213
|
+
For example:
|
214
214
|
|
215
215
|
* "SPX >= 0.10" --> SPX weight must be greater than 10% (note that you can also use `min_weights`)
|
216
216
|
* "SX5E + TLT >= 0.2" --> the sum of SX5E and TLT weights must be greater than 20%
|
@@ -224,7 +224,7 @@ class MaximumDiversification(MeanRisk):
|
|
224
224
|
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
225
225
|
DataFrame with the assets names in columns.
|
226
226
|
|
227
|
-
|
227
|
+
For example:
|
228
228
|
|
229
229
|
* groups = {"SX5E": ["Equity", "Europe"], "SPX": ["Equity", "US"], "TLT": ["Bond", "US"]}
|
230
230
|
* groups = [["Equity", "Equity", "Bond"], ["Europe", "US", "US"]]
|
@@ -428,7 +428,7 @@ class MaximumDiversification(MeanRisk):
|
|
428
428
|
_ = skv.validate_data(self, X, skip_check_array=True)
|
429
429
|
|
430
430
|
def func(w, obj):
|
431
|
-
"""
|
431
|
+
"""Weighted volatilities."""
|
432
432
|
covariance = obj.prior_estimator_.prior_model_.covariance
|
433
433
|
return np.sqrt(np.diag(covariance)) @ w
|
434
434
|
|
@@ -4,7 +4,7 @@ import warnings
|
|
4
4
|
|
5
5
|
# Copyright (c) 2023
|
6
6
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
7
|
-
# License: BSD
|
7
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
8
8
|
# The optimization features are derived
|
9
9
|
# from Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
|
10
10
|
import cvxpy as cp
|
@@ -194,7 +194,7 @@ class MeanRisk(ConvexOptimization):
|
|
194
194
|
all weights). `None` means no budget constraints.
|
195
195
|
The default value is `1.0` (fully invested portfolio).
|
196
196
|
|
197
|
-
|
197
|
+
For example:
|
198
198
|
|
199
199
|
* `budget = 1` --> fully invested portfolio.
|
200
200
|
* `budget = 0` --> market neutral portfolio.
|
@@ -379,7 +379,7 @@ class MeanRisk(ConvexOptimization):
|
|
379
379
|
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
380
380
|
assets names in columns.
|
381
381
|
|
382
|
-
|
382
|
+
For example:
|
383
383
|
|
384
384
|
* "SPX >= 0.10" --> SPX weight must be greater than 10% (note that you can also use `min_weights`)
|
385
385
|
* "SX5E + TLT >= 0.2" --> the sum of SX5E and TLT weights must be greater than 20%
|
@@ -393,7 +393,7 @@ class MeanRisk(ConvexOptimization):
|
|
393
393
|
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
394
394
|
DataFrame with the assets names in columns.
|
395
395
|
|
396
|
-
|
396
|
+
For example:
|
397
397
|
|
398
398
|
* groups = {"SX5E": ["Equity", "Europe"], "SPX": ["Equity", "US"], "TLT": ["Bond", "US"]}
|
399
399
|
* groups = [["Equity", "Equity", "Bond"], ["Europe", "US", "US"]]
|
@@ -712,7 +712,7 @@ class MeanRisk(ConvexOptimization):
|
|
712
712
|
self.max_gini_mean_difference = max_gini_mean_difference
|
713
713
|
|
714
714
|
def _validation(self) -> None:
|
715
|
-
"""Validate the input parameters"""
|
715
|
+
"""Validate the input parameters."""
|
716
716
|
if not isinstance(self.risk_measure, RiskMeasure):
|
717
717
|
raise TypeError("risk_measure must be of type `RiskMeasure`")
|
718
718
|
if not isinstance(self.objective_function, ObjectiveFunction):
|
@@ -1120,5 +1120,4 @@ def _optimal_homogenization_factor(mu: np.ndarray) -> float:
|
|
1120
1120
|
value : float
|
1121
1121
|
Homogenization factor.
|
1122
1122
|
"""
|
1123
|
-
|
1124
1123
|
return min(1e3, max(1e-3, np.mean(np.abs(mu))))
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# The optimization features are derived
|
7
7
|
# from Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
|
8
8
|
|
@@ -226,7 +226,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
226
226
|
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
227
227
|
assets names in columns.
|
228
228
|
|
229
|
-
|
229
|
+
For example:
|
230
230
|
|
231
231
|
* "SPX >= 0.10" --> SPX weight must be greater than 10% (note that you can also use `min_weights`)
|
232
232
|
* "SX5E + TLT >= 0.2" --> the sum of SX5E and TLT weights must be greater than 20%
|
@@ -240,7 +240,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
240
240
|
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
241
241
|
DataFrame with the assets names in columns.
|
242
242
|
|
243
|
-
|
243
|
+
For example:
|
244
244
|
|
245
245
|
* groups = {"SX5E": ["Equity", "Europe"], "SPX": ["Equity", "US"], "TLT": ["Bond", "US"]}
|
246
246
|
* groups = [["Equity", "Equity", "Bond"], ["Europe", "US", "US"]]
|
@@ -1,10 +1,10 @@
|
|
1
1
|
"""Base Composition estimator.
|
2
|
-
Follow same implementation as Base composition from sklearn
|
2
|
+
Follow same implementation as Base composition from sklearn.
|
3
3
|
"""
|
4
4
|
|
5
5
|
# Copyright (c) 2023
|
6
6
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
7
|
-
# License: BSD
|
7
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
8
8
|
# Implementation derived from:
|
9
9
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
10
10
|
# Grisel Licensed under BSD 3 clause.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Copyright (c) 2023
|
4
4
|
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
-
# License: BSD
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
6
|
# Implementation derived from:
|
7
7
|
# scikit-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|