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
skfolio/utils/tools.py
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
"""Tools module"""
|
1
|
+
"""Tools 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-learn, Copyright (c) 2007-2010 David Cournapeau, Fabian Pedregosa, Olivier
|
8
8
|
# Grisel Licensed under BSD 3 clause.
|
9
9
|
|
10
|
+
import warnings
|
10
11
|
from collections.abc import Callable, Iterator
|
11
12
|
from enum import Enum
|
12
13
|
from functools import wraps
|
@@ -21,34 +22,35 @@ import sklearn.base as skb
|
|
21
22
|
|
22
23
|
__all__ = [
|
23
24
|
"AutoEnum",
|
24
|
-
"cached_property_slots",
|
25
|
-
"cache_method",
|
26
|
-
"input_to_array",
|
27
25
|
"args_names",
|
28
|
-
"format_measure",
|
29
|
-
"optimal_rounding_decimals",
|
30
26
|
"bisection",
|
31
|
-
"
|
32
|
-
"
|
33
|
-
"
|
34
|
-
"safe_indexing",
|
27
|
+
"cache_method",
|
28
|
+
"cached_property_slots",
|
29
|
+
"check_estimator",
|
35
30
|
"deduplicate_names",
|
36
31
|
"default_asset_names",
|
37
|
-
"
|
32
|
+
"fit_and_predict",
|
33
|
+
"fit_single_estimator",
|
34
|
+
"format_measure",
|
38
35
|
"get_feature_names",
|
36
|
+
"input_to_array",
|
37
|
+
"optimal_rounding_decimals",
|
38
|
+
"safe_indexing",
|
39
|
+
"safe_split",
|
40
|
+
"validate_input_list",
|
39
41
|
]
|
40
42
|
|
41
43
|
GenericAlias = type(list[int])
|
42
44
|
|
43
45
|
|
44
46
|
class AutoEnum(str, Enum):
|
45
|
-
"""Base Enum class used in `skfolio
|
47
|
+
"""Base Enum class used in `skfolio`."""
|
46
48
|
|
47
49
|
@staticmethod
|
48
50
|
def _generate_next_value_(
|
49
51
|
name: str, start: int, count: int, last_values: Any
|
50
52
|
) -> str:
|
51
|
-
"""Overriding `auto()
|
53
|
+
"""Overriding `auto()`."""
|
52
54
|
return name.lower()
|
53
55
|
|
54
56
|
@classmethod
|
@@ -68,13 +70,13 @@ class AutoEnum(str, Enum):
|
|
68
70
|
return value in cls._value2member_map_
|
69
71
|
|
70
72
|
def __repr__(self) -> str:
|
71
|
-
"""Representation of the Enum"""
|
73
|
+
"""Representation of the Enum."""
|
72
74
|
return self.name
|
73
75
|
|
74
76
|
|
75
77
|
# noinspection PyPep8Naming
|
76
78
|
class cached_property_slots:
|
77
|
-
"""Cached property decorator for slots"""
|
79
|
+
"""Cached property decorator for slots."""
|
78
80
|
|
79
81
|
def __init__(self, func):
|
80
82
|
self.func = func
|
@@ -83,10 +85,12 @@ class cached_property_slots:
|
|
83
85
|
self.__doc__ = func.__doc__
|
84
86
|
|
85
87
|
def __set_name__(self, owner, name):
|
88
|
+
"""Set Name."""
|
86
89
|
self.public_name = name
|
87
90
|
self.private_name = f"_{name}"
|
88
91
|
|
89
92
|
def __get__(self, instance, owner=None):
|
93
|
+
"""Getter."""
|
90
94
|
if instance is None:
|
91
95
|
return self
|
92
96
|
if self.private_name is None:
|
@@ -102,6 +106,7 @@ class cached_property_slots:
|
|
102
106
|
return value
|
103
107
|
|
104
108
|
def __set__(self, instance, owner=None):
|
109
|
+
"""Setter."""
|
105
110
|
raise AttributeError(
|
106
111
|
f"'{type(instance).__name__}' object attribute '{self.public_name}' is"
|
107
112
|
" read-only"
|
@@ -111,7 +116,7 @@ class cached_property_slots:
|
|
111
116
|
|
112
117
|
|
113
118
|
def _make_key(args, kwds) -> int:
|
114
|
-
"""Make a cache key from optionally typed positional and keyword arguments"""
|
119
|
+
"""Make a cache key from optionally typed positional and keyword arguments."""
|
115
120
|
key = args
|
116
121
|
if kwds:
|
117
122
|
for item in kwds.items():
|
@@ -248,7 +253,6 @@ def safe_split(
|
|
248
253
|
y_subset : array-like
|
249
254
|
Indexed targets.
|
250
255
|
"""
|
251
|
-
|
252
256
|
X_subset = safe_indexing(X, indices=indices, axis=axis)
|
253
257
|
if y is not None:
|
254
258
|
y_subset = safe_indexing(y, indices=indices, axis=axis)
|
@@ -340,10 +344,9 @@ def check_estimator(
|
|
340
344
|
|
341
345
|
Returns
|
342
346
|
-------
|
343
|
-
estimator: Estimator
|
347
|
+
estimator : Estimator
|
344
348
|
The checked estimator or the default.
|
345
349
|
"""
|
346
|
-
|
347
350
|
if estimator is None:
|
348
351
|
return default
|
349
352
|
if not isinstance(estimator, check_type):
|
@@ -439,6 +442,67 @@ def input_to_array(
|
|
439
442
|
return arr
|
440
443
|
|
441
444
|
|
445
|
+
def validate_input_list(
|
446
|
+
items: list[int | str],
|
447
|
+
n_assets: int,
|
448
|
+
assets_names: np.ndarray[str] | None,
|
449
|
+
name: str,
|
450
|
+
raise_if_string_missing: bool = True,
|
451
|
+
) -> list[int]:
|
452
|
+
"""Convert a list of items (asset indices or asset names) into a list of
|
453
|
+
validated asset indices.
|
454
|
+
|
455
|
+
Parameters
|
456
|
+
----------
|
457
|
+
items : list[int | str]
|
458
|
+
List of asset indices or asset names.
|
459
|
+
|
460
|
+
n_assets : int
|
461
|
+
Expected number of assets.
|
462
|
+
Used for verification.
|
463
|
+
|
464
|
+
assets_names : ndarray, optional
|
465
|
+
Asset names used when `items` contain strings.
|
466
|
+
|
467
|
+
name : str
|
468
|
+
Name of the items used for error messages.
|
469
|
+
|
470
|
+
raise_if_string_missing : bool, default=True
|
471
|
+
If set to True, raises an error if an item string is missing from assets_names;
|
472
|
+
otherwise, issue a User Warning.
|
473
|
+
|
474
|
+
Returns
|
475
|
+
-------
|
476
|
+
values : list[int]
|
477
|
+
Converted and validated list.
|
478
|
+
"""
|
479
|
+
if len(set(items)) != len(items):
|
480
|
+
raise ValueError(f"Duplicates found in {items}")
|
481
|
+
|
482
|
+
asset_indices = set(range(n_assets))
|
483
|
+
res = []
|
484
|
+
for asset in items:
|
485
|
+
if isinstance(asset, str):
|
486
|
+
if assets_names is None:
|
487
|
+
raise ValueError(
|
488
|
+
f"If `{name}` is provided as a list of string, you must input `X` "
|
489
|
+
f"as a DataFrame with assets names in columns."
|
490
|
+
)
|
491
|
+
mask = assets_names == asset
|
492
|
+
if np.any(mask):
|
493
|
+
res.append(int(np.where(mask)[0][0]))
|
494
|
+
else:
|
495
|
+
if raise_if_string_missing:
|
496
|
+
raise ValueError(f"{asset} not found in {assets_names}")
|
497
|
+
else:
|
498
|
+
warnings.warn(f"{asset} not found in {assets_names}", stacklevel=2)
|
499
|
+
else:
|
500
|
+
if asset not in asset_indices:
|
501
|
+
raise ValueError(f"`central_assets` {asset} is not in {asset_indices}.")
|
502
|
+
res.append(int(asset))
|
503
|
+
return res
|
504
|
+
|
505
|
+
|
442
506
|
def format_measure(x: float, percent: bool = False) -> str:
|
443
507
|
"""Format a measure number into a user-friendly string.
|
444
508
|
|
@@ -514,7 +578,7 @@ def fit_single_estimator(
|
|
514
578
|
indices: np.ndarray | None = None,
|
515
579
|
axis: int = 0,
|
516
580
|
):
|
517
|
-
"""
|
581
|
+
"""Function used to fit an estimator within a job.
|
518
582
|
|
519
583
|
Parameters
|
520
584
|
----------
|
@@ -622,7 +686,7 @@ def fit_and_predict(
|
|
622
686
|
|
623
687
|
|
624
688
|
def default_asset_names(n_assets: int) -> np.ndarray:
|
625
|
-
"""Default asset names are `["x0", "x1", ..., "x(n_assets - 1)"]
|
689
|
+
"""Default asset names are `["x0", "x1", ..., "x(n_assets - 1)"]`.
|
626
690
|
|
627
691
|
Parameters
|
628
692
|
----------
|
@@ -1,9 +1,9 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: skfolio
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.8.0
|
4
4
|
Summary: Portfolio optimization built on top of scikit-learn
|
5
5
|
Author-email: Hugo Delatte <delatte.hugo@gmail.com>
|
6
|
-
Maintainer-email: Hugo Delatte <delatte.hugo@gmail.com>
|
6
|
+
Maintainer-email: Hugo Delatte <delatte.hugo@gmail.com>, Matteo Manzi <matteomanzi09@gmail.com>
|
7
7
|
License: BSD 3-Clause License
|
8
8
|
|
9
9
|
Copyright (c) 2007-2023 The skfolio developers.
|
@@ -56,36 +56,39 @@ Classifier: Topic :: Software Development
|
|
56
56
|
Requires-Python: >=3.10
|
57
57
|
Description-Content-Type: text/x-rst
|
58
58
|
License-File: LICENSE
|
59
|
-
Requires-Dist: numpy
|
60
|
-
Requires-Dist: scipy
|
61
|
-
Requires-Dist: pandas
|
62
|
-
Requires-Dist: cvxpy
|
63
|
-
Requires-Dist:
|
64
|
-
Requires-Dist:
|
65
|
-
Requires-Dist:
|
59
|
+
Requires-Dist: numpy>=1.23.4
|
60
|
+
Requires-Dist: scipy>=1.15.2
|
61
|
+
Requires-Dist: pandas>=1.4.1
|
62
|
+
Requires-Dist: cvxpy-base>=1.5.0
|
63
|
+
Requires-Dist: clarabel>=0.9.0
|
64
|
+
Requires-Dist: scikit-learn>=1.6.0
|
65
|
+
Requires-Dist: joblib>=1.3.2
|
66
|
+
Requires-Dist: plotly>=5.22.0
|
67
|
+
Provides-Extra: dev
|
68
|
+
Requires-Dist: PySCIPOpt; extra == "dev"
|
69
|
+
Requires-Dist: pytest; extra == "dev"
|
70
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
71
|
+
Requires-Dist: ruff; extra == "dev"
|
72
|
+
Requires-Dist: pre-commit; extra == "dev"
|
66
73
|
Provides-Extra: docs
|
67
|
-
Requires-Dist:
|
68
|
-
Requires-Dist: Sphinx
|
69
|
-
Requires-Dist: sphinx-gallery
|
70
|
-
Requires-Dist: sphinx-design
|
71
|
-
Requires-Dist: pydata-sphinx-theme
|
72
|
-
Requires-Dist: matplotlib
|
73
|
-
Requires-Dist: kaleido
|
74
|
-
Requires-Dist: sphinx-copybutton
|
75
|
-
Requires-Dist: numpydoc
|
76
|
-
Requires-Dist: sphinx-togglebutton
|
77
|
-
Requires-Dist: sphinx-favicon
|
78
|
-
Requires-Dist: sphinx-prompt
|
79
|
-
Requires-Dist: sphinxext.opengraph
|
80
|
-
Requires-Dist: sphinx-sitemap
|
81
|
-
Requires-Dist: jupyterlite-sphinx
|
82
|
-
Requires-Dist: jupyterlite-pyodide-kernel
|
83
|
-
Requires-Dist: nbformat
|
84
|
-
|
85
|
-
Requires-Dist: cvxpy[scip] ; extra == 'tests'
|
86
|
-
Requires-Dist: pytest ; extra == 'tests'
|
87
|
-
Requires-Dist: pytest-cov ; extra == 'tests'
|
88
|
-
Requires-Dist: ruff ; extra == 'tests'
|
74
|
+
Requires-Dist: PySCIPOpt; extra == "docs"
|
75
|
+
Requires-Dist: Sphinx; extra == "docs"
|
76
|
+
Requires-Dist: sphinx-gallery; extra == "docs"
|
77
|
+
Requires-Dist: sphinx-design; extra == "docs"
|
78
|
+
Requires-Dist: pydata-sphinx-theme==0.13.3; extra == "docs"
|
79
|
+
Requires-Dist: matplotlib; extra == "docs"
|
80
|
+
Requires-Dist: kaleido==0.2.1; extra == "docs"
|
81
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
82
|
+
Requires-Dist: numpydoc; extra == "docs"
|
83
|
+
Requires-Dist: sphinx-togglebutton; extra == "docs"
|
84
|
+
Requires-Dist: sphinx-favicon; extra == "docs"
|
85
|
+
Requires-Dist: sphinx-prompt; extra == "docs"
|
86
|
+
Requires-Dist: sphinxext.opengraph; extra == "docs"
|
87
|
+
Requires-Dist: sphinx-sitemap; extra == "docs"
|
88
|
+
Requires-Dist: jupyterlite-sphinx; extra == "docs"
|
89
|
+
Requires-Dist: jupyterlite-pyodide-kernel; extra == "docs"
|
90
|
+
Requires-Dist: nbformat; extra == "docs"
|
91
|
+
Dynamic: license-file
|
89
92
|
|
90
93
|
.. -*- mode: rst -*-
|
91
94
|
|
@@ -128,8 +131,9 @@ Requires-Dist: ruff ; extra == 'tests'
|
|
128
131
|
.. |NumpyMinVersion| replace:: 1.23.4
|
129
132
|
.. |ScipyMinVersion| replace:: 1.8.0
|
130
133
|
.. |PandasMinVersion| replace:: 1.4.1
|
131
|
-
.. |
|
132
|
-
.. |
|
134
|
+
.. |CvxpyBaseMinVersion| replace:: 1.5.0
|
135
|
+
.. |ClarabelMinVersion| replace:: 0.9.0
|
136
|
+
.. |SklearnMinVersion| replace:: 1.6.0
|
133
137
|
.. |JoblibMinVersion| replace:: 1.3.2
|
134
138
|
.. |PlotlyMinVersion| replace:: 5.22.0
|
135
139
|
|
@@ -147,7 +151,7 @@ Requires-Dist: ruff ; extra == 'tests'
|
|
147
151
|
It offers a unified interface and tools compatible with scikit-learn to build, fine-tune,
|
148
152
|
and cross-validate portfolio models.
|
149
153
|
|
150
|
-
It is distributed under the open
|
154
|
+
It is distributed under the open-source 3-Clause BSD license.
|
151
155
|
|
152
156
|
.. image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/expo.jpg
|
153
157
|
:target: https://skfolio.org/auto_examples/
|
@@ -179,7 +183,8 @@ Dependencies
|
|
179
183
|
- numpy (>= |NumpyMinVersion|)
|
180
184
|
- scipy (>= |ScipyMinVersion|)
|
181
185
|
- pandas (>= |PandasMinVersion|)
|
182
|
-
- cvxpy (>= |
|
186
|
+
- cvxpy-base (>= |CvxpyBaseMinVersion|)
|
187
|
+
- clarabel (>= |ClarabelMinVersion|)
|
183
188
|
- scikit-learn (>= |SklearnMinVersion|)
|
184
189
|
- joblib (>= |JoblibMinVersion|)
|
185
190
|
- plotly (>= |PlotlyMinVersion|)
|
@@ -193,7 +198,7 @@ Unfortunately, it faces a number of shortcomings, including high sensitivity to
|
|
193
198
|
input parameters (expected returns and covariance), weight concentration, high turnover,
|
194
199
|
and poor out-of-sample performance.
|
195
200
|
|
196
|
-
It is well
|
201
|
+
It is well-known that naive allocation (1/N, inverse-vol, etc.) tends to outperform
|
197
202
|
MVO out-of-sample (DeMiguel, 2007).
|
198
203
|
|
199
204
|
Numerous approaches have been developed to alleviate these shortcomings (shrinkage,
|
@@ -202,10 +207,10 @@ approaches, coherent risk measures, left-tail risk optimization, distributionall
|
|
202
207
|
optimization, factor model, risk-parity, hierarchical clustering, ensemble methods,
|
203
208
|
pre-selection, etc.).
|
204
209
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
210
|
+
Given the large number of methods, and the fact that they can be combined, there is a
|
211
|
+
need for a unified framework with a machine-learning approach to perform model
|
212
|
+
selection, validation, and parameter tuning while mitigating the risk of data leakage
|
213
|
+
and overfitting.
|
209
214
|
|
210
215
|
This framework is built on scikit-learn's API.
|
211
216
|
|
@@ -255,10 +260,27 @@ Available models
|
|
255
260
|
* Distance Correlation
|
256
261
|
* Variation of Information
|
257
262
|
|
263
|
+
* Distribution Estimator:
|
264
|
+
* Univariate:
|
265
|
+
* Gaussian
|
266
|
+
* Student's t
|
267
|
+
* Johnson Su
|
268
|
+
* Normal Inverse Gaussian
|
269
|
+
* Bivariate Copula
|
270
|
+
* Gaussian Copula
|
271
|
+
* Student's t Copula
|
272
|
+
* Clayton Copula
|
273
|
+
* Gumbel Copula
|
274
|
+
* Joe Copula
|
275
|
+
* Independent Copula
|
276
|
+
* Multivariate
|
277
|
+
* Vine Copula (Regular, Centered, Clustered, Conditional Sampling)
|
278
|
+
|
258
279
|
* Prior Estimator:
|
259
280
|
* Empirical
|
260
281
|
* Black & Litterman
|
261
282
|
* Factor Model
|
283
|
+
* Synthetic Data (Stress Test, Factor Stress Test)
|
262
284
|
|
263
285
|
* Uncertainty Set Estimator:
|
264
286
|
* On Expected Returns:
|
@@ -266,12 +288,14 @@ Available models
|
|
266
288
|
* Circular Bootstrap
|
267
289
|
* On Covariance:
|
268
290
|
* Empirical
|
269
|
-
* Circular
|
291
|
+
* Circular Bootstrap
|
270
292
|
|
271
293
|
* Pre-Selection Transformer:
|
272
294
|
* Non-Dominated Selection
|
273
295
|
* Select K Extremes (Best or Worst)
|
274
296
|
* Drop Highly Correlated Assets
|
297
|
+
* Select Non-Expiring Assets
|
298
|
+
* Select Complete Assets (handle late inception, delisting, etc.)
|
275
299
|
|
276
300
|
* Cross-Validation and Model Selection:
|
277
301
|
* Compatible with all `sklearn` methods (KFold, etc.)
|
@@ -316,6 +340,8 @@ Available models
|
|
316
340
|
* Budget Constraints
|
317
341
|
* Tracking Error Constraints
|
318
342
|
* Turnover Constraints
|
343
|
+
* Cardinality and Group Cardinality Constraints
|
344
|
+
* Threshold (Long and Short) Constraints
|
319
345
|
|
320
346
|
Quickstart
|
321
347
|
~~~~~~~~~~
|
@@ -338,6 +364,7 @@ Imports
|
|
338
364
|
|
339
365
|
from skfolio import RatioMeasure, RiskMeasure
|
340
366
|
from skfolio.datasets import load_factors_dataset, load_sp500_dataset
|
367
|
+
from skfolio.distribution import VineCopula
|
341
368
|
from skfolio.model_selection import (
|
342
369
|
CombinatorialPurgedCV,
|
343
370
|
WalkForward,
|
@@ -358,7 +385,7 @@ Imports
|
|
358
385
|
)
|
359
386
|
from skfolio.pre_selection import SelectKExtremes
|
360
387
|
from skfolio.preprocessing import prices_to_returns
|
361
|
-
from skfolio.prior import BlackLitterman, EmpiricalPrior, FactorModel
|
388
|
+
from skfolio.prior import BlackLitterman, EmpiricalPrior, FactorModel, SyntheticData
|
362
389
|
from skfolio.uncertainty_set import BootstrapMuUncertaintySet
|
363
390
|
|
364
391
|
Load Dataset
|
@@ -629,12 +656,61 @@ Combinatorial Purged Cross-Validation
|
|
629
656
|
print(population.summary())
|
630
657
|
|
631
658
|
|
659
|
+
Minimum CVaR Optimization on Synthetic Returns
|
660
|
+
----------------------------------------------
|
661
|
+
.. code-block:: python
|
662
|
+
|
663
|
+
vine = VineCopula(log_transform=True, n_jobs=-1)
|
664
|
+
prior = =SyntheticData(distribution_estimator=vine, n_samples=2000)
|
665
|
+
model = MeanRisk(risk_measure=RiskMeasure.CVAR, prior_estimator=prior)
|
666
|
+
model.fit(X)
|
667
|
+
print(model.weights_)
|
668
|
+
|
669
|
+
|
670
|
+
Stress Test
|
671
|
+
-----------
|
672
|
+
.. code-block:: python
|
673
|
+
|
674
|
+
vine = VineCopula(log_transform=True, central_assets=["BAC"] n_jobs=-1)
|
675
|
+
vine.fit(X)
|
676
|
+
X_stressed = vine.sample(n_samples=10_000, conditioning = {"BAC": -0.2})
|
677
|
+
ptf_stressed = model.predict(X_stressed)
|
678
|
+
|
679
|
+
|
680
|
+
Minimum CVaR Optimization on Synthetic Factors
|
681
|
+
----------------------------------------------
|
682
|
+
.. code-block:: python
|
683
|
+
|
684
|
+
vine = VineCopula(central_assets=["QUAL"], log_transform=True, n_jobs=-1)
|
685
|
+
factor_prior = SyntheticData(
|
686
|
+
distribution_estimator=vine,
|
687
|
+
n_samples=10_000,
|
688
|
+
sample_args=dict(conditioning={"QUAL": -0.2}),
|
689
|
+
)
|
690
|
+
factor_model = FactorModel(factor_prior_estimator=factor_prior)
|
691
|
+
model = MeanRisk(risk_measure=RiskMeasure.CVAR, prior_estimator=factor_model)
|
692
|
+
model.fit(X, y)
|
693
|
+
print(model.weights_)
|
694
|
+
|
695
|
+
|
696
|
+
Factor Stress Test
|
697
|
+
------------------
|
698
|
+
.. code-block:: python
|
699
|
+
|
700
|
+
factor_model.set_params(factor_prior_estimator__sample_args=dict(
|
701
|
+
conditioning={"QUAL": -0.5}
|
702
|
+
))
|
703
|
+
factor_model.fit(X,y)
|
704
|
+
stressed_X = factor_model.prior_model_.returns
|
705
|
+
stressed_ptf = model.predict(stressed_X)
|
706
|
+
|
707
|
+
|
632
708
|
Recognition
|
633
709
|
~~~~~~~~~~~
|
634
710
|
|
635
|
-
We would like to thank all contributors
|
636
|
-
scikit-learn and cvxpy,
|
637
|
-
|
711
|
+
We would like to thank all contributors to our direct dependencies, such as
|
712
|
+
scikit-learn and cvxpy, as well as the contributors of the following resources that
|
713
|
+
served as sources of inspiration:
|
638
714
|
|
639
715
|
* PyPortfolioOpt
|
640
716
|
* Riskfolio-Lib
|
@@ -0,0 +1,120 @@
|
|
1
|
+
skfolio/__init__.py,sha256=XdSV1bcfft5pNl5Y_mX8MR0IzjXjRs8uRURp42UGa08,635
|
2
|
+
skfolio/exceptions.py,sha256=omi5qQiEuFDpIoZfQHQxORZRcKYkusmdGPLBJt-Sna0,805
|
3
|
+
skfolio/typing.py,sha256=5wnu_qoGZtCWKu-nHlZ5w3rOKy5CXxGI5ZvzDSR9pLU,1394
|
4
|
+
skfolio/cluster/__init__.py,sha256=ycySaq2MgG3etqNF-pITuYKfYPHYm3-frjFc8PRzMc0,267
|
5
|
+
skfolio/cluster/_hierarchical.py,sha256=PTtr6H4keY6DEVvXyYM24AnNjj72sNaXKjGFEyMXZ5c,12839
|
6
|
+
skfolio/datasets/__init__.py,sha256=hxeG8dQOQWzlsKagxyAp2nX67wj7fAD-UZtv36xzMIE,497
|
7
|
+
skfolio/datasets/_base.py,sha256=n95CwIYEgh4cShFUItph7Prgv5XkndhBZ0OdOIE66Wk,16088
|
8
|
+
skfolio/datasets/data/__init__.py,sha256=XN1VFRn8-YLCbu6avsq21aUA94gN5f0WX0I5riTsNEk,27
|
9
|
+
skfolio/datasets/data/factors_dataset.csv.gz,sha256=brCJlT25DJo40yg1gnUXAakNtvWZZYR_1ksFeN5JcWE,36146
|
10
|
+
skfolio/datasets/data/sp500_dataset.csv.gz,sha256=7iHKwovvsdCnOanOsiGE-ZU5RyaqDP3pohlB0awErA0,426065
|
11
|
+
skfolio/datasets/data/sp500_index.csv.gz,sha256=iUw0QxwoT4aqZKRn4Xbio8m2l8hX65qzUAbC3VXT_fI,41898
|
12
|
+
skfolio/distance/__init__.py,sha256=KFDHNcpzA8Hng0xAs9JyFEkbDRubgeDrQUP4B2ZwYjw,563
|
13
|
+
skfolio/distance/_base.py,sha256=3qqkWfqb3igC6Y7XHwPYir9A2qwi2LjCtLlczMGi6UI,1343
|
14
|
+
skfolio/distance/_distance.py,sha256=-ztyE8oittGfn-ib4-JztAXxeIQ4QLAOj4OX4AJ2G64,19107
|
15
|
+
skfolio/distribution/__init__.py,sha256=A42xmx-VjMSy-An6ZIdhwPLFAoViCaOY7KUQDHgaOAY,1295
|
16
|
+
skfolio/distribution/_base.py,sha256=YEnJsLSO-_NkucUNKSaW9ZTwoORXFj7DWnFrxwaYaco,5665
|
17
|
+
skfolio/distribution/copula/__init__.py,sha256=dKN-BGl5t5EXlVb7Qamkktbj1V098Ocf3J6qNlRssI4,1106
|
18
|
+
skfolio/distribution/copula/_base.py,sha256=1N3I2lFuzm5ge1zG9VZWufIwwMKf8oE1OT_PtVEPyHo,15982
|
19
|
+
skfolio/distribution/copula/_clayton.py,sha256=xat9ZyhV3FbWcDVn6ax6Z8YGuOsHTKGVUXXNxxCqhcQ,18307
|
20
|
+
skfolio/distribution/copula/_gaussian.py,sha256=-OxQdvFEBesozIPofBG_X0j1tDmwlu4i9bpxnV7iqS4,14128
|
21
|
+
skfolio/distribution/copula/_gumbel.py,sha256=KIhyfGyF9jLRKqZo8D5k19k3Wgw9X6hX1o9pVDxzG00,19354
|
22
|
+
skfolio/distribution/copula/_independent.py,sha256=OIqmig7hP-KTCuBi0bsb4fwEkQkaxipYoy1JR1xer6w,6360
|
23
|
+
skfolio/distribution/copula/_joe.py,sha256=kSqPqMyyyNTgPEGSnlOm8drrRqMRhV2fNuJw1daxcMc,21446
|
24
|
+
skfolio/distribution/copula/_selection.py,sha256=JovKO2_Vq9Zq1WFArFTeKXSDVLFJtCRB8qi3N7vhnRM,4438
|
25
|
+
skfolio/distribution/copula/_student_t.py,sha256=Zl5WlmZ5fum2v6CH4VyVPln7Aivo_49Jj5hHcYlNQfU,17821
|
26
|
+
skfolio/distribution/copula/_utils.py,sha256=drMtv71bkwlerR0HJCdNCZTuFSitN5vn33avRGWxj94,16440
|
27
|
+
skfolio/distribution/multivariate/__init__.py,sha256=E9AR0Hh5wWShOTwj62R1RVMkzZpXc5Ams4ppibwhrUY,339
|
28
|
+
skfolio/distribution/multivariate/_base.py,sha256=MV3rhTafPlKdb3wuLbHfhApyV1ll7WmfzdR97Dq8VZw,8716
|
29
|
+
skfolio/distribution/multivariate/_utils.py,sha256=WNL1lzO0Ki5x_yO8p3GRKrXwG4fK99je7sDQ3avyUQ8,19274
|
30
|
+
skfolio/distribution/multivariate/_vine_copula.py,sha256=b545CKAMXUXMaIiI7hQ-P8jHhmZ4hUnGo2F22uWtbac,49756
|
31
|
+
skfolio/distribution/univariate/__init__.py,sha256=m9vZUhZyRUT5IOQRixGPdGci1wtC5ua8RWtHsC8HAlU,628
|
32
|
+
skfolio/distribution/univariate/_base.py,sha256=8oPMOdQi2wHc-UOWG18x_eZ57G_ksQhPM9C0ncYf1Lg,9874
|
33
|
+
skfolio/distribution/univariate/_gaussian.py,sha256=pe8YxTQjvObeVeZD2YXduN5M-k2kNNTy2q0AvYCm1n4,4274
|
34
|
+
skfolio/distribution/univariate/_johnson_su.py,sha256=Dl1WyCmn-sRE4BrckVNGXHz9biDQtXyPq1JXEPKIHBo,4857
|
35
|
+
skfolio/distribution/univariate/_normal_inverse_gaussian.py,sha256=oq5omNUQanFWBGaYSNwf9YDa6c-B1j9ZErq6p96resc,4983
|
36
|
+
skfolio/distribution/univariate/_selection.py,sha256=6KL4gngiLKwaBUpCDX19ABOkMBzZp1YVRnXFrUtppCs,3110
|
37
|
+
skfolio/distribution/univariate/_student_t.py,sha256=GcI4fKp6q5XegfvT_i3AqfWlUMxCq7A5sX6Xsf4pye8,4553
|
38
|
+
skfolio/measures/__init__.py,sha256=lB5xBqEFU-8x-12AA1VdCHaPwYpfwvejRaiYnr8IGYg,1647
|
39
|
+
skfolio/measures/_enums.py,sha256=S6WOT8NHzm-eMHELuOjngIBupCctCdiTA2BaJlWl-4E,8956
|
40
|
+
skfolio/measures/_measures.py,sha256=LmKgSAOXaKGomAcO1FkeypD6tRiEeDLUIh6lySky4vs,16835
|
41
|
+
skfolio/metrics/__init__.py,sha256=ebu5h7Q9X0f3ZZ1VFmAEBPic2sirboKG_zNBHO5abjo,98
|
42
|
+
skfolio/metrics/_scorer.py,sha256=L-qct4cby15a4xC4arSaG5__1mxBCQYeMjlrHBIVnSY,4325
|
43
|
+
skfolio/model_selection/__init__.py,sha256=BT8VCXW7C4bXI2Oam4amTHOcJVlKxLpkcsHjB63pZHQ,524
|
44
|
+
skfolio/model_selection/_combinatorial.py,sha256=XVbZuVA0ePEYpbKiyioQcNULtEEm5KM0Bc_-AvzQTtk,19109
|
45
|
+
skfolio/model_selection/_validation.py,sha256=fM3PnB9O6JrgyEznf4-yvmFLz-z0trOoYSKkMLzWqVc,10051
|
46
|
+
skfolio/model_selection/_walk_forward.py,sha256=Q_RV2Aw4J7nB5UhhrWuWcoYmyxc9CN45yL3vpyfuFGo,15060
|
47
|
+
skfolio/moments/__init__.py,sha256=st8AYX3tHT2ZkqnnMNbS6CiwufvHq6Tl6nHtRVhtlq0,794
|
48
|
+
skfolio/moments/covariance/__init__.py,sha256=twNNLP44sv4-3EgET27UdJ-8wbVgF2cYmIn8DERwFTk,1068
|
49
|
+
skfolio/moments/covariance/_base.py,sha256=vrYW0q1tG-l_uvnRk1TBTlQnamdmMXdJOZutRrRl08M,3986
|
50
|
+
skfolio/moments/covariance/_denoise_covariance.py,sha256=mXjcEYZn9HXVTkiUn4CkKM9Jy27XLOnweInbyu4f-_o,7002
|
51
|
+
skfolio/moments/covariance/_detone_covariance.py,sha256=Yw24UA68mw4yHe_utOD4FpOdWfV8kFXAMCNLZgGLD8c,6109
|
52
|
+
skfolio/moments/covariance/_empirical_covariance.py,sha256=ayIr0yn3oJS_H9LpHNCfHwttSGry3lR6_umXE_nE6tg,3560
|
53
|
+
skfolio/moments/covariance/_ew_covariance.py,sha256=z0-mcnewjKya8uz8JOO9BkS5xkSgTI1sG0ndJVScn1o,3732
|
54
|
+
skfolio/moments/covariance/_gerber_covariance.py,sha256=IHO4wcefrbvTUECrkEEnL_UOQSHNRLTrj6arrDKk73o,5915
|
55
|
+
skfolio/moments/covariance/_graphical_lasso_cv.py,sha256=vCQxDsqxJlNHUAs_ETPPW1y_v_5Zp0ePZC2NkTNmM-s,6555
|
56
|
+
skfolio/moments/covariance/_implied_covariance.py,sha256=ioXg1oThiOAHHZVZh3upPdDVJcCzACe831ypPXlZoM8,17625
|
57
|
+
skfolio/moments/covariance/_ledoit_wolf.py,sha256=bCorMMeQ7137QDKDW_TUzDiC0DdcRAvzRPoKL5EMCX8,4891
|
58
|
+
skfolio/moments/covariance/_oas.py,sha256=V9FAE4-VsiOXpAA5tGilphA32hfPolfzfoI974jLEY4,3700
|
59
|
+
skfolio/moments/covariance/_shrunk_covariance.py,sha256=URJgonaWoiOUQcSrtN1LUrJtdi4tCrwiuNUg-FaDNvE,3111
|
60
|
+
skfolio/moments/expected_returns/__init__.py,sha256=Bi3c4bok3SyktdYeFUs3VepTrtpmDITIk9GXPhIuDc0,504
|
61
|
+
skfolio/moments/expected_returns/_base.py,sha256=Bla1peGBVafIUwOxNuRF5-T84k-QHN8Z2W6mdLoSbzU,887
|
62
|
+
skfolio/moments/expected_returns/_empirical_mu.py,sha256=KLwO_9HCK7H6eiB9JU5EdLWcMqD2Vr7wcSjXONJk1Cg,1879
|
63
|
+
skfolio/moments/expected_returns/_equilibrium_mu.py,sha256=A4zAYZ7ex2Y68YV0HajYDKtnH0luQuKEN4hENEwk4Lk,4423
|
64
|
+
skfolio/moments/expected_returns/_ew_mu.py,sha256=vDOqpTpTY3iaJc9PfMU_dpdfglT1dJ_DuM3pCTpjHpc,2125
|
65
|
+
skfolio/moments/expected_returns/_shrunk_mu.py,sha256=nqypZJweZIf6u3Idz-TLPHiD3h3XzuKgTEQWJHSVnwo,8292
|
66
|
+
skfolio/optimization/__init__.py,sha256=LA4n85e-wVTeRNI-NlTU1ID5FhP3-B410kmsh9268Ho,1049
|
67
|
+
skfolio/optimization/_base.py,sha256=lPVvoV36URnjMUJGOO23QbaFYiuyVA9oRuvk68Dwd7o,5780
|
68
|
+
skfolio/optimization/cluster/__init__.py,sha256=nxsuDxviDbj-YMHhQXIkUEWUoKPhPn10bQ0_nULNUoE,424
|
69
|
+
skfolio/optimization/cluster/_nco.py,sha256=Gbd18HYlwq_MUd9JmytM1-Uqu-GFT8NXb8QWPVgmDxk,16433
|
70
|
+
skfolio/optimization/cluster/hierarchical/__init__.py,sha256=eT1A6YKETKCBEnrUc6pHwyTkDVRcUr8jtdtmN3kdh0c,446
|
71
|
+
skfolio/optimization/cluster/hierarchical/_base.py,sha256=mdplfuwUepui8RWPlySxoviuA0PNIkgn6wSYENNy9H0,16295
|
72
|
+
skfolio/optimization/cluster/hierarchical/_herc.py,sha256=5ZYkoi8ywN89U2xi1lc-3B8TPQjLlxbUmOSB3PR_nKA,20414
|
73
|
+
skfolio/optimization/cluster/hierarchical/_hrp.py,sha256=06kch9QkthV5yB8RNB_5Xz-IUuNq-fcZPjz99Mz5otg,18171
|
74
|
+
skfolio/optimization/convex/__init__.py,sha256=q1Q2p7HcnmbQlBIA0SXm0TwDGxl7hRc0JhF1o01lFSg,605
|
75
|
+
skfolio/optimization/convex/_base.py,sha256=mUTXVM6bq5cvlieAl6TXNGd6BNIqBajoAiDL28fPx9o,89455
|
76
|
+
skfolio/optimization/convex/_distributionally_robust.py,sha256=4iWfEuJGuBawVGU5X1-QHVMMh9hBnMtou2Uh5hRdXeA,17958
|
77
|
+
skfolio/optimization/convex/_maximum_diversification.py,sha256=a8nDecN6jTR_bOFKBsenI4G2kNu5t98y5ALY78lNrAU,19657
|
78
|
+
skfolio/optimization/convex/_mean_risk.py,sha256=mM5KMCxwAf1dT6JTxJuuQfvvk63hMQg5GD3LumQkfjQ,49534
|
79
|
+
skfolio/optimization/convex/_risk_budgeting.py,sha256=xtRg3CGmasi-ebx7e5XevHJs3n9PpccaZR7Z7loyKDc,23653
|
80
|
+
skfolio/optimization/ensemble/__init__.py,sha256=IJhsX8f-6wclc9a6Fd8yAQvZKxtxq4Qf7AC2CLryHrU,195
|
81
|
+
skfolio/optimization/ensemble/_base.py,sha256=e0dWCEIYnho3HU2KGGS9UHQdycdVuqMcTe7hi0LihjQ,3416
|
82
|
+
skfolio/optimization/ensemble/_stacking.py,sha256=DaswFVBTghP10vHGESn6aLT7C9wgp-D8NuXGtpdZcwE,14192
|
83
|
+
skfolio/optimization/naive/__init__.py,sha256=1QKgOuA6DoqKVOsJxWKogaGPyOir6ln-aQ28PTAbtJs,181
|
84
|
+
skfolio/optimization/naive/_naive.py,sha256=w5lDVpn5YeO6NN5dRzSRvj-V6GpfLogOW7FVxevwZl8,6453
|
85
|
+
skfolio/population/__init__.py,sha256=ehKwWhDJCifjhEL-QezVR0xYjzRTeyHbrEMbfWjF9cU,106
|
86
|
+
skfolio/population/_population.py,sha256=jmfy759zm5Z0ReRBaHMHCaPHEOf8AFxqXVzYrNhaVIw,31354
|
87
|
+
skfolio/portfolio/__init__.py,sha256=YeDSH0ZdyE-lcbDqpNw9IOltURtoM-ewAzzcec44Q5Q,586
|
88
|
+
skfolio/portfolio/_base.py,sha256=V81HUQ2CWmohGOeNip1dPESGnmRKQk8eDAthjkvVFhQ,40541
|
89
|
+
skfolio/portfolio/_multi_period_portfolio.py,sha256=9z71aZL2GrV6rQ_EkIyPkK-mJ9N2ZLZCIinSScfRgfw,24412
|
90
|
+
skfolio/portfolio/_portfolio.py,sha256=o1e1KNZAuxlC8y3zTIcaW7c2jk_LlEBCzEF8FRJht20,32791
|
91
|
+
skfolio/pre_selection/__init__.py,sha256=3hqxwd8nAa1dBna5MrE1P5JPrM-OkSvXGyhbMq7ZKIk,511
|
92
|
+
skfolio/pre_selection/_drop_correlated.py,sha256=4-PSd8R20Rcdyc8Zzcy9B2eRPEtaEkM3YXi74YKF-Pk,3839
|
93
|
+
skfolio/pre_selection/_select_complete.py,sha256=2nEvcjROMJzhAHMCHADeAiCws_tc-BMtndIkjRexL84,3902
|
94
|
+
skfolio/pre_selection/_select_k_extremes.py,sha256=nMugK88igmscribCw_I1UnjE_O7cuIjrJF8AGuVTfiA,3082
|
95
|
+
skfolio/pre_selection/_select_non_dominated.py,sha256=Auv7G8E1QNO96heb35oBWmFLd68LlVDRgSpcg7wpv5A,6004
|
96
|
+
skfolio/pre_selection/_select_non_expiring.py,sha256=hVXLNw5KBU7WxOI6v4feZ9lJaVIgl-CBhW80T9-ZUac,5105
|
97
|
+
skfolio/preprocessing/__init__.py,sha256=94jMyP_E7FlwQVE8D_bXDi8KyfAA2xPHTDvYOi6zf_g,123
|
98
|
+
skfolio/preprocessing/_returns.py,sha256=6G5qJIVHGnIoeBNAqpJTB-569g9NeXVIyrz033bK5Gk,4576
|
99
|
+
skfolio/prior/__init__.py,sha256=daUO3ha87Nu0ixJci33dR1dKgoYC6-1Nf3AUoaskE5o,544
|
100
|
+
skfolio/prior/_base.py,sha256=Py3Ip3mDhaDyBVWQy9Mz7ztv3RkovVC58gw4rCcC-jU,1958
|
101
|
+
skfolio/prior/_black_litterman.py,sha256=oMNYNyDSBp8Uygp0EvQissjNKS41GMLCVzITUqA0HeY,10470
|
102
|
+
skfolio/prior/_empirical.py,sha256=jDWgNhCfqOFVbVBphACZsqpK47OPOKGUCnOVsgmdqXI,7324
|
103
|
+
skfolio/prior/_factor_model.py,sha256=GhilLpNu8UdPrj5vb63zKJ9WWnt79k3SpNf6ULqZ8Bk,11571
|
104
|
+
skfolio/prior/_synthetic_data.py,sha256=XhavOTbbwBtO1suoA4pfZnm5YAdlykb07NQvvqPpRxo,8551
|
105
|
+
skfolio/synthetic_returns/__init__.py,sha256=-dnmFSmrTJcsMmrwIxPCbqENbx6gTuWAm_cx7nQHpns,29
|
106
|
+
skfolio/uncertainty_set/__init__.py,sha256=SHbOq0ip3vuwEK9G4pzz0GncDbGsHw7ywF9tPnkUrZ8,648
|
107
|
+
skfolio/uncertainty_set/_base.py,sha256=R6qH8Zg5Ti3Qny-guL4Js8rY9JhpF8jMwV_w9HCbgWI,4307
|
108
|
+
skfolio/uncertainty_set/_bootstrap.py,sha256=tDnUvhTtl0HWu-xL6MWZZZyWs4Y06PKQ5xPDiOU7RE4,11265
|
109
|
+
skfolio/uncertainty_set/_empirical.py,sha256=t9_V23gH1eJ0jaASQcus-QOSATAr9HKVW2hjHMNYjO0,9380
|
110
|
+
skfolio/utils/__init__.py,sha256=bC6-MsCVF7xKTr48z7OzJJUeWvqAB7BiHeNTiKsme70,20
|
111
|
+
skfolio/utils/bootstrap.py,sha256=6BN_9CgfbeImBSNEE0dF52FRGuQT41HcQXeHPLwFqJc,3565
|
112
|
+
skfolio/utils/equations.py,sha256=yj6-TReoPq3YaUQyAx-t4wZNbODON2T4TyA82z2SnkU,15577
|
113
|
+
skfolio/utils/sorting.py,sha256=F7gfIBfnulfDUiqvzrlR-pba4PPLJT6NH7-5s4sdRhw,3521
|
114
|
+
skfolio/utils/stats.py,sha256=glVHo7rjwy06dl5kkULLOADMrEkVJcfXXAz-1qmYQL4,17005
|
115
|
+
skfolio/utils/tools.py,sha256=sGJFiqc60TqXyaWoH7JdsbaFYj_bvwq3hHIk6FxDC3U,22994
|
116
|
+
skfolio-0.8.0.dist-info/licenses/LICENSE,sha256=F6Gi-ZJX5BlVzYK8R9NcvAkAsKa7KO29xB1OScbrH6Q,1526
|
117
|
+
skfolio-0.8.0.dist-info/METADATA,sha256=2I3oPRJjRLU5M_KQRaAx9xmrcARPZbaMuE8qu2RdSAE,22383
|
118
|
+
skfolio-0.8.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
119
|
+
skfolio-0.8.0.dist-info/top_level.txt,sha256=NXEaoS9Ms7t32gxkb867nV0OKlU0KmssL7IJBVo0fJs,8
|
120
|
+
skfolio-0.8.0.dist-info/RECORD,,
|