skfolio 0.1.1__py3-none-any.whl → 0.1.3__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/datasets/_base.py CHANGED
@@ -140,7 +140,10 @@ def download_dataset(
140
140
  DataFrame with each row representing one observation and each column
141
141
  representing the asset price of a given observation.
142
142
  """
143
- url = f"https://github.com/skfolio/skfolio/raw/main/datasets/{data_filename}.csv.gz"
143
+ url = (
144
+ f"https://github.com/skfolio/skfolio-datasets/raw/main/"
145
+ f"datasets/{data_filename}.csv.gz"
146
+ )
144
147
 
145
148
  data_home = get_data_home(data_home=data_home)
146
149
  filepath = os.path.join(data_home, f"{data_filename}.pkz")
@@ -4,7 +4,6 @@
4
4
  # Author: Hugo Delatte <delatte.hugo@gmail.com>
5
5
  # License: BSD 3 clause
6
6
 
7
-
8
7
  import numpy as np
9
8
  import numpy.typing as npt
10
9
  import pandas as pd
@@ -16,6 +16,7 @@ from skfolio.measures._measures import (
16
16
  cvar,
17
17
  drawdown_at_risk,
18
18
  edar,
19
+ effective_number_assets,
19
20
  entropic_risk_measure,
20
21
  evar,
21
22
  first_lower_partial_moment,
@@ -73,4 +74,5 @@ __all__ = [
73
74
  "owa_gmd_weights",
74
75
  "skew",
75
76
  "kurtosis",
77
+ "effective_number_assets",
76
78
  ]
@@ -19,7 +19,9 @@ class BaseMeasure(AutoEnum):
19
19
  (
20
20
  word.capitalize()
21
21
  if len(word) > 3
22
- else word.upper() if len(word) != 2 else word.lower()
22
+ else word.upper()
23
+ if len(word) != 2
24
+ else word.lower()
23
25
  )
24
26
  for word in self.value.split("_")
25
27
  ]
@@ -6,7 +6,6 @@
6
6
  # Gini mean difference and OWA GMD weights features are derived
7
7
  # from Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
8
8
 
9
-
10
9
  import numpy as np
11
10
  import scipy.optimize as sco
12
11
 
@@ -611,11 +610,13 @@ def gini_mean_difference(returns: np.ndarray) -> float:
611
610
 
612
611
 
613
612
  def effective_number_assets(weights: np.ndarray) -> float:
614
- r"""
615
- Computes the effective number of assets, defined as the inverse of the Herfindahl index [1]_:
613
+ r"""Computes the effective number of assets, defined as the inverse of the
614
+ Herfindahl index [1]_:
615
+
616
616
  .. math:: N_{eff} = \frac{1}{\Vert w \Vert_{2}^{2}}
617
617
 
618
- It quantifies portfolio concentration, with a higher value indicating a more diversified portfolio.
618
+ It quantifies portfolio concentration, with a higher value indicating a more
619
+ diversified portfolio.
619
620
 
620
621
  Parameters
621
622
  ----------
@@ -321,18 +321,20 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
321
321
 
322
322
  def summary(self, X) -> pd.Series:
323
323
  n_samples = X.shape[0]
324
- return pd.Series({
325
- "Number of Observations": n_samples,
326
- "Total Number of Folds": self.n_folds,
327
- "Number of Test Folds": self.n_test_folds,
328
- "Purge Size": self.purged_size,
329
- "Embargo Size": self.embargo_size,
330
- "Average Training Size": int(
331
- n_samples / self.n_folds * (self.n_folds - self.n_test_folds)
332
- ),
333
- "Number of Test Paths": self.n_test_paths,
334
- "Number of Training Combinations": self.n_splits,
335
- })
324
+ return pd.Series(
325
+ {
326
+ "Number of Observations": n_samples,
327
+ "Total Number of Folds": self.n_folds,
328
+ "Number of Test Folds": self.n_test_folds,
329
+ "Purge Size": self.purged_size,
330
+ "Embargo Size": self.embargo_size,
331
+ "Average Training Size": int(
332
+ n_samples / self.n_folds * (self.n_folds - self.n_test_folds)
333
+ ),
334
+ "Number of Test Paths": self.n_test_paths,
335
+ "Number of Training Combinations": self.n_splits,
336
+ }
337
+ )
336
338
 
337
339
  def plot_train_test_folds(self) -> skt.Figure:
338
340
  """Plot the train/test fold locations"""
@@ -170,12 +170,14 @@ def cross_val_predict(
170
170
  path_id = path_ids[i, j]
171
171
  portfolios[path_id].append(p)
172
172
  name = portfolio_params.pop("name", "path")
173
- pred = Population([
174
- MultiPeriodPortfolio(
175
- name=f"{name}_{i}", portfolios=portfolios[i], **portfolio_params
176
- )
177
- for i in range(path_nb)
178
- ])
173
+ pred = Population(
174
+ [
175
+ MultiPeriodPortfolio(
176
+ name=f"{name}_{i}", portfolios=portfolios[i], **portfolio_params
177
+ )
178
+ for i in range(path_nb)
179
+ ]
180
+ )
179
181
  else:
180
182
  # We need to re-order the test folds in case they were un-ordered by the
181
183
  # CV generator.
@@ -97,15 +97,17 @@ class BaseOptimization(skb.BaseEstimator, ABC):
97
97
  # For a 2D array we return a population of portfolios.
98
98
  if self.weights_.ndim == 2:
99
99
  n_portfolios = self.weights_.shape[0]
100
- return Population([
101
- Portfolio(
102
- X=X,
103
- weights=self.weights_[i],
104
- name=f"ptf{i} - {name}",
105
- **ptf_kwargs,
106
- )
107
- for i in range(n_portfolios)
108
- ])
100
+ return Population(
101
+ [
102
+ Portfolio(
103
+ X=X,
104
+ weights=self.weights_[i],
105
+ name=f"ptf{i} - {name}",
106
+ **ptf_kwargs,
107
+ )
108
+ for i in range(n_portfolios)
109
+ ]
110
+ )
109
111
  return Portfolio(X=X, weights=self.weights_, name=name, **ptf_kwargs)
110
112
 
111
113
  def score(self, X: npt.ArrayLike, y: npt.ArrayLike = None) -> float:
@@ -6,7 +6,6 @@
6
6
  # The risk measure generalization and constraint features are derived
7
7
  # from Riskfolio-Lib, Copyright (c) 2020-2023, Dany Cajas, Licensed under BSD 3 clause.
8
8
 
9
-
10
9
  import numpy as np
11
10
  import numpy.typing as npt
12
11
  import pandas as pd
@@ -80,9 +80,7 @@ class BaseComposition(skb.BaseEstimator, ABC):
80
80
  invalid_names = set(names).intersection(self.get_params(deep=False))
81
81
  if invalid_names:
82
82
  raise ValueError(
83
- "Estimator names conflict with constructor arguments: {!r}".format(
84
- sorted(invalid_names)
85
- )
83
+ f"Estimator names conflict with constructor arguments: {sorted(invalid_names)!r}"
86
84
  )
87
85
  invalid_names = [name for name in names if "__" in name]
88
86
  if invalid_names:
@@ -312,10 +312,12 @@ class StackingOptimization(BaseOptimization, BaseComposition):
312
312
  _ = self._validate_data(X)
313
313
 
314
314
  if isinstance(self.cv, BaseCombinatorialCV):
315
- X_pred = np.array([
316
- pred.quantile(measure=self.quantile_measure, q=self.quantile)
317
- for pred in cv_predictions
318
- ]).T
315
+ X_pred = np.array(
316
+ [
317
+ pred.quantile(measure=self.quantile_measure, q=self.quantile)
318
+ for pred in cv_predictions
319
+ ]
320
+ ).T
319
321
  else:
320
322
  X_pred = np.array(cv_predictions).T
321
323
  if y is not None:
@@ -1,4 +1,4 @@
1
- """ Population module.
1
+ """Population module.
2
2
  A population is a collection of portfolios.
3
3
  """
4
4
 
@@ -140,9 +140,12 @@ class Population(list):
140
140
  non-dominated portfolios.
141
141
  """
142
142
  n = len(self)
143
- if n > 0 and np.any([
144
- portfolio.fitness_measures != self[0].fitness_measures for portfolio in self
145
- ]):
143
+ if n > 0 and np.any(
144
+ [
145
+ portfolio.fitness_measures != self[0].fitness_measures
146
+ for portfolio in self
147
+ ]
148
+ ):
146
149
  raise ValueError(
147
150
  "Cannot compute non denominated sorting with Portfolios "
148
151
  "containing mixed `fitness_measures`"
@@ -187,11 +190,13 @@ class Population(list):
187
190
  return self.__class__(
188
191
  [portfolio for portfolio in self if portfolio.tag in tags]
189
192
  )
190
- return self.__class__([
191
- portfolio
192
- for portfolio in self
193
- if portfolio.name in names and portfolio.tag in tags
194
- ])
193
+ return self.__class__(
194
+ [
195
+ portfolio
196
+ for portfolio in self
197
+ if portfolio.name in names and portfolio.tag in tags
198
+ ]
199
+ )
195
200
 
196
201
  def measures(
197
202
  self,
@@ -784,15 +789,17 @@ class Population(list):
784
789
  x=xi,
785
790
  y=yi,
786
791
  z=Z,
787
- hovertemplate="<br>".join([
788
- str(e)
789
- + ": %{"
790
- + v
791
- + ":"
792
- + (",.3%" if not e.is_ratio else None)
793
- + "}"
794
- for e, v in [(x, "x"), (y, "y"), (z, "z")]
795
- ])
792
+ hovertemplate="<br>".join(
793
+ [
794
+ str(e)
795
+ + ": %{"
796
+ + v
797
+ + ":"
798
+ + (",.3%" if not e.is_ratio else None)
799
+ + "}"
800
+ for e, v in [(x, "x"), (y, "y"), (z, "z")]
801
+ ]
802
+ )
796
803
  + "<extra></extra>",
797
804
  colorbar=dict(
798
805
  title=str(z),
@@ -37,7 +37,6 @@
37
37
  # the class attributes with the argument name preceded by the measure name and
38
38
  # separated by '_'.
39
39
 
40
-
41
40
  import warnings
42
41
  from abc import abstractmethod
43
42
  from typing import ClassVar
@@ -8,7 +8,6 @@ is the dot product of the assets weights with the assets returns.
8
8
  # Author: Hugo Delatte <delatte.hugo@gmail.com>
9
9
  # License: BSD 3 clause
10
10
 
11
-
12
11
  import numbers
13
12
  from typing import ClassVar
14
13
 
@@ -18,7 +17,7 @@ import pandas as pd
18
17
  import plotly.express as px
19
18
 
20
19
  import skfolio.typing as skt
21
- from skfolio.measures import RiskMeasure
20
+ from skfolio.measures import RiskMeasure, effective_number_assets
22
21
  from skfolio.portfolio._base import _ZERO_THRESHOLD, BasePortfolio
23
22
  from skfolio.utils.tools import (
24
23
  args_names,
@@ -402,17 +401,19 @@ class Portfolio(BasePortfolio):
402
401
  """
403
402
 
404
403
  _read_only_attrs: ClassVar[set] = BasePortfolio._read_only_attrs.copy()
405
- _read_only_attrs.update({
406
- "X",
407
- "assets",
408
- "weights",
409
- "previous_weights",
410
- "transaction_costs",
411
- "management_fees",
412
- "n_assets",
413
- "total_cost",
414
- "total_fee",
415
- })
404
+ _read_only_attrs.update(
405
+ {
406
+ "X",
407
+ "assets",
408
+ "weights",
409
+ "previous_weights",
410
+ "transaction_costs",
411
+ "management_fees",
412
+ "n_assets",
413
+ "total_cost",
414
+ "total_fee",
415
+ }
416
+ )
416
417
 
417
418
  __slots__ = {
418
419
  # read-only
@@ -691,6 +692,28 @@ class Portfolio(BasePortfolio):
691
692
  self.n_observations * self.sharpe_ratio
692
693
  )
693
694
 
695
+ @property
696
+ def effective_number_assets(self) -> float:
697
+ r"""Computes the effective number of assets, defined as the inverse of the
698
+ Herfindahl index [1]_:
699
+
700
+ .. math:: N_{eff} = \frac{1}{\Vert w \Vert_{2}^{2}}
701
+
702
+ It quantifies portfolio concentration, with a higher value indicating a more
703
+ diversified portfolio.
704
+
705
+ Returns
706
+ -------
707
+ value : float
708
+ Effective number of assets.
709
+
710
+ References
711
+ ----------
712
+ .. [1] "Banking and Financial Institutions Law in a Nutshell".
713
+ Lovett, William Anthony (1988)
714
+ """
715
+ return effective_number_assets(weights=self.weights)
716
+
694
717
  # Public methods
695
718
  def expected_returns_from_assets(
696
719
  self, assets_expected_returns: np.ndarray
@@ -817,9 +840,12 @@ class Portfolio(BasePortfolio):
817
840
  """
818
841
  df = super().summary(formatted=formatted)
819
842
  assets_number = self.n_assets
843
+ effective_nb_assets = self.effective_number_assets
820
844
  if formatted:
821
- assets_number = str(self.n_assets)
822
- df["Assets number"] = assets_number
845
+ assets_number = str(assets_number)
846
+ effective_nb_assets = str(effective_nb_assets)
847
+ df["Effective Number of Assets"] = effective_nb_assets
848
+ df["Assets Number"] = assets_number
823
849
  return df
824
850
 
825
851
  def get_weight(self, asset: str) -> float:
@@ -114,10 +114,12 @@ class LoadingMatrixRegression(BaseLoadingMatrix):
114
114
  self.loading_matrix_ = np.array(
115
115
  [self.multi_output_regressor_.estimators_[i].coef_ for i in range(n_assets)]
116
116
  )
117
- self.intercepts_ = np.array([
118
- self.multi_output_regressor_.estimators_[i].intercept_
119
- for i in range(n_assets)
120
- ])
117
+ self.intercepts_ = np.array(
118
+ [
119
+ self.multi_output_regressor_.estimators_[i].intercept_
120
+ for i in range(n_assets)
121
+ ]
122
+ )
121
123
 
122
124
 
123
125
  class FactorModel(BasePrior):
@@ -290,13 +290,15 @@ class _Dendrogram:
290
290
  Sets and returns default layout object for dendrogram figure.
291
291
 
292
292
  """
293
- self.layout.update({
294
- "showlegend": False,
295
- "autosize": False,
296
- "hovermode": "closest",
297
- "width": width,
298
- "height": height,
299
- })
293
+ self.layout.update(
294
+ {
295
+ "showlegend": False,
296
+ "autosize": False,
297
+ "hovermode": "closest",
298
+ "width": width,
299
+ "height": height,
300
+ }
301
+ )
300
302
 
301
303
  self.set_axis_layout(self.xaxis)
302
304
  self.set_axis_layout(self.yaxis)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: skfolio
3
- Version: 0.1.1
3
+ Version: 0.1.3
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>
@@ -80,7 +80,6 @@ Requires-Dist: sphinx-sitemap ; extra == 'docs'
80
80
  Provides-Extra: tests
81
81
  Requires-Dist: pytest ; extra == 'tests'
82
82
  Requires-Dist: pytest-cov ; extra == 'tests'
83
- Requires-Dist: black ; extra == 'tests'
84
83
  Requires-Dist: ruff ; extra == 'tests'
85
84
 
86
85
  .. -*- mode: rst -*-
@@ -645,9 +644,9 @@ If you use `skfolio` in a scientific publication, we would appreciate citations:
645
644
  Bibtex entry::
646
645
 
647
646
  @misc{skfolio,
648
- author = {Hugo Delatte, Carlo Nicolini},
649
- title = {skfolio},
650
- year = {2023},
651
- url = {https://github.com/skfolio/skfolio}
652
-
647
+ author = {Delatte, Hugo and Nicolini, Carlo},
648
+ title = {skfolio},
649
+ year = {2023},
650
+ url = {https://github.com/skfolio/skfolio}
651
+ }
653
652
 
@@ -4,22 +4,22 @@ skfolio/typing.py,sha256=yEZiCZ6UIyfYUqtfj9Kf2KA9mrjUbmxyzpH9uqVboJs,1378
4
4
  skfolio/cluster/__init__.py,sha256=4g-PFB_ld9BhiQ1ZPvvAorpFbRwd_p_DkeRlulDv2Hk,251
5
5
  skfolio/cluster/_hierarchical.py,sha256=SoISGgdyq4Rgqq1_TCzMbLv69c8a2Q91j_s9-jqaB3E,12817
6
6
  skfolio/datasets/__init__.py,sha256=9Tpf0Uj8wgr-g7xqvqQP4S4TUYDUNmNmK8t6lqBw2Fs,407
7
- skfolio/datasets/_base.py,sha256=GYvblFzTyfTs-Tij20FKWgVDCIT1n7y4uwx4TkZzdHc,13915
7
+ skfolio/datasets/_base.py,sha256=laAj8vE8evEKv6NAAJdypLrsfmlhqOJ27aP_AcpcxVQ,13952
8
8
  skfolio/datasets/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  skfolio/datasets/data/factors_dataset.csv.gz,sha256=brCJlT25DJo40yg1gnUXAakNtvWZZYR_1ksFeN5JcWE,36146
10
10
  skfolio/datasets/data/sp500_dataset.csv.gz,sha256=7iHKwovvsdCnOanOsiGE-ZU5RyaqDP3pohlB0awErA0,426065
11
11
  skfolio/datasets/data/sp500_index.csv.gz,sha256=iUw0QxwoT4aqZKRn4Xbio8m2l8hX65qzUAbC3VXT_fI,41898
12
12
  skfolio/distance/__init__.py,sha256=vpdmjFlJeI0AvPV3r5tp2zooAG4N9ihCwPlaqqdVj1w,547
13
13
  skfolio/distance/_base.py,sha256=jBgRk6lZrP1woSI9541fTfxBBkp4WCTLlRPmWcmA3j4,1326
14
- skfolio/distance/_distance.py,sha256=PHDqEourtqKSSFYiXKaUPQQqNFEqIEBhWcbWwe3fxjg,18539
15
- skfolio/measures/__init__.py,sha256=Wm8soTkAapZ-g82INBpljgKfxkwCAIJdqjBOGVZBeQ8,1571
16
- skfolio/measures/_enums.py,sha256=oy8wPm3EGsHokgLXe9xfUKet4vAuvch0cJuISH9RNvk,8902
17
- skfolio/measures/_measures.py,sha256=nrpfaOVF94_ZpZXe2ciaBNzioGVTkzuYTmkYp9_EMec,16826
14
+ skfolio/distance/_distance.py,sha256=nQRm141leyCXtjxqXNhsTPtq2dATbpyyEQHKhZ98rE4,18538
15
+ skfolio/measures/__init__.py,sha256=9ThQikIAQcfKRLSCoMr-Z5vE2-ThtYe9B-L40b6Ewg0,1631
16
+ skfolio/measures/_enums.py,sha256=NJcngwg9b2JMMiekwkWU9POfnDvgfUgtYtyV2VSFDVM,8934
17
+ skfolio/measures/_measures.py,sha256=VU9tahJKJvt8PaJZNxWkmFkFU4PsN0FfYO32Je6D53E,16829
18
18
  skfolio/metrics/__init__.py,sha256=MomHJ5_bgjq4qUwGS2bfhNmG_ld0oQ4wK6y0Yy_Eonc,75
19
19
  skfolio/metrics/_scorer.py,sha256=h1VuZk-zzn4rIChHl9FvM7RxqVT3b-jR1CEB-cr9F2s,4306
20
20
  skfolio/model_selection/__init__.py,sha256=QYYm5lYyioZuPnsTu-b3lz-tCcl3Gwrx-y9IIvep13A,453
21
- skfolio/model_selection/_combinatorial.py,sha256=z4nhqIq98iGMP9I3GM8ng1WRJDJQn4eQ56bYaw5JWog,14716
22
- skfolio/model_selection/_validation.py,sha256=uPk9HhOak1jh3PEjNMyi3jx4PzIW2fxnqdC7u1yWGwY,7644
21
+ skfolio/model_selection/_combinatorial.py,sha256=Dts2eic69ZTa8HOLcf3n1MyfakA_HxRT7JWn5WTXGlQ,14782
22
+ skfolio/model_selection/_validation.py,sha256=Rs3j6LFfm8HJCnaoUXlPnNsqxIyjRmMhmGWvvJ0olXA,7686
23
23
  skfolio/model_selection/_walk_forward.py,sha256=pbMD8VM1OoKiEtrlPeCLG29xVijsq1RArSjTvGO1FnU,7539
24
24
  skfolio/moments/__init__.py,sha256=BaP6FjU-CEsV_mcC2AOKXNFy-_wXZsk-jqzJG6mTpsM,746
25
25
  skfolio/moments/covariance/__init__.py,sha256=KuzhGuiu-eOwQMgWmEhFhqCcOmiayrYp5yeL1NsFW98,563
@@ -29,13 +29,13 @@ skfolio/moments/expected_returns/__init__.py,sha256=NETEcKKYKsQvzUU4ZIq6mgT14zdr
29
29
  skfolio/moments/expected_returns/_base.py,sha256=xk9mzi48uCOHaMTGQBMr3FU7Ai_shxYhmGeOsVwjv9Q,871
30
30
  skfolio/moments/expected_returns/_expected_returns.py,sha256=T_tt_dsYgXrjIM2REUii7_4_R8IEc3xdtuv45yYM-5o,13388
31
31
  skfolio/optimization/__init__.py,sha256=vXIbwWJL48zJ1jy7ZB2PPBVx7rZo0vVA8QQQuD-L6ts,1021
32
- skfolio/optimization/_base.py,sha256=5GEMjlw5jrbygTp-4ZCk7cmwjJ0PBOoNdULqypVlfQM,5606
32
+ skfolio/optimization/_base.py,sha256=O8jYu9Tv1IHIHvvcRXBCa-rjPnhKYvVn_Up6QI2ymig,5668
33
33
  skfolio/optimization/cluster/__init__.py,sha256=M3xVdYhNKp4e9CB7hzb4yjTxkkNCHh7Mt_KGFFrkOgs,388
34
34
  skfolio/optimization/cluster/_nco.py,sha256=MKzNvDIAbqS_D41Vp7tNa7OrXYq_bYVSQEVbVCHOEWA,14834
35
35
  skfolio/optimization/cluster/hierarchical/__init__.py,sha256=YnfcPHvjwB6kcG4hoQqc0NqIJKaG7OjBtmXNbOxCq08,405
36
36
  skfolio/optimization/cluster/hierarchical/_base.py,sha256=0FtVcrMOFsQIJVaShf_qoHBRSuVmR4qzmJdvJc214HI,17255
37
37
  skfolio/optimization/cluster/hierarchical/_herc.py,sha256=JyXYX4PE17alCzIv6piF-G7_nprgzdzfYp35kjAeWMo,17235
38
- skfolio/optimization/cluster/hierarchical/_hrp.py,sha256=xdnbYNcY1Vpv-mDw-JAGz5o--Rl2b8CfGzyunLJe75M,16121
38
+ skfolio/optimization/cluster/hierarchical/_hrp.py,sha256=CSBfOk47uv_9tLdWTI2dnh2UXDqy8iXdBbc4rK7G7-0,16120
39
39
  skfolio/optimization/convex/__init__.py,sha256=F6BPFikTo0B-7JCKazqLGEwM3RkgTNbFm5GAGkaq9Uo,570
40
40
  skfolio/optimization/convex/_base.py,sha256=CyEP2JXP0ISnEZRsV-tumH9wwPGBbyM6MDf1B-jCxyw,75413
41
41
  skfolio/optimization/convex/_distributionally_robust.py,sha256=nQW_MD0wlVY_tvLvRq_CvezOn4q92YC7wHfzFE9k9tY,17308
@@ -43,16 +43,16 @@ skfolio/optimization/convex/_maximum_diversification.py,sha256=8wQn5eFEat5wixmu0
43
43
  skfolio/optimization/convex/_mean_risk.py,sha256=ivAjLXis4fUZ9XOvh_iOemfnvgDAzrK3LDvrlaa2TpA,43130
44
44
  skfolio/optimization/convex/_risk_budgeting.py,sha256=wXCgn64w2alAGG-dGJ8IwFrhYVtybM-O2hXiFaXietg,23618
45
45
  skfolio/optimization/ensemble/__init__.py,sha256=8TXxcxH2_gG3C1xtgQj9OHHr0Le8lhdejtlURL6T3ZY,158
46
- skfolio/optimization/ensemble/_base.py,sha256=vOi08U1MjoceD_xMFKTdM8egd1sY0GsCh1BSJuKH_fQ,3445
47
- skfolio/optimization/ensemble/_stacking.py,sha256=3yqGHE1MpnugkJ0Z6fp7bfYLOuImsfmeiMQ8XDdIdZY,13098
46
+ skfolio/optimization/ensemble/_base.py,sha256=GaNDQu6ivosYuwMrb-b0PhToCsNrmhSYyXkxeM8W4rU,3399
47
+ skfolio/optimization/ensemble/_stacking.py,sha256=2PodXf_JahToShSAbwQRXosEer3ESOAhpsnB6SCwztk,13148
48
48
  skfolio/optimization/naive/__init__.py,sha256=Dkr55R48urC-jfYN007NTbei16N91Na_EDYLVqzhGgQ,147
49
49
  skfolio/optimization/naive/_naive.py,sha256=sadsU8TnNRf28EDLg-KZ4yJm2FvV204vdsb1MhVJyMQ,5561
50
50
  skfolio/population/__init__.py,sha256=rsPPMUv95aTK7vmpPeQwF8NzFuBwk6RDo5g4HNaPzNM,80
51
- skfolio/population/_population.py,sha256=cyHdpZr6Ib725CRE_rr0irI4sHEcVEAY-Gmy--1goKo,29242
51
+ skfolio/population/_population.py,sha256=O5o8OmR7szAA6NRKvELyq2P6B14jHMUaB8LMbrS3b7E,29411
52
52
  skfolio/portfolio/__init__.py,sha256=YYtcAPmA2zeCxFGTXegg2FXcA7py6CxOX7IMTdYuXl0,586
53
- skfolio/portfolio/_base.py,sha256=XHSFrQJRY6nIyUG8sd8ZgbwZt7_ZKlMRNCfOqdls0Rw,38314
53
+ skfolio/portfolio/_base.py,sha256=jO6YKXu8oxE-uldl2CayLvbA40yfeCA1vNa_xm-WcWo,38313
54
54
  skfolio/portfolio/_multi_period_portfolio.py,sha256=63RwL0oTn-3L5LON6f2e9J58zw9q8S2gQ5c8JfSnN28,22759
55
- skfolio/portfolio/_portfolio.py,sha256=axthHXaavCll_qXrYvJqfk-6AuMNDb-syD__jU_9acU,30714
55
+ skfolio/portfolio/_portfolio.py,sha256=I2P-ogv78wx6aRytHN7z8BHLkye-E8T5LinVARgsuIQ,31649
56
56
  skfolio/pre_selection/__init__.py,sha256=VtUtDn-U-Mn_xR2k7yfld0Yb0rPhLakEAiBwUyi-4Z8,189
57
57
  skfolio/pre_selection/_pre_selection.py,sha256=w84T14nKmzkgzbw5CW_AIlci741lXYxKUwB5pBjhTTI,12163
58
58
  skfolio/preprocessing/__init__.py,sha256=15A1bzfPsbfxxXgGP1gstf4R0E_347Wn18z5W5jH-hk,94
@@ -61,7 +61,7 @@ skfolio/prior/__init__.py,sha256=jql8NTiWlykPKJUXTOPdqm531mP8Pul1QAR6hXTXA6c,446
61
61
  skfolio/prior/_base.py,sha256=Dx6rX0X6ymDiieFOI-ik3xMNNFhYEtwLSXOdajf5wZY,1927
62
62
  skfolio/prior/_black_litterman.py,sha256=JuwVXLXY5qHETBZDg0wmBGMSQehJp_1t7c1-kanKaiU,9397
63
63
  skfolio/prior/_empirical.py,sha256=YhCYW8R3vqs3ntF4WSokuwLW6Gd98df7f8LL8zCS-D0,5740
64
- skfolio/prior/_factor_model.py,sha256=E42sx_CbT-GbkT-BBb59XrUP4DMYJzuf3I2MEcGEnyE,9608
64
+ skfolio/prior/_factor_model.py,sha256=feQzb04-BjBN-ryba5niAhI3RRuRAcUxD8yuiNOIWsI,9642
65
65
  skfolio/uncertainty_set/__init__.py,sha256=LlMHtYv9G9fgtM7m4sCSToS9et57Pm2Q2gGchTVrj6c,617
66
66
  skfolio/uncertainty_set/_base.py,sha256=rZ3g2AhDKFQTPajgh6Fz5S5TTf0qM4Ie6RGxPhp32D8,3301
67
67
  skfolio/uncertainty_set/_bootstrap.py,sha256=Rig8ZGc8rEOnYygPyTaDSu5lp3wGuZrQVRoJTm3UuAA,10301
@@ -73,9 +73,9 @@ skfolio/utils/sorting.py,sha256=lSjMvH2L-sSj-06B3MlwBrH1rtjCeGEe4hG894W7TE0,3504
73
73
  skfolio/utils/stats.py,sha256=IP36nMc5j5Hcqjbg7lvDIsGp1GWRdOh5jU3W6Z8nkYs,13132
74
74
  skfolio/utils/tools.py,sha256=roj4zTwmfunPb8HtxcOPAsCKpk0ZPEPnQztSglE9t4o,15351
75
75
  skfolio/utils/fixes/__init__.py,sha256=knHau8PRZP07XDHR59CW8VWxkpTP0gdr6RAHJrO-zaA,95
76
- skfolio/utils/fixes/_dendrogram.py,sha256=QK0OYAmlDe4sdrbFtRvxIlKfPlOGyA2zmsZIz1fIMsM,13505
77
- skfolio-0.1.1.dist-info/LICENSE,sha256=F6Gi-ZJX5BlVzYK8R9NcvAkAsKa7KO29xB1OScbrH6Q,1526
78
- skfolio-0.1.1.dist-info/METADATA,sha256=hTWceCx0MfXBQ4x3awiMxPxIxHVcxcqAM52DauFX7Vg,19613
79
- skfolio-0.1.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
80
- skfolio-0.1.1.dist-info/top_level.txt,sha256=NXEaoS9Ms7t32gxkb867nV0OKlU0KmssL7IJBVo0fJs,8
81
- skfolio-0.1.1.dist-info/RECORD,,
76
+ skfolio/utils/fixes/_dendrogram.py,sha256=9aIhSnMwpQHJhQx7IpXC3jlw6YJ3H4XQnnx_d4nMllQ,13551
77
+ skfolio-0.1.3.dist-info/LICENSE,sha256=F6Gi-ZJX5BlVzYK8R9NcvAkAsKa7KO29xB1OScbrH6Q,1526
78
+ skfolio-0.1.3.dist-info/METADATA,sha256=JXNH0_kBjWWR-hp4XQfTtLWP5KIQW5i4pN7SK7lFpYY,19567
79
+ skfolio-0.1.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
80
+ skfolio-0.1.3.dist-info/top_level.txt,sha256=NXEaoS9Ms7t32gxkb867nV0OKlU0KmssL7IJBVo0fJs,8
81
+ skfolio-0.1.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5