skfolio 0.0.11__py3-none-any.whl → 0.1.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.
@@ -608,3 +608,28 @@ def gini_mean_difference(returns: np.ndarray) -> float:
608
608
  """
609
609
  w = owa_gmd_weights(len(returns))
610
610
  return float(w @ np.sort(returns, axis=0))
611
+
612
+
613
+ 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]_:
616
+ .. math:: N_{eff} = \frac{1}{\Vert w \Vert_{2}^{2}}
617
+
618
+ It quantifies portfolio concentration, with a higher value indicating a more diversified portfolio.
619
+
620
+ Parameters
621
+ ----------
622
+ weights : ndarray of shape (n_assets,)
623
+ Weights of the assets.
624
+
625
+ Returns
626
+ -------
627
+ value : float
628
+ Effective number of assets.
629
+
630
+ References
631
+ ----------
632
+ .. [1] "Banking and Financial Institutions Law in a Nutshell".
633
+ Lovett, William Anthony (1988)
634
+ """
635
+ return 1.0 / (np.power(weights, 2).sum())
@@ -369,7 +369,6 @@ class BasePortfolio:
369
369
  _read_only_attrs: ClassVar[set] = {
370
370
  "returns",
371
371
  "observations",
372
- "n_observations",
373
372
  }
374
373
 
375
374
  # Arguments globally used in measures computation
@@ -401,7 +400,6 @@ class BasePortfolio:
401
400
  # public read-only
402
401
  "returns",
403
402
  "observations",
404
- "n_observations",
405
403
  # private
406
404
  "_loaded",
407
405
  # custom getter and setter
@@ -521,7 +519,6 @@ class BasePortfolio:
521
519
  self._fitness_measures = [PerfMeasure.MEAN, RiskMeasure.VARIANCE]
522
520
  else:
523
521
  self._fitness_measures = fitness_measures
524
- self.n_observations = len(observations)
525
522
  self._loaded = True
526
523
 
527
524
  def __reduce__(self):
@@ -531,9 +528,6 @@ class BasePortfolio:
531
528
  [getattr(self, arg) for arg in args_names(self.__init__)]
532
529
  )
533
530
 
534
- def __len__(self) -> int:
535
- return len(self.observations)
536
-
537
531
  def __repr__(self) -> str:
538
532
  return f"<{type(self).__name__} {self.name}>"
539
533
 
@@ -679,6 +673,11 @@ class BasePortfolio:
679
673
  return mt.get_drawdowns(returns=self.returns, compounded=self.compounded)
680
674
 
681
675
  # Classic property
676
+ @property
677
+ def n_observations(self) -> int:
678
+ """Number of observations"""
679
+ return len(self.observations)
680
+
682
681
  @property
683
682
  def returns_df(self) -> pd.Series:
684
683
  """Portfolio returns DataFrame."""
@@ -369,6 +369,9 @@ class MultiPeriodPortfolio(BasePortfolio):
369
369
  self.check_observations_order = check_observations_order
370
370
  self._set_portfolios(portfolios=portfolios)
371
371
 
372
+ def __len__(self) -> int:
373
+ return len(self.portfolios)
374
+
372
375
  def __getitem__(self, key: int | slice) -> Portfolio | list[Portfolio]:
373
376
  return self._portfolios[key]
374
377
 
@@ -571,12 +574,12 @@ class MultiPeriodPortfolio(BasePortfolio):
571
574
  """
572
575
  df = super().summary(formatted=formatted)
573
576
  portfolios_number = len(self)
574
- avg_assets_per_portfolio = np.mean([len(p) for p in self])
577
+ avg_assets_per_portfolio = np.mean([p.n_assets for p in self])
575
578
  if formatted:
576
579
  portfolios_number = str(int(portfolios_number))
577
580
  avg_assets_per_portfolio = f"{avg_assets_per_portfolio:0.1f}"
578
- df["Portfolios number"] = portfolios_number
579
- df["Avg nb of assets per portfolio"] = avg_assets_per_portfolio
581
+ df["Portfolios Number"] = portfolios_number
582
+ df["Avg nb of Assets per Portfolio"] = avg_assets_per_portfolio
580
583
  return df
581
584
 
582
585
  # Public methods
@@ -290,15 +290,13 @@ class _Dendrogram:
290
290
  Sets and returns default layout object for dendrogram figure.
291
291
 
292
292
  """
293
- self.layout.update(
294
- {
295
- "showlegend": False,
296
- "autosize": False,
297
- "hovermode": "closest",
298
- "width": width,
299
- "height": height,
300
- }
301
- )
293
+ self.layout.update({
294
+ "showlegend": False,
295
+ "autosize": False,
296
+ "hovermode": "closest",
297
+ "width": width,
298
+ "height": height,
299
+ })
302
300
 
303
301
  self.set_axis_layout(self.xaxis)
304
302
  self.set_axis_layout(self.yaxis)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: skfolio
3
- Version: 0.0.11
3
+ Version: 0.1.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>
@@ -85,7 +85,7 @@ Requires-Dist: ruff ; extra == 'tests'
85
85
 
86
86
  .. -*- mode: rst -*-
87
87
 
88
- |Licence|_ |Codecov|_ |Black|_ |PythonVersion|_ |PyPi|_ |CI/CD|_ |Downloads|_ |Ruff|_ |Website|_
88
+ |Licence|_ |Codecov|_ |Black|_ |PythonVersion|_ |PyPi|_ |CI/CD|_ |Downloads|_ |Ruff|_ |Contribution|_ |Website|_
89
89
 
90
90
  .. |Licence| image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
91
91
  .. _Licence: https://github.com/skfolio/skfolio/blob/main/LICENSE
@@ -111,7 +111,10 @@ Requires-Dist: ruff ; extra == 'tests'
111
111
  .. |Ruff| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
112
112
  .. _Ruff: https://github.com/astral-sh/ruff
113
113
 
114
- .. |Website| image:: https://img.shields.io/website-up-down-green-red/http/skfolio.org
114
+ .. |Contribution| image:: https://img.shields.io/badge/Contributions-Welcome-blue
115
+ .. _Contribution: https://github.com/skfolio/skfolio/blob/main/CONTRIBUTING.md
116
+
117
+ .. |Website| image:: https://img.shields.io/website-up-down-53cc0d-red/http/skfolio.org
115
118
  .. _Website: https://skfolio.org
116
119
 
117
120
  .. |PythonMinVersion| replace:: 3.10
@@ -127,7 +130,7 @@ Requires-Dist: ruff ; extra == 'tests'
127
130
  ===============
128
131
  |icon| skfolio
129
132
  ===============
130
- .. |icon| image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/favicon.png
133
+ .. |icon| image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/logo_animate.svg
131
134
  :width: 100
132
135
  :alt: skfolio documentation
133
136
  :target: https://skfolio.org/
@@ -14,7 +14,7 @@ skfolio/distance/_base.py,sha256=jBgRk6lZrP1woSI9541fTfxBBkp4WCTLlRPmWcmA3j4,132
14
14
  skfolio/distance/_distance.py,sha256=PHDqEourtqKSSFYiXKaUPQQqNFEqIEBhWcbWwe3fxjg,18539
15
15
  skfolio/measures/__init__.py,sha256=Wm8soTkAapZ-g82INBpljgKfxkwCAIJdqjBOGVZBeQ8,1571
16
16
  skfolio/measures/_enums.py,sha256=oy8wPm3EGsHokgLXe9xfUKet4vAuvch0cJuISH9RNvk,8902
17
- skfolio/measures/_measures.py,sha256=SPp-JGBXsf7KLcU3saq4KhP1HiReFxDoo3ojvk3wzQ0,16122
17
+ skfolio/measures/_measures.py,sha256=nrpfaOVF94_ZpZXe2ciaBNzioGVTkzuYTmkYp9_EMec,16826
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
@@ -50,8 +50,8 @@ skfolio/optimization/naive/_naive.py,sha256=sadsU8TnNRf28EDLg-KZ4yJm2FvV204vdsb1
50
50
  skfolio/population/__init__.py,sha256=rsPPMUv95aTK7vmpPeQwF8NzFuBwk6RDo5g4HNaPzNM,80
51
51
  skfolio/population/_population.py,sha256=cyHdpZr6Ib725CRE_rr0irI4sHEcVEAY-Gmy--1goKo,29242
52
52
  skfolio/portfolio/__init__.py,sha256=YYtcAPmA2zeCxFGTXegg2FXcA7py6CxOX7IMTdYuXl0,586
53
- skfolio/portfolio/_base.py,sha256=asQ4EG5gOjZvW20Z8YEj8G-9RZBL8uqpLCzD8GmdztI,38356
54
- skfolio/portfolio/_multi_period_portfolio.py,sha256=RFvag_bvvQNJSfJj2UThKxZvEGBTWjPHNW4EVyOq1_g,22688
53
+ skfolio/portfolio/_base.py,sha256=XHSFrQJRY6nIyUG8sd8ZgbwZt7_ZKlMRNCfOqdls0Rw,38314
54
+ skfolio/portfolio/_multi_period_portfolio.py,sha256=63RwL0oTn-3L5LON6f2e9J58zw9q8S2gQ5c8JfSnN28,22759
55
55
  skfolio/portfolio/_portfolio.py,sha256=axthHXaavCll_qXrYvJqfk-6AuMNDb-syD__jU_9acU,30714
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
@@ -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=9aIhSnMwpQHJhQx7IpXC3jlw6YJ3H4XQnnx_d4nMllQ,13551
77
- skfolio-0.0.11.dist-info/LICENSE,sha256=F6Gi-ZJX5BlVzYK8R9NcvAkAsKa7KO29xB1OScbrH6Q,1526
78
- skfolio-0.0.11.dist-info/METADATA,sha256=AOJvG3qDb_FLJ3s08wVfP8Wd2XnubyPklYMAAwiecBo,19430
79
- skfolio-0.0.11.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
80
- skfolio-0.0.11.dist-info/top_level.txt,sha256=NXEaoS9Ms7t32gxkb867nV0OKlU0KmssL7IJBVo0fJs,8
81
- skfolio-0.0.11.dist-info/RECORD,,
76
+ skfolio/utils/fixes/_dendrogram.py,sha256=QK0OYAmlDe4sdrbFtRvxIlKfPlOGyA2zmsZIz1fIMsM,13505
77
+ skfolio-0.1.0.dist-info/LICENSE,sha256=F6Gi-ZJX5BlVzYK8R9NcvAkAsKa7KO29xB1OScbrH6Q,1526
78
+ skfolio-0.1.0.dist-info/METADATA,sha256=zUZtTWjCZIla8MbEauTnhntSsQbJut6GWXk2cjJPMuE,19613
79
+ skfolio-0.1.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
80
+ skfolio-0.1.0.dist-info/top_level.txt,sha256=NXEaoS9Ms7t32gxkb867nV0OKlU0KmssL7IJBVo0fJs,8
81
+ skfolio-0.1.0.dist-info/RECORD,,