skfolio 0.9.0__py3-none-any.whl → 0.10.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/distribution/multivariate/_vine_copula.py +35 -34
- skfolio/distribution/univariate/_base.py +20 -15
- skfolio/exceptions.py +5 -0
- skfolio/measures/__init__.py +2 -0
- skfolio/measures/_measures.py +390 -155
- skfolio/optimization/_base.py +21 -4
- skfolio/optimization/cluster/hierarchical/_base.py +16 -13
- skfolio/optimization/cluster/hierarchical/_herc.py +6 -6
- skfolio/optimization/cluster/hierarchical/_hrp.py +8 -6
- skfolio/optimization/convex/_base.py +238 -144
- skfolio/optimization/convex/_distributionally_robust.py +32 -20
- skfolio/optimization/convex/_maximum_diversification.py +15 -18
- skfolio/optimization/convex/_mean_risk.py +35 -25
- skfolio/optimization/convex/_risk_budgeting.py +23 -21
- skfolio/optimization/ensemble/__init__.py +2 -4
- skfolio/optimization/ensemble/_stacking.py +1 -1
- skfolio/optimization/naive/_naive.py +2 -2
- skfolio/population/_population.py +30 -9
- skfolio/portfolio/_base.py +68 -26
- skfolio/portfolio/_multi_period_portfolio.py +5 -0
- skfolio/portfolio/_portfolio.py +5 -0
- skfolio/pre_selection/_select_non_expiring.py +1 -1
- skfolio/prior/__init__.py +6 -2
- skfolio/prior/_base.py +7 -3
- skfolio/prior/_black_litterman.py +14 -12
- skfolio/prior/_empirical.py +8 -7
- skfolio/prior/_entropy_pooling.py +1493 -0
- skfolio/prior/_factor_model.py +39 -22
- skfolio/prior/_opinion_pooling.py +475 -0
- skfolio/prior/_synthetic_data.py +10 -8
- skfolio/uncertainty_set/_bootstrap.py +4 -4
- skfolio/uncertainty_set/_empirical.py +6 -6
- skfolio/utils/equations.py +11 -5
- skfolio/utils/figure.py +185 -0
- skfolio/utils/tools.py +4 -2
- {skfolio-0.9.0.dist-info → skfolio-0.10.0.dist-info}/METADATA +94 -5
- {skfolio-0.9.0.dist-info → skfolio-0.10.0.dist-info}/RECORD +41 -39
- {skfolio-0.9.0.dist-info → skfolio-0.10.0.dist-info}/WHEEL +1 -1
- skfolio/synthetic_returns/__init__.py +0 -1
- /skfolio/{optimization/ensemble/_base.py → utils/composition.py} +0 -0
- {skfolio-0.9.0.dist-info → skfolio-0.10.0.dist-info}/licenses/LICENSE +0 -0
- {skfolio-0.9.0.dist-info → skfolio-0.10.0.dist-info}/top_level.txt +0 -0
@@ -124,11 +124,11 @@ class EmpiricalMuUncertaintySet(BaseMuUncertaintySet):
|
|
124
124
|
# fitting estimators
|
125
125
|
self.prior_estimator_.fit(X, y, **routed_params.prior_estimator.fit)
|
126
126
|
|
127
|
-
|
128
|
-
n_observations, n_assets =
|
127
|
+
return_distribution = self.prior_estimator_.return_distribution_
|
128
|
+
n_observations, n_assets = return_distribution.returns.shape
|
129
129
|
k = np.sqrt(st.chi2.ppf(q=self.confidence_level, df=n_assets))
|
130
130
|
|
131
|
-
sigma =
|
131
|
+
sigma = return_distribution.covariance / n_observations
|
132
132
|
if self.diagonal:
|
133
133
|
sigma = np.diag(np.diag(sigma))
|
134
134
|
|
@@ -239,11 +239,11 @@ class EmpiricalCovarianceUncertaintySet(BaseCovarianceUncertaintySet):
|
|
239
239
|
# fitting estimators
|
240
240
|
self.prior_estimator_.fit(X, y, **routed_params.prior_estimator.fit)
|
241
241
|
|
242
|
-
|
243
|
-
n_observations, n_assets =
|
242
|
+
return_distribution = self.prior_estimator_.return_distribution_
|
243
|
+
n_observations, n_assets = return_distribution.returns.shape
|
244
244
|
k = np.sqrt(st.chi2.ppf(q=self.confidence_level, df=n_assets**2))
|
245
245
|
|
246
|
-
sigma =
|
246
|
+
sigma = return_distribution.covariance / n_observations
|
247
247
|
if self.diagonal:
|
248
248
|
sigma = np.diag(np.diag(sigma))
|
249
249
|
|
skfolio/utils/equations.py
CHANGED
@@ -103,6 +103,8 @@ def equations_to_matrix(
|
|
103
103
|
groups = _validate_groups(groups, name=names[0])
|
104
104
|
equations = _validate_equations(equations, name=names[1])
|
105
105
|
|
106
|
+
n_groups, n_assets = groups.shape
|
107
|
+
|
106
108
|
a_equality = []
|
107
109
|
b_equality = []
|
108
110
|
|
@@ -127,10 +129,14 @@ def equations_to_matrix(
|
|
127
129
|
raise
|
128
130
|
warnings.warn(str(e), stacklevel=2)
|
129
131
|
return (
|
130
|
-
np.array(a_equality)
|
131
|
-
|
132
|
-
np.
|
133
|
-
np.array(
|
132
|
+
np.array(a_equality, dtype=float)
|
133
|
+
if a_equality
|
134
|
+
else np.empty((0, n_assets), dtype=float),
|
135
|
+
np.array(b_equality, dtype=float),
|
136
|
+
np.array(a_inequality, dtype=float)
|
137
|
+
if a_inequality
|
138
|
+
else np.empty((0, n_assets), dtype=float),
|
139
|
+
np.array(b_inequality, dtype=float),
|
134
140
|
)
|
135
141
|
|
136
142
|
|
@@ -276,7 +282,7 @@ def _matching_array(values: np.ndarray, key: str, sum_to_one: bool) -> np.ndarra
|
|
276
282
|
if not arr.any():
|
277
283
|
raise EquationToMatrixError(f"Unable to find '{key}' in '{values}'")
|
278
284
|
if sum_to_one:
|
279
|
-
s =
|
285
|
+
s = arr.sum()
|
280
286
|
else:
|
281
287
|
s = 1
|
282
288
|
return arr / s
|
skfolio/utils/figure.py
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
"""Figure module."""
|
2
|
+
|
3
|
+
# Copyright (c) 2023
|
4
|
+
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
6
|
+
|
7
|
+
import numpy as np
|
8
|
+
import pandas as pd
|
9
|
+
import plotly.express as px
|
10
|
+
import plotly.graph_objects as go
|
11
|
+
import scipy.stats as st
|
12
|
+
|
13
|
+
|
14
|
+
def plot_kde_distributions(
|
15
|
+
X: pd.DataFrame,
|
16
|
+
sample_weight: np.ndarray | None = None,
|
17
|
+
percentile_cutoff: float | None = None,
|
18
|
+
title: str = "Distribution of Asset Returns",
|
19
|
+
unweighted_suffix: str = "",
|
20
|
+
weighted_suffix: str = "with Sample Weight",
|
21
|
+
) -> go.Figure:
|
22
|
+
"""
|
23
|
+
Plot the Kernel Density Estimate (KDE) of return distributions for multiple assets.
|
24
|
+
|
25
|
+
Parameters
|
26
|
+
----------
|
27
|
+
X : DataFrame of shape (n_observations, n_assets)
|
28
|
+
Return data where each column corresponds to an asset and each row to an
|
29
|
+
observation.
|
30
|
+
|
31
|
+
sample_weight : ndarray of shape (n_observations,), optional
|
32
|
+
Weights to apply to each observation when computing the KDE.
|
33
|
+
If None, equal weighting is used.
|
34
|
+
|
35
|
+
percentile_cutoff : float, default=None
|
36
|
+
Percentile cutoff for tail truncation (percentile), in percent.
|
37
|
+
- If a float p is provided, the distribution support is truncated at
|
38
|
+
the p-th and (100 - p)-th percentiles.
|
39
|
+
- If None, no truncation is applied (uses full min/max of returns).
|
40
|
+
|
41
|
+
title : str, default="Distribution of Asset Returns"
|
42
|
+
Title for the Plotly figure.
|
43
|
+
|
44
|
+
unweighted_suffix : str, default=""
|
45
|
+
Suffix to append to asset names for unweighted KDE traces.
|
46
|
+
|
47
|
+
weighted_suffix : str, default="weighted"
|
48
|
+
Suffix to append to asset names for weighted KDE traces.
|
49
|
+
|
50
|
+
Returns
|
51
|
+
-------
|
52
|
+
fig : plotly.graph_objects.Figure
|
53
|
+
A Plotly Figure object containing overlaid KDE plots for each asset,
|
54
|
+
with separate traces for weighted and unweighted distributions if weights
|
55
|
+
are provided.
|
56
|
+
"""
|
57
|
+
asset_names = X.columns.tolist()
|
58
|
+
X = X.values
|
59
|
+
colors = px.colors.qualitative.Plotly
|
60
|
+
|
61
|
+
traces: list[go.Scatter] = []
|
62
|
+
|
63
|
+
for i, asset in enumerate(asset_names):
|
64
|
+
x = X[:, i]
|
65
|
+
color = colors[i % len(colors)]
|
66
|
+
visible = True if i == 0 else "legendonly"
|
67
|
+
|
68
|
+
# Unweighted: solid line
|
69
|
+
traces.append(
|
70
|
+
kde_trace(
|
71
|
+
x=x,
|
72
|
+
sample_weight=None,
|
73
|
+
percentile_cutoff=percentile_cutoff,
|
74
|
+
name=f"{asset} {unweighted_suffix}".strip(),
|
75
|
+
line_color=color,
|
76
|
+
fill_opacity=0.17,
|
77
|
+
line_dash="solid",
|
78
|
+
line_width=1,
|
79
|
+
visible=visible,
|
80
|
+
)
|
81
|
+
)
|
82
|
+
|
83
|
+
# Weighted: dashed, thicker line
|
84
|
+
if sample_weight is not None:
|
85
|
+
traces.append(
|
86
|
+
kde_trace(
|
87
|
+
x=x,
|
88
|
+
sample_weight=sample_weight,
|
89
|
+
percentile_cutoff=percentile_cutoff,
|
90
|
+
name=f"{asset} {weighted_suffix}".strip(),
|
91
|
+
line_color=color,
|
92
|
+
fill_opacity=0.17,
|
93
|
+
line_dash="dash",
|
94
|
+
line_width=1.5,
|
95
|
+
visible=visible,
|
96
|
+
)
|
97
|
+
)
|
98
|
+
|
99
|
+
fig = go.Figure(data=traces)
|
100
|
+
fig.update_layout(
|
101
|
+
title=title,
|
102
|
+
xaxis_title="Returns",
|
103
|
+
yaxis_title="Probability Density",
|
104
|
+
)
|
105
|
+
fig.update_xaxes(tickformat=".0%")
|
106
|
+
return fig
|
107
|
+
|
108
|
+
|
109
|
+
def kde_trace(
|
110
|
+
x: np.ndarray,
|
111
|
+
sample_weight: np.ndarray | None,
|
112
|
+
percentile_cutoff: float | None,
|
113
|
+
name: str,
|
114
|
+
line_color: str,
|
115
|
+
fill_opacity: float,
|
116
|
+
line_dash: str,
|
117
|
+
line_width: float,
|
118
|
+
visible: bool,
|
119
|
+
) -> go.Scatter:
|
120
|
+
"""
|
121
|
+
Create a Plotly Scatter trace representing a Gaussian kernel density estimate (KDE),
|
122
|
+
with customizable line style and fill opacity.
|
123
|
+
|
124
|
+
Parameters
|
125
|
+
----------
|
126
|
+
x : ndarray of shape (n_observations,)
|
127
|
+
One-dimensional array of sample values for which the KDE is computed.
|
128
|
+
|
129
|
+
sample_weight : ndarray of shape (n_observations,), optional
|
130
|
+
Weights to apply to each observation when computing the KDE.
|
131
|
+
If None, equal weighting is used.
|
132
|
+
|
133
|
+
percentile_cutoff : float, default=None
|
134
|
+
Percentile cutoff for tail truncation (percentile), in percent.
|
135
|
+
- If a float p is provided, the distribution support is truncated at
|
136
|
+
the p-th and (100 - p)-th percentiles.
|
137
|
+
- If None, no truncation is applied (uses full min/max of returns).
|
138
|
+
|
139
|
+
name : str
|
140
|
+
Legend name for this trace.
|
141
|
+
|
142
|
+
line_color : str
|
143
|
+
Color of the KDE line (hex or named CSS color).
|
144
|
+
|
145
|
+
fill_opacity : float
|
146
|
+
Opacity of the filled area under the curve (0 to 1).
|
147
|
+
|
148
|
+
line_dash : str
|
149
|
+
Dash style for the line ("solid", "dash", "dot", etc.).
|
150
|
+
|
151
|
+
line_width : float
|
152
|
+
Width of the line.
|
153
|
+
|
154
|
+
visible : bool
|
155
|
+
Initial visibility of the trace in the Plotly figure.
|
156
|
+
|
157
|
+
Returns
|
158
|
+
-------
|
159
|
+
go.Scatter
|
160
|
+
A Plotly Scatter trace with the KDE line and shaded area under the curve.
|
161
|
+
"""
|
162
|
+
if percentile_cutoff is None:
|
163
|
+
lower, upper = x.min(), x.max()
|
164
|
+
else:
|
165
|
+
lower = np.percentile(x, percentile_cutoff)
|
166
|
+
upper = np.percentile(x, 100.0 - percentile_cutoff)
|
167
|
+
|
168
|
+
xs = np.linspace(lower, upper, 500)
|
169
|
+
ys = st.gaussian_kde(x, weights=sample_weight)(xs)
|
170
|
+
|
171
|
+
# build RGBA fill color from the line_color hex
|
172
|
+
r, g, b = tuple(int(line_color.lstrip("#")[i : i + 2], 16) for i in (0, 2, 4))
|
173
|
+
fill_color = f"rgba({r},{g},{b},{fill_opacity})"
|
174
|
+
|
175
|
+
return go.Scatter(
|
176
|
+
x=xs,
|
177
|
+
y=ys,
|
178
|
+
mode="lines",
|
179
|
+
name=name,
|
180
|
+
visible=visible,
|
181
|
+
line=dict(color=line_color, dash=line_dash, width=line_width),
|
182
|
+
fill="tozeroy",
|
183
|
+
fillcolor=fill_color,
|
184
|
+
opacity=1.0,
|
185
|
+
)
|
skfolio/utils/tools.py
CHANGED
@@ -326,7 +326,9 @@ def args_names(func: object) -> list[str]:
|
|
326
326
|
|
327
327
|
|
328
328
|
def check_estimator(
|
329
|
-
estimator: skb.BaseEstimator | None,
|
329
|
+
estimator: skb.BaseEstimator | None,
|
330
|
+
default: skb.BaseEstimator | None,
|
331
|
+
check_type: Any,
|
330
332
|
):
|
331
333
|
"""Check the estimator type and returns its cloned version it provided, otherwise
|
332
334
|
return the default estimator.
|
@@ -336,7 +338,7 @@ def check_estimator(
|
|
336
338
|
estimator : BaseEstimator, optional
|
337
339
|
Estimator.
|
338
340
|
|
339
|
-
default : BaseEstimator
|
341
|
+
default : BaseEstimator, optional
|
340
342
|
Default estimator to return when `estimator` is `None`.
|
341
343
|
|
342
344
|
check_type : Any
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: skfolio
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.10.0
|
4
4
|
Summary: Portfolio optimization built on top of scikit-learn
|
5
5
|
Author-email: Hugo Delatte <delatte.hugo@gmail.com>
|
6
6
|
Maintainer-email: Hugo Delatte <delatte.hugo@gmail.com>, Matteo Manzi <matteomanzi09@gmail.com>
|
@@ -92,7 +92,7 @@ Dynamic: license-file
|
|
92
92
|
|
93
93
|
.. -*- mode: rst -*-
|
94
94
|
|
95
|
-
|Licence| |Codecov| |Black| |PythonVersion| |PyPi| |CI/CD| |Downloads| |Ruff| |Contribution| |Website| |JupyterLite|
|
95
|
+
|Licence| |Codecov| |Black| |PythonVersion| |PyPi| |CI/CD| |Downloads| |Ruff| |Contribution| |Website| |JupyterLite| |Discord|
|
96
96
|
|
97
97
|
.. |Licence| image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
|
98
98
|
:target: https://github.com/skfolio/skfolio/blob/main/LICENSE
|
@@ -127,6 +127,9 @@ Dynamic: license-file
|
|
127
127
|
.. |JupyterLite| image:: https://jupyterlite.rtfd.io/en/latest/_static/badge.svg
|
128
128
|
:target: https://skfolio.org/lite
|
129
129
|
|
130
|
+
.. |Discord| image:: https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord&logoColor=white
|
131
|
+
:target: https://discord.gg/Bu7EtNYugS
|
132
|
+
|
130
133
|
.. |PythonMinVersion| replace:: 3.10
|
131
134
|
.. |NumpyMinVersion| replace:: 1.23.4
|
132
135
|
.. |ScipyMinVersion| replace:: 1.8.0
|
@@ -281,6 +284,8 @@ Available models
|
|
281
284
|
* Black & Litterman
|
282
285
|
* Factor Model
|
283
286
|
* Synthetic Data (Stress Test, Factor Stress Test)
|
287
|
+
* Entropy Pooling
|
288
|
+
* Opinion Pooling
|
284
289
|
|
285
290
|
* Uncertainty Set Estimator:
|
286
291
|
* On Expected Returns:
|
@@ -296,6 +301,7 @@ Available models
|
|
296
301
|
* Drop Highly Correlated Assets
|
297
302
|
* Select Non-Expiring Assets
|
298
303
|
* Select Complete Assets (handle late inception, delisting, etc.)
|
304
|
+
* Drop Zero Variance
|
299
305
|
|
300
306
|
* Cross-Validation and Model Selection:
|
301
307
|
* Compatible with all `sklearn` methods (KFold, etc.)
|
@@ -385,7 +391,14 @@ Imports
|
|
385
391
|
)
|
386
392
|
from skfolio.pre_selection import SelectKExtremes
|
387
393
|
from skfolio.preprocessing import prices_to_returns
|
388
|
-
from skfolio.prior import
|
394
|
+
from skfolio.prior import (
|
395
|
+
BlackLitterman,
|
396
|
+
EmpiricalPrior,
|
397
|
+
EntropyPooling,
|
398
|
+
FactorModel,
|
399
|
+
OpinionPooling,
|
400
|
+
SyntheticData,
|
401
|
+
)
|
389
402
|
from skfolio.uncertainty_set import BootstrapMuUncertaintySet
|
390
403
|
|
391
404
|
Load Dataset
|
@@ -701,8 +714,84 @@ Factor Stress Test
|
|
701
714
|
conditioning={"QUAL": -0.5}
|
702
715
|
))
|
703
716
|
factor_model.fit(X,y)
|
704
|
-
|
705
|
-
stressed_ptf = model.predict(
|
717
|
+
stressed_dist = factor_model.return_distribution_
|
718
|
+
stressed_ptf = model.predict(stressed_dist)
|
719
|
+
|
720
|
+
Entropy Pooling
|
721
|
+
---------------
|
722
|
+
.. code-block:: python
|
723
|
+
|
724
|
+
entropy_pooling = EntropyPooling(
|
725
|
+
mean_views=[
|
726
|
+
"JPM == -0.002",
|
727
|
+
"PG >= LLY",
|
728
|
+
"BAC >= prior(BAC) * 1.2",
|
729
|
+
],
|
730
|
+
cvar_views=[
|
731
|
+
"GE == 0.08",
|
732
|
+
],
|
733
|
+
)
|
734
|
+
entropy_pooling.fit(X)
|
735
|
+
print(entropy_pooling.relative_entropy_)
|
736
|
+
print(entropy_pooling.effective_number_of_scenarios_)
|
737
|
+
print(entropy_pooling.return_distribution_.sample_weight)
|
738
|
+
|
739
|
+
CVaR Hierarchical Risk Parity optimization on Entropy Pooling
|
740
|
+
-------------------------------------------------------------
|
741
|
+
.. code-block:: python
|
742
|
+
|
743
|
+
entropy_pooling = EntropyPooling(cvar_views=["GE == 0.08"])
|
744
|
+
model = HierarchicalRiskParity(
|
745
|
+
risk_measure=RiskMeasure.CVAR,
|
746
|
+
prior_estimator=entropy_pooling
|
747
|
+
)
|
748
|
+
model.fit(X)
|
749
|
+
print(model.weights_)
|
750
|
+
|
751
|
+
Stress Test with Entropy Pooling on Factor Synthetic Data
|
752
|
+
---------------------------------------------------------
|
753
|
+
.. code-block:: python
|
754
|
+
|
755
|
+
# Regular Vine Copula and sampling of 100,000 synthetic factor returns
|
756
|
+
factor_synth = SyntheticData(
|
757
|
+
n_samples=100_000,
|
758
|
+
distribution_estimator=VineCopula(log_transform=True, n_jobs=-1, random_state=0)
|
759
|
+
)
|
760
|
+
|
761
|
+
# Entropy Pooling by imposing a CVaR-95% of 10% on the Quality factor
|
762
|
+
factor_entropy_pooling = EntropyPooling(
|
763
|
+
prior_estimator=factor_synth,
|
764
|
+
cvar_views=["QUAL == 0.10"],
|
765
|
+
)
|
766
|
+
|
767
|
+
factor_entropy_pooling.fit(X, factors)
|
768
|
+
|
769
|
+
# We retrieve the stressed distribution:
|
770
|
+
stressed_dist = factor_model.return_distribution_
|
771
|
+
|
772
|
+
# We stress-test our portfolio:
|
773
|
+
stressed_ptf = model.predict(stressed_dist)
|
774
|
+
|
775
|
+
Opinion Pooling
|
776
|
+
---------------
|
777
|
+
.. code-block:: python
|
778
|
+
|
779
|
+
# We consider two expert opinions, each generated via Entropy Pooling with
|
780
|
+
# user-defined views.
|
781
|
+
# We assign probabilities of 40% to Expert 1, 50% to Expert 2, and by default
|
782
|
+
# the remaining 10% is allocated to the prior distribution:
|
783
|
+
opinion_1 = EntropyPooling(cvar_views=["AMD == 0.10"])
|
784
|
+
opinion_2 = EntropyPooling(
|
785
|
+
mean_views=["AMD >= BAC", "JPM <= prior(JPM) * 0.8"],
|
786
|
+
cvar_views=["GE == 0.12"],
|
787
|
+
)
|
788
|
+
|
789
|
+
opinion_pooling = OpinionPooling(
|
790
|
+
estimators=[("opinion_1", opinion_1), ("opinion_2", opinion_2)],
|
791
|
+
opinion_probabilities=[0.4, 0.5],
|
792
|
+
)
|
793
|
+
|
794
|
+
opinion_pooling.fit(X)
|
706
795
|
|
707
796
|
|
708
797
|
Recognition
|
@@ -1,5 +1,5 @@
|
|
1
1
|
skfolio/__init__.py,sha256=XdSV1bcfft5pNl5Y_mX8MR0IzjXjRs8uRURp42UGa08,635
|
2
|
-
skfolio/exceptions.py,sha256=
|
2
|
+
skfolio/exceptions.py,sha256=4k4cFgV0qCAovDKe0XqthzKs9SX871BTv1GKfX00ovc,880
|
3
3
|
skfolio/typing.py,sha256=5wnu_qoGZtCWKu-nHlZ5w3rOKy5CXxGI5ZvzDSR9pLU,1394
|
4
4
|
skfolio/cluster/__init__.py,sha256=ycySaq2MgG3etqNF-pITuYKfYPHYm3-frjFc8PRzMc0,267
|
5
5
|
skfolio/cluster/_hierarchical.py,sha256=PTtr6H4keY6DEVvXyYM24AnNjj72sNaXKjGFEyMXZ5c,12839
|
@@ -27,17 +27,17 @@ skfolio/distribution/copula/_utils.py,sha256=drMtv71bkwlerR0HJCdNCZTuFSitN5vn33a
|
|
27
27
|
skfolio/distribution/multivariate/__init__.py,sha256=E9AR0Hh5wWShOTwj62R1RVMkzZpXc5Ams4ppibwhrUY,339
|
28
28
|
skfolio/distribution/multivariate/_base.py,sha256=MV3rhTafPlKdb3wuLbHfhApyV1ll7WmfzdR97Dq8VZw,8716
|
29
29
|
skfolio/distribution/multivariate/_utils.py,sha256=WNL1lzO0Ki5x_yO8p3GRKrXwG4fK99je7sDQ3avyUQ8,19274
|
30
|
-
skfolio/distribution/multivariate/_vine_copula.py,sha256=
|
30
|
+
skfolio/distribution/multivariate/_vine_copula.py,sha256=2SPUwDthWe8pcDpXMZ6dqLMjpI0HGdkguP0sziOlEYc,50099
|
31
31
|
skfolio/distribution/univariate/__init__.py,sha256=m9vZUhZyRUT5IOQRixGPdGci1wtC5ua8RWtHsC8HAlU,628
|
32
|
-
skfolio/distribution/univariate/_base.py,sha256=
|
32
|
+
skfolio/distribution/univariate/_base.py,sha256=8uleYSiCJ4n6X1uI0ju5f4l0iLvJcyS3Gncxh7yyH90,10096
|
33
33
|
skfolio/distribution/univariate/_gaussian.py,sha256=pe8YxTQjvObeVeZD2YXduN5M-k2kNNTy2q0AvYCm1n4,4274
|
34
34
|
skfolio/distribution/univariate/_johnson_su.py,sha256=Dl1WyCmn-sRE4BrckVNGXHz9biDQtXyPq1JXEPKIHBo,4857
|
35
35
|
skfolio/distribution/univariate/_normal_inverse_gaussian.py,sha256=oq5omNUQanFWBGaYSNwf9YDa6c-B1j9ZErq6p96resc,4983
|
36
36
|
skfolio/distribution/univariate/_selection.py,sha256=6KL4gngiLKwaBUpCDX19ABOkMBzZp1YVRnXFrUtppCs,3110
|
37
37
|
skfolio/distribution/univariate/_student_t.py,sha256=GcI4fKp6q5XegfvT_i3AqfWlUMxCq7A5sX6Xsf4pye8,4553
|
38
|
-
skfolio/measures/__init__.py,sha256=
|
38
|
+
skfolio/measures/__init__.py,sha256=saJ3tGQyZ5MRtwnj0tVS9L4yvnLJVSdyXVyH5_FyoNo,1683
|
39
39
|
skfolio/measures/_enums.py,sha256=S6WOT8NHzm-eMHELuOjngIBupCctCdiTA2BaJlWl-4E,8956
|
40
|
-
skfolio/measures/_measures.py,sha256=
|
40
|
+
skfolio/measures/_measures.py,sha256=ysON3rPfcLPSAPY3T1MfkuLPoKU__KN5sRyCzOXe6to,28716
|
41
41
|
skfolio/metrics/__init__.py,sha256=ebu5h7Q9X0f3ZZ1VFmAEBPic2sirboKG_zNBHO5abjo,98
|
42
42
|
skfolio/metrics/_scorer.py,sha256=L-qct4cby15a4xC4arSaG5__1mxBCQYeMjlrHBIVnSY,4325
|
43
43
|
skfolio/model_selection/__init__.py,sha256=BT8VCXW7C4bXI2Oam4amTHOcJVlKxLpkcsHjB63pZHQ,524
|
@@ -64,58 +64,60 @@ skfolio/moments/expected_returns/_equilibrium_mu.py,sha256=A4zAYZ7ex2Y68YV0HajYD
|
|
64
64
|
skfolio/moments/expected_returns/_ew_mu.py,sha256=vDOqpTpTY3iaJc9PfMU_dpdfglT1dJ_DuM3pCTpjHpc,2125
|
65
65
|
skfolio/moments/expected_returns/_shrunk_mu.py,sha256=nqypZJweZIf6u3Idz-TLPHiD3h3XzuKgTEQWJHSVnwo,8292
|
66
66
|
skfolio/optimization/__init__.py,sha256=LA4n85e-wVTeRNI-NlTU1ID5FhP3-B410kmsh9268Ho,1049
|
67
|
-
skfolio/optimization/_base.py,sha256=
|
67
|
+
skfolio/optimization/_base.py,sha256=tbD-HiulBXHMAbrMGq8K62qUxVHu6uf1Cl0pT34VyIc,6351
|
68
68
|
skfolio/optimization/cluster/__init__.py,sha256=nxsuDxviDbj-YMHhQXIkUEWUoKPhPn10bQ0_nULNUoE,424
|
69
69
|
skfolio/optimization/cluster/_nco.py,sha256=Gbd18HYlwq_MUd9JmytM1-Uqu-GFT8NXb8QWPVgmDxk,16433
|
70
70
|
skfolio/optimization/cluster/hierarchical/__init__.py,sha256=eT1A6YKETKCBEnrUc6pHwyTkDVRcUr8jtdtmN3kdh0c,446
|
71
|
-
skfolio/optimization/cluster/hierarchical/_base.py,sha256=
|
72
|
-
skfolio/optimization/cluster/hierarchical/_herc.py,sha256=
|
73
|
-
skfolio/optimization/cluster/hierarchical/_hrp.py,sha256=
|
71
|
+
skfolio/optimization/cluster/hierarchical/_base.py,sha256=2YH9m_L_NFdBfhPso-WVCx-Meiy_bCNYVukt72nZHno,16480
|
72
|
+
skfolio/optimization/cluster/hierarchical/_herc.py,sha256=3Mwfe6PGWzWWWpOYnfLTWAmeNcYE1d3eh1uXB9hqAyM,20476
|
73
|
+
skfolio/optimization/cluster/hierarchical/_hrp.py,sha256=pNr2e2COZIi9jj5IEddT4a79BCD0VjwbPeXHRRSLdoI,18287
|
74
74
|
skfolio/optimization/convex/__init__.py,sha256=q1Q2p7HcnmbQlBIA0SXm0TwDGxl7hRc0JhF1o01lFSg,605
|
75
|
-
skfolio/optimization/convex/_base.py,sha256=
|
76
|
-
skfolio/optimization/convex/_distributionally_robust.py,sha256=
|
77
|
-
skfolio/optimization/convex/_maximum_diversification.py,sha256=
|
78
|
-
skfolio/optimization/convex/_mean_risk.py,sha256=
|
79
|
-
skfolio/optimization/convex/_risk_budgeting.py,sha256=
|
80
|
-
skfolio/optimization/ensemble/__init__.py,sha256=
|
81
|
-
skfolio/optimization/ensemble/
|
82
|
-
skfolio/optimization/ensemble/_stacking.py,sha256=DaswFVBTghP10vHGESn6aLT7C9wgp-D8NuXGtpdZcwE,14192
|
75
|
+
skfolio/optimization/convex/_base.py,sha256=gIFIF5DCIDPL8FeXaipdZBbkiUHP55MsWfyc8DVQ6ng,92190
|
76
|
+
skfolio/optimization/convex/_distributionally_robust.py,sha256=BKMp718PqG02t2qQ8ejgCSuY18ZNA_4y05RxLV16OJs,18332
|
77
|
+
skfolio/optimization/convex/_maximum_diversification.py,sha256=QBHPRsAHjR4zpxJvvaKoKI0dMMTTHMlRRquB_sOWNuU,19569
|
78
|
+
skfolio/optimization/convex/_mean_risk.py,sha256=ZO2CXMeb9uOiOQVunuUmJcgsWj-uwaPw_PqZNmOV-Mk,50287
|
79
|
+
skfolio/optimization/convex/_risk_budgeting.py,sha256=jZtQXfXF1iIVTIiV9fphW4xam36qKylHmdfIgJtdG5o,23803
|
80
|
+
skfolio/optimization/ensemble/__init__.py,sha256=8YKBsrAMjyAaUWRbDG_ciNuyj0mtSPmn85ms8Afvm90,219
|
81
|
+
skfolio/optimization/ensemble/_stacking.py,sha256=i7tAHjzydb75o2xdgzV2lkqpkhEqpwsugXJjCFyV8rY,14182
|
83
82
|
skfolio/optimization/naive/__init__.py,sha256=1QKgOuA6DoqKVOsJxWKogaGPyOir6ln-aQ28PTAbtJs,181
|
84
|
-
skfolio/optimization/naive/_naive.py,sha256=
|
83
|
+
skfolio/optimization/naive/_naive.py,sha256=TRwQO7stD8hVg5OEe_QVpBgdcLaT_jUZco2lf5skYqo,6469
|
85
84
|
skfolio/population/__init__.py,sha256=ehKwWhDJCifjhEL-QezVR0xYjzRTeyHbrEMbfWjF9cU,106
|
86
|
-
skfolio/population/_population.py,sha256=
|
85
|
+
skfolio/population/_population.py,sha256=0mXy1yXNCZWeaYUu9tzRifv-NSttcy_nSlh-44PJiz4,32048
|
87
86
|
skfolio/portfolio/__init__.py,sha256=YeDSH0ZdyE-lcbDqpNw9IOltURtoM-ewAzzcec44Q5Q,586
|
88
|
-
skfolio/portfolio/_base.py,sha256=
|
89
|
-
skfolio/portfolio/_multi_period_portfolio.py,sha256=
|
90
|
-
skfolio/portfolio/_portfolio.py,sha256=
|
87
|
+
skfolio/portfolio/_base.py,sha256=1fzDIYpgz8GIDDySfAO32RN-2IX6waT6vZS6CzvkLT8,42239
|
88
|
+
skfolio/portfolio/_multi_period_portfolio.py,sha256=EI0LeJ3DokDUnumNv_Q1-P3wykjeBHpw2qa2KTi1a-M,24649
|
89
|
+
skfolio/portfolio/_portfolio.py,sha256=so9wer_KNnJqudvalNeV9ubEy5WIumE-PxvEAAL9Ty4,33028
|
91
90
|
skfolio/pre_selection/__init__.py,sha256=6J_D0QIMi24owwJJP6vxYnIgIyWZuMzCMnpMCEpAvCo,606
|
92
91
|
skfolio/pre_selection/_drop_correlated.py,sha256=4-PSd8R20Rcdyc8Zzcy9B2eRPEtaEkM3YXi74YKF-Pk,3839
|
93
92
|
skfolio/pre_selection/_drop_zero_variance.py,sha256=66Mi0Fta1kdmLw0CCqa7p9AqpoBpS9B3fGPLqhb8VIU,2312
|
94
93
|
skfolio/pre_selection/_select_complete.py,sha256=2nEvcjROMJzhAHMCHADeAiCws_tc-BMtndIkjRexL84,3902
|
95
94
|
skfolio/pre_selection/_select_k_extremes.py,sha256=nMugK88igmscribCw_I1UnjE_O7cuIjrJF8AGuVTfiA,3082
|
96
95
|
skfolio/pre_selection/_select_non_dominated.py,sha256=Auv7G8E1QNO96heb35oBWmFLd68LlVDRgSpcg7wpv5A,6004
|
97
|
-
skfolio/pre_selection/_select_non_expiring.py,sha256=
|
96
|
+
skfolio/pre_selection/_select_non_expiring.py,sha256=g7ekl69MxQFkg06Km3NiuJXr0JfYPqvo5hMLQsIcUKY,5101
|
98
97
|
skfolio/preprocessing/__init__.py,sha256=94jMyP_E7FlwQVE8D_bXDi8KyfAA2xPHTDvYOi6zf_g,123
|
99
98
|
skfolio/preprocessing/_returns.py,sha256=6G5qJIVHGnIoeBNAqpJTB-569g9NeXVIyrz033bK5Gk,4576
|
100
|
-
skfolio/prior/__init__.py,sha256=
|
101
|
-
skfolio/prior/_base.py,sha256=
|
102
|
-
skfolio/prior/_black_litterman.py,sha256=
|
103
|
-
skfolio/prior/_empirical.py,sha256=
|
104
|
-
skfolio/prior/
|
105
|
-
skfolio/prior/
|
106
|
-
skfolio/
|
99
|
+
skfolio/prior/__init__.py,sha256=4bi4u7Y-D9vLKb0nxlAXYEZUuYkjPXQcC7qlYUu_DMA,720
|
100
|
+
skfolio/prior/_base.py,sha256=aSqyhBYc35RpWq4XpM3UsOu88Bvxbqn7QhctK9bP0I0,2217
|
101
|
+
skfolio/prior/_black_litterman.py,sha256=oRH6wUjsL5bkjiNbVtxaIPMNi34rqPp7WBmDbJiklKM,10675
|
102
|
+
skfolio/prior/_empirical.py,sha256=zRceQNsbeWdkZHIaFvO91AhZTqkPd8YE2f60cK39M-U,7486
|
103
|
+
skfolio/prior/_entropy_pooling.py,sha256=TBczvvauhaV0Uq5NOZXHWc3Ojru-PFNosvbm79RuT9E,59278
|
104
|
+
skfolio/prior/_factor_model.py,sha256=lbXFsuidDJvLBX7fwp6fXXvgdL3MzkL5lJCx7HEABcA,12241
|
105
|
+
skfolio/prior/_opinion_pooling.py,sha256=dBZ8TjlAOKWA9lZFD4DS_PH5HG8iZYgtNrJLPnqwX0o,19055
|
106
|
+
skfolio/prior/_synthetic_data.py,sha256=HsxcIQa9lwcYh81Y-o00xsSr9-djgrTQtRTE4SCNpKo,8735
|
107
107
|
skfolio/uncertainty_set/__init__.py,sha256=SHbOq0ip3vuwEK9G4pzz0GncDbGsHw7ywF9tPnkUrZ8,648
|
108
108
|
skfolio/uncertainty_set/_base.py,sha256=R6qH8Zg5Ti3Qny-guL4Js8rY9JhpF8jMwV_w9HCbgWI,4307
|
109
|
-
skfolio/uncertainty_set/_bootstrap.py,sha256=
|
110
|
-
skfolio/uncertainty_set/_empirical.py,sha256=
|
109
|
+
skfolio/uncertainty_set/_bootstrap.py,sha256=6cSTae56zFAAS4WCxEm3IO2FdVk3JHbCOJc7IOIx8b4,11297
|
110
|
+
skfolio/uncertainty_set/_empirical.py,sha256=ZmCk6OBMxbii3TyFg3tZRHWijU7fH1R0R-WS-jb3gj4,9444
|
111
111
|
skfolio/utils/__init__.py,sha256=bC6-MsCVF7xKTr48z7OzJJUeWvqAB7BiHeNTiKsme70,20
|
112
112
|
skfolio/utils/bootstrap.py,sha256=6BN_9CgfbeImBSNEE0dF52FRGuQT41HcQXeHPLwFqJc,3565
|
113
|
-
skfolio/utils/
|
113
|
+
skfolio/utils/composition.py,sha256=e0dWCEIYnho3HU2KGGS9UHQdycdVuqMcTe7hi0LihjQ,3416
|
114
|
+
skfolio/utils/equations.py,sha256=N4C937GesVEwC3PWecP2oSpg6myayA58fWsNGjhEbpw,15812
|
115
|
+
skfolio/utils/figure.py,sha256=2U0PuHRuza_1N6o_fWD8amNDc0IhgfzM5owFl3zBzwg,5744
|
114
116
|
skfolio/utils/sorting.py,sha256=F7gfIBfnulfDUiqvzrlR-pba4PPLJT6NH7-5s4sdRhw,3521
|
115
117
|
skfolio/utils/stats.py,sha256=glVHo7rjwy06dl5kkULLOADMrEkVJcfXXAz-1qmYQL4,17005
|
116
|
-
skfolio/utils/tools.py,sha256=
|
117
|
-
skfolio-0.
|
118
|
-
skfolio-0.
|
119
|
-
skfolio-0.
|
120
|
-
skfolio-0.
|
121
|
-
skfolio-0.
|
118
|
+
skfolio/utils/tools.py,sha256=XQ-bkbhIqBTuv_ZLK-vDnDx8NGFCFvmWoJF8Ui1tj38,23020
|
119
|
+
skfolio-0.10.0.dist-info/licenses/LICENSE,sha256=F6Gi-ZJX5BlVzYK8R9NcvAkAsKa7KO29xB1OScbrH6Q,1526
|
120
|
+
skfolio-0.10.0.dist-info/METADATA,sha256=bZvW8kQjrwBd2XWFdvZElhNYQaJVzCxkjo0f8Ju7pUU,25053
|
121
|
+
skfolio-0.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
122
|
+
skfolio-0.10.0.dist-info/top_level.txt,sha256=NXEaoS9Ms7t32gxkb867nV0OKlU0KmssL7IJBVo0fJs,8
|
123
|
+
skfolio-0.10.0.dist-info/RECORD,,
|
@@ -1 +0,0 @@
|
|
1
|
-
"""Synthetic Data module."""
|
File without changes
|
File without changes
|
File without changes
|