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.
- skfolio/measures/_measures.py +25 -0
- skfolio/portfolio/_base.py +5 -6
- skfolio/portfolio/_multi_period_portfolio.py +6 -3
- skfolio/utils/fixes/_dendrogram.py +7 -9
- {skfolio-0.0.11.dist-info → skfolio-0.1.0.dist-info}/METADATA +7 -4
- {skfolio-0.0.11.dist-info → skfolio-0.1.0.dist-info}/RECORD +9 -9
- {skfolio-0.0.11.dist-info → skfolio-0.1.0.dist-info}/LICENSE +0 -0
- {skfolio-0.0.11.dist-info → skfolio-0.1.0.dist-info}/WHEEL +0 -0
- {skfolio-0.0.11.dist-info → skfolio-0.1.0.dist-info}/top_level.txt +0 -0
skfolio/measures/_measures.py
CHANGED
@@ -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())
|
skfolio/portfolio/_base.py
CHANGED
@@ -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([
|
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
|
579
|
-
df["Avg nb of
|
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
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
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
|
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
|
-
.. |
|
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/
|
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=
|
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=
|
54
|
-
skfolio/portfolio/_multi_period_portfolio.py,sha256=
|
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=
|
77
|
-
skfolio-0.0.
|
78
|
-
skfolio-0.0.
|
79
|
-
skfolio-0.0.
|
80
|
-
skfolio-0.0.
|
81
|
-
skfolio-0.0.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|