skfolio 0.6.0__py3-none-any.whl → 0.8.0__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 +7 -7
- skfolio/cluster/__init__.py +2 -2
- skfolio/cluster/_hierarchical.py +2 -2
- skfolio/datasets/__init__.py +3 -3
- skfolio/datasets/_base.py +2 -2
- skfolio/datasets/data/__init__.py +1 -0
- skfolio/distance/__init__.py +4 -4
- skfolio/distance/_base.py +2 -2
- skfolio/distance/_distance.py +11 -10
- 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 +8 -8
- skfolio/measures/__init__.py +24 -24
- 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 +4 -4
- skfolio/model_selection/_combinatorial.py +15 -12
- skfolio/model_selection/_validation.py +2 -2
- skfolio/model_selection/_walk_forward.py +3 -3
- skfolio/moments/__init__.py +11 -11
- skfolio/moments/covariance/__init__.py +6 -6
- skfolio/moments/covariance/_base.py +1 -1
- skfolio/moments/covariance/_denoise_covariance.py +3 -2
- skfolio/moments/covariance/_detone_covariance.py +3 -2
- skfolio/moments/covariance/_empirical_covariance.py +3 -2
- skfolio/moments/covariance/_ew_covariance.py +3 -2
- skfolio/moments/covariance/_gerber_covariance.py +3 -2
- skfolio/moments/covariance/_graphical_lasso_cv.py +1 -1
- skfolio/moments/covariance/_implied_covariance.py +3 -8
- 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/__init__.py +2 -2
- skfolio/moments/expected_returns/_base.py +1 -1
- skfolio/moments/expected_returns/_empirical_mu.py +3 -2
- skfolio/moments/expected_returns/_equilibrium_mu.py +3 -2
- skfolio/moments/expected_returns/_ew_mu.py +3 -2
- skfolio/moments/expected_returns/_shrunk_mu.py +4 -3
- skfolio/optimization/__init__.py +12 -10
- skfolio/optimization/_base.py +2 -2
- skfolio/optimization/cluster/__init__.py +3 -1
- skfolio/optimization/cluster/_nco.py +10 -9
- skfolio/optimization/cluster/hierarchical/__init__.py +3 -1
- skfolio/optimization/cluster/hierarchical/_base.py +1 -2
- skfolio/optimization/cluster/hierarchical/_herc.py +4 -3
- skfolio/optimization/cluster/hierarchical/_hrp.py +4 -3
- skfolio/optimization/convex/__init__.py +5 -3
- skfolio/optimization/convex/_base.py +10 -9
- skfolio/optimization/convex/_distributionally_robust.py +8 -5
- skfolio/optimization/convex/_maximum_diversification.py +8 -6
- skfolio/optimization/convex/_mean_risk.py +10 -8
- skfolio/optimization/convex/_risk_budgeting.py +6 -4
- skfolio/optimization/ensemble/__init__.py +2 -0
- skfolio/optimization/ensemble/_base.py +2 -2
- skfolio/optimization/ensemble/_stacking.py +3 -3
- skfolio/optimization/naive/__init__.py +3 -1
- skfolio/optimization/naive/_naive.py +4 -3
- skfolio/population/__init__.py +2 -0
- skfolio/population/_population.py +34 -7
- skfolio/portfolio/__init__.py +1 -1
- skfolio/portfolio/_base.py +43 -8
- skfolio/portfolio/_multi_period_portfolio.py +3 -2
- skfolio/portfolio/_portfolio.py +5 -4
- skfolio/pre_selection/__init__.py +3 -1
- skfolio/pre_selection/_drop_correlated.py +3 -3
- skfolio/pre_selection/_select_complete.py +31 -30
- skfolio/pre_selection/_select_k_extremes.py +3 -3
- skfolio/pre_selection/_select_non_dominated.py +3 -3
- skfolio/pre_selection/_select_non_expiring.py +8 -6
- skfolio/preprocessing/__init__.py +2 -0
- skfolio/preprocessing/_returns.py +2 -2
- skfolio/prior/__init__.py +7 -3
- skfolio/prior/_base.py +2 -2
- skfolio/prior/_black_litterman.py +7 -4
- skfolio/prior/_empirical.py +5 -2
- skfolio/prior/_factor_model.py +10 -5
- skfolio/prior/_synthetic_data.py +239 -0
- skfolio/synthetic_returns/__init__.py +1 -0
- skfolio/typing.py +7 -7
- skfolio/uncertainty_set/__init__.py +7 -5
- skfolio/uncertainty_set/_base.py +5 -4
- 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 +15 -15
- skfolio/utils/tools.py +86 -22
- {skfolio-0.6.0.dist-info → skfolio-0.8.0.dist-info}/METADATA +122 -46
- skfolio-0.8.0.dist-info/RECORD +120 -0
- {skfolio-0.6.0.dist-info → skfolio-0.8.0.dist-info}/WHEEL +1 -1
- skfolio-0.6.0.dist-info/RECORD +0 -95
- {skfolio-0.6.0.dist-info → skfolio-0.8.0.dist-info/licenses}/LICENSE +0 -0
- {skfolio-0.6.0.dist-info → skfolio-0.8.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,8 @@
|
|
1
|
-
"""Combinatorial module"""
|
1
|
+
"""Combinatorial module."""
|
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
|
@@ -36,7 +36,7 @@ class BaseCombinatorialCV(ABC):
|
|
36
36
|
|
37
37
|
@abstractmethod
|
38
38
|
def get_path_ids(self) -> np.ndarray:
|
39
|
-
"""Return the path id of each test sets in each split"""
|
39
|
+
"""Return the path id of each test sets in each split."""
|
40
40
|
pass
|
41
41
|
|
42
42
|
__repr__ = sks.BaseCrossValidator.__repr__
|
@@ -196,18 +196,19 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
196
196
|
|
197
197
|
@property
|
198
198
|
def n_splits(self) -> int:
|
199
|
-
"""Number of splits"""
|
199
|
+
"""Number of splits."""
|
200
200
|
return _n_splits(n_folds=self.n_folds, n_test_folds=self.n_test_folds)
|
201
201
|
|
202
202
|
@property
|
203
203
|
def n_test_paths(self) -> int:
|
204
204
|
"""Number of test paths that can be reconstructed from the train/test
|
205
|
-
combinations
|
205
|
+
combinations.
|
206
|
+
"""
|
206
207
|
return _n_test_paths(n_folds=self.n_folds, n_test_folds=self.n_test_folds)
|
207
208
|
|
208
209
|
@property
|
209
210
|
def test_set_index(self) -> np.ndarray:
|
210
|
-
"""Location of each test set"""
|
211
|
+
"""Location of each test set."""
|
211
212
|
return np.array(
|
212
213
|
list(itertools.combinations(np.arange(self.n_folds), self.n_test_folds))
|
213
214
|
).reshape(-1, self.n_test_folds)
|
@@ -215,7 +216,8 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
215
216
|
@property
|
216
217
|
def binary_train_test_sets(self) -> np.ndarray:
|
217
218
|
"""Identify training and test folds for each combinations by assigning `0` to
|
218
|
-
training folds and `1` to test folds
|
219
|
+
training folds and `1` to test folds.
|
220
|
+
"""
|
219
221
|
folds_train_test = np.zeros((self.n_folds, self.n_splits))
|
220
222
|
folds_train_test[
|
221
223
|
self.test_set_index, np.arange(self.n_splits)[:, np.newaxis]
|
@@ -230,7 +232,7 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
230
232
|
)
|
231
233
|
|
232
234
|
def get_path_ids(self) -> np.ndarray:
|
233
|
-
"""Return the path id of each test sets in each split"""
|
235
|
+
"""Return the path id of each test sets in each split."""
|
234
236
|
recombine_paths = self.recombined_paths
|
235
237
|
path_ids = np.zeros((self.n_splits, self.n_test_folds), dtype=int)
|
236
238
|
for i in range(self.n_splits):
|
@@ -334,7 +336,7 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
334
336
|
)
|
335
337
|
|
336
338
|
def plot_train_test_folds(self) -> skt.Figure:
|
337
|
-
"""Plot the train/test fold locations"""
|
339
|
+
"""Plot the train/test fold locations."""
|
338
340
|
values = self.binary_train_test_sets
|
339
341
|
fill_color = np.where(values == 0, "blue", "red")
|
340
342
|
fill_color = fill_color.astype(object)
|
@@ -367,7 +369,8 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
367
369
|
|
368
370
|
def plot_train_test_index(self, X) -> skt.Figure:
|
369
371
|
"""Plot the training and test indices for each combinations by assigning `0` to
|
370
|
-
training, `1` to test and `-1` to both purge and embargo indices.
|
372
|
+
training, `1` to test and `-1` to both purge and embargo indices.
|
373
|
+
"""
|
371
374
|
next(self.split(X))
|
372
375
|
n_samples = X.shape[0]
|
373
376
|
cond = [
|
@@ -425,12 +428,12 @@ def _n_splits(n_folds: int, n_test_folds: int) -> int:
|
|
425
428
|
n_splits : int
|
426
429
|
Number of splits
|
427
430
|
"""
|
428
|
-
return
|
431
|
+
return math.comb(n_folds, n_test_folds)
|
429
432
|
|
430
433
|
|
431
434
|
def _n_test_paths(n_folds: int, n_test_folds: int) -> int:
|
432
435
|
"""Number of test paths that can be reconstructed from the train/test
|
433
|
-
combinations
|
436
|
+
combinations.
|
434
437
|
|
435
438
|
Parameters
|
436
439
|
----------
|
@@ -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
|
----------
|
skfolio/moments/__init__.py
CHANGED
@@ -23,21 +23,21 @@ from skfolio.moments.expected_returns import (
|
|
23
23
|
)
|
24
24
|
|
25
25
|
__all__ = [
|
26
|
+
"OAS",
|
27
|
+
"BaseCovariance",
|
26
28
|
"BaseMu",
|
27
|
-
"
|
29
|
+
"DenoiseCovariance",
|
30
|
+
"DetoneCovariance",
|
31
|
+
"EWCovariance",
|
28
32
|
"EWMu",
|
29
|
-
"ShrunkMu",
|
30
|
-
"EquilibriumMu",
|
31
|
-
"ShrunkMuMethods",
|
32
|
-
"BaseCovariance",
|
33
33
|
"EmpiricalCovariance",
|
34
|
-
"
|
34
|
+
"EmpiricalMu",
|
35
|
+
"EquilibriumMu",
|
35
36
|
"GerberCovariance",
|
36
|
-
"DenoiseCovariance",
|
37
|
-
"DetoneCovariance",
|
38
|
-
"LedoitWolf",
|
39
|
-
"OAS",
|
40
|
-
"ShrunkCovariance",
|
41
37
|
"GraphicalLassoCV",
|
42
38
|
"ImpliedCovariance",
|
39
|
+
"LedoitWolf",
|
40
|
+
"ShrunkCovariance",
|
41
|
+
"ShrunkMu",
|
42
|
+
"ShrunkMuMethods",
|
43
43
|
]
|
@@ -15,15 +15,15 @@ from skfolio.moments.covariance._oas import OAS
|
|
15
15
|
from skfolio.moments.covariance._shrunk_covariance import ShrunkCovariance
|
16
16
|
|
17
17
|
__all__ = [
|
18
|
+
"OAS",
|
18
19
|
"BaseCovariance",
|
19
|
-
"EmpiricalCovariance",
|
20
|
-
"EWCovariance",
|
21
|
-
"GerberCovariance",
|
22
20
|
"DenoiseCovariance",
|
23
21
|
"DetoneCovariance",
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
22
|
+
"EWCovariance",
|
23
|
+
"EmpiricalCovariance",
|
24
|
+
"GerberCovariance",
|
27
25
|
"GraphicalLassoCV",
|
28
26
|
"ImpliedCovariance",
|
27
|
+
"LedoitWolf",
|
28
|
+
"ShrunkCovariance",
|
29
29
|
]
|
@@ -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.
|
@@ -12,6 +12,7 @@ import numpy.typing as npt
|
|
12
12
|
import scipy.optimize as sco
|
13
13
|
import sklearn.neighbors as skn
|
14
14
|
import sklearn.utils.metadata_routing as skm
|
15
|
+
import sklearn.utils.validation as skv
|
15
16
|
|
16
17
|
from skfolio.moments.covariance._base import BaseCovariance
|
17
18
|
from skfolio.moments.covariance._empirical_covariance import EmpiricalCovariance
|
@@ -139,7 +140,7 @@ class DenoiseCovariance(BaseCovariance):
|
|
139
140
|
|
140
141
|
# we validate and convert to numpy after all models have been fitted to keep
|
141
142
|
# features names information.
|
142
|
-
X =
|
143
|
+
X = skv.validate_data(self, X)
|
143
144
|
n_observations, n_assets = X.shape
|
144
145
|
q = n_observations / n_assets
|
145
146
|
corr, std = cov_to_corr(self.covariance_estimator_.covariance_)
|
@@ -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.
|
@@ -10,6 +10,7 @@
|
|
10
10
|
import numpy as np
|
11
11
|
import numpy.typing as npt
|
12
12
|
import sklearn.utils.metadata_routing as skm
|
13
|
+
import sklearn.utils.validation as skv
|
13
14
|
|
14
15
|
from skfolio.moments.covariance._base import BaseCovariance
|
15
16
|
from skfolio.moments.covariance._empirical_covariance import EmpiricalCovariance
|
@@ -141,7 +142,7 @@ class DetoneCovariance(BaseCovariance):
|
|
141
142
|
|
142
143
|
# we validate and convert to numpy after all models have been fitted to keep
|
143
144
|
# features names information.
|
144
|
-
_ =
|
145
|
+
_ = skv.validate_data(self, X)
|
145
146
|
corr, std = cov_to_corr(self.covariance_estimator_.covariance_)
|
146
147
|
e_val, e_vec = np.linalg.eigh(corr)
|
147
148
|
indices = e_val.argsort()[::-1]
|
@@ -2,13 +2,14 @@
|
|
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.
|
9
9
|
|
10
10
|
import numpy as np
|
11
11
|
import numpy.typing as npt
|
12
|
+
import sklearn.utils.validation as skv
|
12
13
|
|
13
14
|
from skfolio.moments.covariance._base import BaseCovariance
|
14
15
|
|
@@ -92,7 +93,7 @@ class EmpiricalCovariance(BaseCovariance):
|
|
92
93
|
self : EmpiricalCovariance
|
93
94
|
Fitted estimator.
|
94
95
|
"""
|
95
|
-
X =
|
96
|
+
X = skv.validate_data(self, X)
|
96
97
|
if self.window_size is not None:
|
97
98
|
X = X[-int(self.window_size) :]
|
98
99
|
covariance = np.cov(X.T, ddof=self.ddof)
|
@@ -2,13 +2,14 @@
|
|
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.
|
9
9
|
|
10
10
|
import numpy.typing as npt
|
11
11
|
import pandas as pd
|
12
|
+
import sklearn.utils.validation as skv
|
12
13
|
|
13
14
|
from skfolio.moments.covariance._base import BaseCovariance
|
14
15
|
|
@@ -94,7 +95,7 @@ class EWCovariance(BaseCovariance):
|
|
94
95
|
self : EWCovariance
|
95
96
|
Fitted estimator.
|
96
97
|
"""
|
97
|
-
X =
|
98
|
+
X = skv.validate_data(self, X)
|
98
99
|
if self.window_size is not None:
|
99
100
|
X = X[-int(self.window_size) :]
|
100
101
|
n_observations = X.shape[0]
|
@@ -2,13 +2,14 @@
|
|
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.
|
9
9
|
|
10
10
|
import numpy as np
|
11
11
|
import numpy.typing as npt
|
12
|
+
import sklearn.utils.validation as skv
|
12
13
|
|
13
14
|
from skfolio.moments.covariance._base import BaseCovariance
|
14
15
|
from skfolio.utils.stats import corr_to_cov
|
@@ -131,7 +132,7 @@ class GerberCovariance(BaseCovariance):
|
|
131
132
|
self : GerberCovariance
|
132
133
|
Fitted estimator.
|
133
134
|
"""
|
134
|
-
X =
|
135
|
+
X = skv.validate_data(self, X)
|
135
136
|
if self.window_size is not None:
|
136
137
|
X = X[-self.window_size :]
|
137
138
|
if not (1 > self.threshold > 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-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.
|
@@ -272,7 +272,7 @@ class ImpliedCovariance(BaseCovariance):
|
|
272
272
|
# and re-order to follow returns ordering.
|
273
273
|
implied_vol = safe_indexing(implied_vol, indices=indices, axis=1)
|
274
274
|
|
275
|
-
X =
|
275
|
+
X = skv.validate_data(self, X)
|
276
276
|
_, n_assets = X.shape
|
277
277
|
implied_vol = check_implied_vol(implied_vol=implied_vol, X=X)
|
278
278
|
implied_vol /= np.sqrt(self.annualized_factor)
|
@@ -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,13 +2,14 @@
|
|
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.
|
9
9
|
|
10
10
|
import numpy as np
|
11
11
|
import numpy.typing as npt
|
12
|
+
import sklearn.utils.validation as skv
|
12
13
|
|
13
14
|
from skfolio.moments.expected_returns._base import BaseMu
|
14
15
|
|
@@ -56,7 +57,7 @@ class EmpiricalMu(BaseMu):
|
|
56
57
|
self : EmpiricalMu
|
57
58
|
Fitted estimator.
|
58
59
|
"""
|
59
|
-
X =
|
60
|
+
X = skv.validate_data(self, X)
|
60
61
|
if self.window_size is not None:
|
61
62
|
X = X[-self.window_size :]
|
62
63
|
self.mu_ = np.mean(X, axis=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-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
@@ -10,6 +10,7 @@
|
|
10
10
|
import numpy as np
|
11
11
|
import numpy.typing as npt
|
12
12
|
import sklearn.utils.metadata_routing as skm
|
13
|
+
import sklearn.utils.validation as skv
|
13
14
|
|
14
15
|
from skfolio.moments.covariance import BaseCovariance, EmpiricalCovariance
|
15
16
|
from skfolio.moments.expected_returns._base import BaseMu
|
@@ -114,7 +115,7 @@ class EquilibriumMu(BaseMu):
|
|
114
115
|
|
115
116
|
# we validate and convert to numpy after all models have been fitted to keep
|
116
117
|
# features names information.
|
117
|
-
X =
|
118
|
+
X = skv.validate_data(self, X)
|
118
119
|
n_assets = X.shape[1]
|
119
120
|
if self.weights is None:
|
120
121
|
weights = np.ones(n_assets) / n_assets
|
@@ -2,13 +2,14 @@
|
|
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.
|
9
9
|
|
10
10
|
import numpy.typing as npt
|
11
11
|
import pandas as pd
|
12
|
+
import sklearn.utils.validation as skv
|
12
13
|
|
13
14
|
from skfolio.moments.expected_returns._base import BaseMu
|
14
15
|
|
@@ -62,7 +63,7 @@ class EWMu(BaseMu):
|
|
62
63
|
self : EWMu
|
63
64
|
Fitted estimator.
|
64
65
|
"""
|
65
|
-
X =
|
66
|
+
X = skv.validate_data(self, X)
|
66
67
|
if self.window_size is not None:
|
67
68
|
X = X[-self.window_size :]
|
68
69
|
self.mu_ = pd.DataFrame(X).ewm(alpha=self.alpha).mean().iloc[-1, :].to_numpy()
|
@@ -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
|
@@ -13,6 +13,7 @@ from enum import auto
|
|
13
13
|
import numpy as np
|
14
14
|
import numpy.typing as npt
|
15
15
|
import sklearn.utils.metadata_routing as skm
|
16
|
+
import sklearn.utils.validation as skv
|
16
17
|
|
17
18
|
from skfolio.moments.covariance import BaseCovariance, EmpiricalCovariance
|
18
19
|
from skfolio.moments.expected_returns._base import BaseMu
|
@@ -20,7 +21,7 @@ from skfolio.utils.tools import AutoEnum, check_estimator
|
|
20
21
|
|
21
22
|
|
22
23
|
class ShrunkMuMethods(AutoEnum):
|
23
|
-
"""Shrinkage methods for the ShrunkMu estimator
|
24
|
+
"""Shrinkage methods for the ShrunkMu estimator.
|
24
25
|
|
25
26
|
Parameters
|
26
27
|
----------
|
@@ -189,7 +190,7 @@ class ShrunkMu(BaseMu):
|
|
189
190
|
|
190
191
|
# we validate and convert to numpy after all models have been fitted to keep
|
191
192
|
# features names information.
|
192
|
-
X =
|
193
|
+
X = skv.validate_data(self, X)
|
193
194
|
n_observations, n_assets = X.shape
|
194
195
|
|
195
196
|
covariance = self.covariance_estimator_.covariance_
|
skfolio/optimization/__init__.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
"""Optimization module."""
|
2
|
+
|
1
3
|
from skfolio.optimization._base import BaseOptimization
|
2
4
|
from skfolio.optimization.cluster import (
|
3
5
|
BaseHierarchicalOptimization,
|
@@ -17,20 +19,20 @@ from skfolio.optimization.ensemble import BaseComposition, StackingOptimization
|
|
17
19
|
from skfolio.optimization.naive import EqualWeighted, InverseVolatility, Random
|
18
20
|
|
19
21
|
__all__ = [
|
22
|
+
"BaseComposition",
|
23
|
+
"BaseHierarchicalOptimization",
|
20
24
|
"BaseOptimization",
|
21
|
-
"InverseVolatility",
|
22
|
-
"EqualWeighted",
|
23
|
-
"Random",
|
24
|
-
"ObjectiveFunction",
|
25
25
|
"ConvexOptimization",
|
26
|
-
"MeanRisk",
|
27
|
-
"RiskBudgeting",
|
28
26
|
"DistributionallyRobustCVaR",
|
29
|
-
"
|
30
|
-
"BaseHierarchicalOptimization",
|
31
|
-
"HierarchicalRiskParity",
|
27
|
+
"EqualWeighted",
|
32
28
|
"HierarchicalEqualRiskContribution",
|
29
|
+
"HierarchicalRiskParity",
|
30
|
+
"InverseVolatility",
|
31
|
+
"MaximumDiversification",
|
32
|
+
"MeanRisk",
|
33
33
|
"NestedClustersOptimization",
|
34
|
-
"
|
34
|
+
"ObjectiveFunction",
|
35
|
+
"Random",
|
36
|
+
"RiskBudgeting",
|
35
37
|
"StackingOptimization",
|
36
38
|
]
|
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
|
@@ -1,3 +1,5 @@
|
|
1
|
+
"""Cluster Optimization module."""
|
2
|
+
|
1
3
|
from skfolio.optimization.cluster._nco import NestedClustersOptimization
|
2
4
|
from skfolio.optimization.cluster.hierarchical import (
|
3
5
|
BaseHierarchicalOptimization,
|
@@ -7,7 +9,7 @@ from skfolio.optimization.cluster.hierarchical import (
|
|
7
9
|
|
8
10
|
__all__ = [
|
9
11
|
"BaseHierarchicalOptimization",
|
10
|
-
"HierarchicalRiskParity",
|
11
12
|
"HierarchicalEqualRiskContribution",
|
13
|
+
"HierarchicalRiskParity",
|
12
14
|
"NestedClustersOptimization",
|
13
15
|
]
|