skfolio 0.0.7__tar.gz → 0.0.9__tar.gz
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-0.0.7/src/skfolio.egg-info → skfolio-0.0.9}/PKG-INFO +75 -52
- {skfolio-0.0.7 → skfolio-0.0.9}/README.rst +74 -50
- {skfolio-0.0.7 → skfolio-0.0.9}/pyproject.toml +1 -2
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/model_selection/_combinatorial.py +2 -2
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/_base.py +1 -1
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/cluster/_nco.py +5 -5
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/cluster/hierarchical/_base.py +7 -7
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/cluster/hierarchical/_herc.py +17 -14
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/cluster/hierarchical/_hrp.py +13 -12
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/convex/_base.py +10 -10
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/convex/_distributionally_robust.py +9 -9
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/convex/_maximum_diversification.py +10 -10
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/convex/_mean_risk.py +10 -10
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/convex/_risk_budgeting.py +11 -11
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/ensemble/_stacking.py +6 -4
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/prior/_black_litterman.py +2 -2
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/prior/_factor_model.py +2 -2
- {skfolio-0.0.7 → skfolio-0.0.9/src/skfolio.egg-info}/PKG-INFO +75 -52
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio.egg-info/requires.txt +0 -1
- {skfolio-0.0.7 → skfolio-0.0.9}/LICENSE +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/MANIFEST.in +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/setup.cfg +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/cluster/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/cluster/_hierarchical.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/datasets/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/datasets/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/datasets/data/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/datasets/data/factors_dataset.csv.gz +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/datasets/data/sp500_dataset.csv.gz +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/datasets/data/sp500_index.csv.gz +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/distance/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/distance/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/distance/_distance.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/exceptions.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/measures/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/measures/_enums.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/measures/_measures.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/metrics/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/metrics/_scorer.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/model_selection/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/model_selection/_validation.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/model_selection/_walk_forward.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/moments/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/moments/covariance/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/moments/covariance/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/moments/covariance/_covariance.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/moments/expected_returns/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/moments/expected_returns/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/moments/expected_returns/_expected_returns.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/cluster/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/cluster/hierarchical/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/convex/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/ensemble/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/ensemble/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/naive/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/optimization/naive/_naive.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/population/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/population/_population.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/portfolio/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/portfolio/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/portfolio/_multi_period_portfolio.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/portfolio/_portfolio.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/pre_selection/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/pre_selection/_pre_selection.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/preprocessing/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/preprocessing/_returns.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/prior/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/prior/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/prior/_empirical.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/typing.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/uncertainty_set/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/uncertainty_set/_base.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/uncertainty_set/_bootstrap.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/uncertainty_set/_empirical.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/utils/__init__.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/utils/bootstrap.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/utils/equations.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/utils/sorting.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/utils/stats.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio/utils/tools.py +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio.egg-info/SOURCES.txt +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio.egg-info/dependency_links.txt +0 -0
- {skfolio-0.0.7 → skfolio-0.0.9}/src/skfolio.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: skfolio
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.9
|
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>
|
@@ -78,7 +78,6 @@ Requires-Dist: kaleido; extra == "docs"
|
|
78
78
|
Requires-Dist: sphinx-copybutton; extra == "docs"
|
79
79
|
Requires-Dist: numpydoc; extra == "docs"
|
80
80
|
Requires-Dist: sphinx-togglebutton; extra == "docs"
|
81
|
-
Requires-Dist: jupyterlite-sphinx; extra == "docs"
|
82
81
|
Requires-Dist: sphinx-favicon; extra == "docs"
|
83
82
|
Requires-Dist: sphinx-prompt; extra == "docs"
|
84
83
|
Requires-Dist: sphinxext.opengraph; extra == "docs"
|
@@ -128,8 +127,10 @@ Requires-Dist: sphinx-favicon; extra == "docs"
|
|
128
127
|
|
129
128
|
|
130
129
|
**skfolio** is a Python library for portfolio optimization built on top of scikit-learn.
|
131
|
-
It
|
132
|
-
cross-validate portfolio models.
|
130
|
+
It offers a unified interface and tools compatible with scikit-learn to build, fine-tune,
|
131
|
+
and cross-validate portfolio models.
|
132
|
+
|
133
|
+
It is distributed under the open source 3-Clause BSD license.
|
133
134
|
|
134
135
|
.. image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/expo.jpg
|
135
136
|
:target: https://skfolio.org/auto_examples/
|
@@ -146,7 +147,7 @@ Important links
|
|
146
147
|
Installation
|
147
148
|
~~~~~~~~~~~~
|
148
149
|
|
149
|
-
|
150
|
+
`skfolio` is available on PyPI and can be installed with::
|
150
151
|
|
151
152
|
pip install -U skfolio
|
152
153
|
|
@@ -155,7 +156,7 @@ To install skfolio::
|
|
155
156
|
Dependencies
|
156
157
|
~~~~~~~~~~~~
|
157
158
|
|
158
|
-
skfolio requires:
|
159
|
+
`skfolio` requires:
|
159
160
|
|
160
161
|
- python (>= |PythonMinVersion|)
|
161
162
|
- numpy (>= |NumpyMinVersion|)
|
@@ -168,30 +169,37 @@ skfolio requires:
|
|
168
169
|
|
169
170
|
Key Concepts
|
170
171
|
~~~~~~~~~~~~
|
171
|
-
Since the development of modern portfolio theory by Markowitz (1952), mean-variance
|
172
|
-
has received considerable attention.
|
173
|
-
|
174
|
-
|
175
|
-
|
172
|
+
Since the development of modern portfolio theory by Markowitz (1952), mean-variance
|
173
|
+
optimization (MVO) has received considerable attention.
|
174
|
+
|
175
|
+
Unfortunately, it faces a number of shortcomings, including high sensitivity to the
|
176
|
+
input parameters (expected returns and covariance), weight concentration, high turnover,
|
177
|
+
and poor out-of-sample performance.
|
178
|
+
|
179
|
+
It is well known that naive allocation (1/N, inverse-vol, etc.) tends to outperform
|
180
|
+
MVO out-of-sample (DeMiguel, 2007).
|
176
181
|
|
177
|
-
Numerous approaches have been developed to alleviate these shortcomings (shrinkage,
|
178
|
-
additional constraints, regularization, uncertainty set, higher moments,
|
179
|
-
left-tail risk optimization, distributionally robust
|
180
|
-
ensemble methods
|
182
|
+
Numerous approaches have been developed to alleviate these shortcomings (shrinkage,
|
183
|
+
additional constraints, regularization, uncertainty set, higher moments, Bayesian
|
184
|
+
approaches, coherent risk measures, left-tail risk optimization, distributionally robust
|
185
|
+
optimization, factor model, risk-parity, hierarchical clustering, ensemble methods,
|
186
|
+
pre-selection, etc.).
|
181
187
|
|
182
|
-
With this large number of methods, added to the fact that they can be composed together
|
183
|
-
|
184
|
-
and
|
188
|
+
With this large number of methods, added to the fact that they can be composed together,
|
189
|
+
there is a need for a unified framework with a machine learning approach to perform
|
190
|
+
model selection, validation, and parameter tuning while reducing the risk of data
|
191
|
+
leakage and overfitting.
|
192
|
+
|
193
|
+
This framework is built on scikit-learn's API.
|
185
194
|
|
186
195
|
Available models
|
187
196
|
~~~~~~~~~~~~~~~~
|
188
|
-
The current release contains:
|
189
197
|
|
190
|
-
* Optimization
|
198
|
+
* Portfolio Optimization:
|
191
199
|
* Naive:
|
192
200
|
* Equal-Weighted
|
193
201
|
* Inverse-Volatility
|
194
|
-
* Random (
|
202
|
+
* Random (Dirichlet)
|
195
203
|
* Convex:
|
196
204
|
* Mean-Risk
|
197
205
|
* Risk Budgeting
|
@@ -201,27 +209,27 @@ The current release contains:
|
|
201
209
|
* Hierarchical Risk Parity
|
202
210
|
* Hierarchical Equal Risk Contribution
|
203
211
|
* Nested Clusters Optimization
|
204
|
-
* Ensemble
|
212
|
+
* Ensemble Methods:
|
205
213
|
* Stacking Optimization
|
206
214
|
|
207
|
-
*
|
208
|
-
*
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
* Distance
|
215
|
+
* Expected Returns Estimator:
|
216
|
+
* Empirical
|
217
|
+
* Exponentially Weighted
|
218
|
+
* Equilibrium
|
219
|
+
* Shrinkage
|
220
|
+
|
221
|
+
* Covariance Estimator:
|
222
|
+
* Empirical
|
223
|
+
* Gerber
|
224
|
+
* Denoising
|
225
|
+
* Denoting
|
226
|
+
* Exponentially Weighted
|
227
|
+
* Ledoit-Wolf
|
228
|
+
* Oracle Approximating Shrinkage
|
229
|
+
* Shrunk Covariance
|
230
|
+
* Graphical Lasso CV
|
231
|
+
|
232
|
+
* Distance Estimator:
|
225
233
|
* Pearson Distance
|
226
234
|
* Kendall Distance
|
227
235
|
* Spearman Distance
|
@@ -229,12 +237,12 @@ The current release contains:
|
|
229
237
|
* Distance Correlation
|
230
238
|
* Variation of Information
|
231
239
|
|
232
|
-
* Prior
|
240
|
+
* Prior Estimator:
|
233
241
|
* Empirical
|
234
242
|
* Black & Litterman
|
235
243
|
* Factor Model
|
236
244
|
|
237
|
-
* Uncertainty Set
|
245
|
+
* Uncertainty Set Estimator:
|
238
246
|
* On Expected Returns:
|
239
247
|
* Empirical
|
240
248
|
* Circular Bootstrap
|
@@ -242,18 +250,18 @@ The current release contains:
|
|
242
250
|
* Empirical
|
243
251
|
* Circular bootstrap
|
244
252
|
|
245
|
-
* Pre-Selection
|
253
|
+
* Pre-Selection Transformer:
|
246
254
|
* Non-Dominated Selection
|
247
255
|
* Select K Extremes (Best or Worst)
|
248
256
|
* Drop Highly Correlated Assets
|
249
257
|
|
250
258
|
* Cross-Validation and Model Selection:
|
251
|
-
* Compatible with all `sklearn` methods (KFold,
|
259
|
+
* Compatible with all `sklearn` methods (KFold, etc.)
|
252
260
|
* Walk Forward
|
253
|
-
* Combinatorial Purged Cross-
|
261
|
+
* Combinatorial Purged Cross-Validation
|
254
262
|
|
255
263
|
* Hyper-Parameter Tuning:
|
256
|
-
* Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV
|
264
|
+
* Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV)
|
257
265
|
|
258
266
|
* Risk Measures:
|
259
267
|
* Variance
|
@@ -277,9 +285,24 @@ The current release contains:
|
|
277
285
|
* Skew
|
278
286
|
* Kurtosis
|
279
287
|
|
288
|
+
* Optimization Features:
|
289
|
+
* Minimize Risk
|
290
|
+
* Maximize Returns
|
291
|
+
* Maximize Utility
|
292
|
+
* Maximize Ratio
|
293
|
+
* Transaction Costs
|
294
|
+
* Management Fees
|
295
|
+
* L1 and L2 Regularization
|
296
|
+
* Weight Constraints
|
297
|
+
* Group Constraints
|
298
|
+
* Budget Constraints
|
299
|
+
* Tracking Error Constraints
|
300
|
+
* Turnover Constraints
|
301
|
+
|
280
302
|
Quickstart
|
281
303
|
~~~~~~~~~~
|
282
|
-
The code snippets below are designed to introduce
|
304
|
+
The code snippets below are designed to introduce the functionality of `skfolio` so you
|
305
|
+
can start using it quickly. It follows the same API as scikit-learn.
|
283
306
|
|
284
307
|
Imports
|
285
308
|
-------
|
@@ -591,9 +614,9 @@ Combinatorial Purged Cross-Validation
|
|
591
614
|
Recognition
|
592
615
|
~~~~~~~~~~~
|
593
616
|
|
594
|
-
We would like to
|
595
|
-
scikit-learn and cvxpy but also the contributors of the following packages that
|
596
|
-
|
617
|
+
We would like to thank all contributors behind our direct dependencies, such as
|
618
|
+
scikit-learn and cvxpy, but also the contributors of the following packages that were a
|
619
|
+
source of inspiration:
|
597
620
|
|
598
621
|
* PyPortfolioOpt
|
599
622
|
* Riskfolio-Lib
|
@@ -606,11 +629,11 @@ were a source of inspiration:
|
|
606
629
|
Citation
|
607
630
|
~~~~~~~~
|
608
631
|
|
609
|
-
If you use skfolio in a scientific publication, we would appreciate citations:
|
632
|
+
If you use `skfolio` in a scientific publication, we would appreciate citations:
|
610
633
|
|
611
634
|
Bibtex entry::
|
612
635
|
|
613
|
-
@misc{
|
636
|
+
@misc{skfolio,
|
614
637
|
author = {Hugo Delatte},
|
615
638
|
title = {skfolio},
|
616
639
|
year = {2023},
|
@@ -41,8 +41,10 @@
|
|
41
41
|
|
42
42
|
|
43
43
|
**skfolio** is a Python library for portfolio optimization built on top of scikit-learn.
|
44
|
-
It
|
45
|
-
cross-validate portfolio models.
|
44
|
+
It offers a unified interface and tools compatible with scikit-learn to build, fine-tune,
|
45
|
+
and cross-validate portfolio models.
|
46
|
+
|
47
|
+
It is distributed under the open source 3-Clause BSD license.
|
46
48
|
|
47
49
|
.. image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/expo.jpg
|
48
50
|
:target: https://skfolio.org/auto_examples/
|
@@ -59,7 +61,7 @@ Important links
|
|
59
61
|
Installation
|
60
62
|
~~~~~~~~~~~~
|
61
63
|
|
62
|
-
|
64
|
+
`skfolio` is available on PyPI and can be installed with::
|
63
65
|
|
64
66
|
pip install -U skfolio
|
65
67
|
|
@@ -68,7 +70,7 @@ To install skfolio::
|
|
68
70
|
Dependencies
|
69
71
|
~~~~~~~~~~~~
|
70
72
|
|
71
|
-
skfolio requires:
|
73
|
+
`skfolio` requires:
|
72
74
|
|
73
75
|
- python (>= |PythonMinVersion|)
|
74
76
|
- numpy (>= |NumpyMinVersion|)
|
@@ -81,30 +83,37 @@ skfolio requires:
|
|
81
83
|
|
82
84
|
Key Concepts
|
83
85
|
~~~~~~~~~~~~
|
84
|
-
Since the development of modern portfolio theory by Markowitz (1952), mean-variance
|
85
|
-
has received considerable attention.
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
Since the development of modern portfolio theory by Markowitz (1952), mean-variance
|
87
|
+
optimization (MVO) has received considerable attention.
|
88
|
+
|
89
|
+
Unfortunately, it faces a number of shortcomings, including high sensitivity to the
|
90
|
+
input parameters (expected returns and covariance), weight concentration, high turnover,
|
91
|
+
and poor out-of-sample performance.
|
92
|
+
|
93
|
+
It is well known that naive allocation (1/N, inverse-vol, etc.) tends to outperform
|
94
|
+
MVO out-of-sample (DeMiguel, 2007).
|
89
95
|
|
90
|
-
Numerous approaches have been developed to alleviate these shortcomings (shrinkage,
|
91
|
-
additional constraints, regularization, uncertainty set, higher moments,
|
92
|
-
left-tail risk optimization, distributionally robust
|
93
|
-
ensemble methods
|
96
|
+
Numerous approaches have been developed to alleviate these shortcomings (shrinkage,
|
97
|
+
additional constraints, regularization, uncertainty set, higher moments, Bayesian
|
98
|
+
approaches, coherent risk measures, left-tail risk optimization, distributionally robust
|
99
|
+
optimization, factor model, risk-parity, hierarchical clustering, ensemble methods,
|
100
|
+
pre-selection, etc.).
|
94
101
|
|
95
|
-
With this large number of methods, added to the fact that they can be composed together
|
96
|
-
|
97
|
-
and
|
102
|
+
With this large number of methods, added to the fact that they can be composed together,
|
103
|
+
there is a need for a unified framework with a machine learning approach to perform
|
104
|
+
model selection, validation, and parameter tuning while reducing the risk of data
|
105
|
+
leakage and overfitting.
|
106
|
+
|
107
|
+
This framework is built on scikit-learn's API.
|
98
108
|
|
99
109
|
Available models
|
100
110
|
~~~~~~~~~~~~~~~~
|
101
|
-
The current release contains:
|
102
111
|
|
103
|
-
* Optimization
|
112
|
+
* Portfolio Optimization:
|
104
113
|
* Naive:
|
105
114
|
* Equal-Weighted
|
106
115
|
* Inverse-Volatility
|
107
|
-
* Random (
|
116
|
+
* Random (Dirichlet)
|
108
117
|
* Convex:
|
109
118
|
* Mean-Risk
|
110
119
|
* Risk Budgeting
|
@@ -114,27 +123,27 @@ The current release contains:
|
|
114
123
|
* Hierarchical Risk Parity
|
115
124
|
* Hierarchical Equal Risk Contribution
|
116
125
|
* Nested Clusters Optimization
|
117
|
-
* Ensemble
|
126
|
+
* Ensemble Methods:
|
118
127
|
* Stacking Optimization
|
119
128
|
|
120
|
-
*
|
121
|
-
*
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
* Distance
|
129
|
+
* Expected Returns Estimator:
|
130
|
+
* Empirical
|
131
|
+
* Exponentially Weighted
|
132
|
+
* Equilibrium
|
133
|
+
* Shrinkage
|
134
|
+
|
135
|
+
* Covariance Estimator:
|
136
|
+
* Empirical
|
137
|
+
* Gerber
|
138
|
+
* Denoising
|
139
|
+
* Denoting
|
140
|
+
* Exponentially Weighted
|
141
|
+
* Ledoit-Wolf
|
142
|
+
* Oracle Approximating Shrinkage
|
143
|
+
* Shrunk Covariance
|
144
|
+
* Graphical Lasso CV
|
145
|
+
|
146
|
+
* Distance Estimator:
|
138
147
|
* Pearson Distance
|
139
148
|
* Kendall Distance
|
140
149
|
* Spearman Distance
|
@@ -142,12 +151,12 @@ The current release contains:
|
|
142
151
|
* Distance Correlation
|
143
152
|
* Variation of Information
|
144
153
|
|
145
|
-
* Prior
|
154
|
+
* Prior Estimator:
|
146
155
|
* Empirical
|
147
156
|
* Black & Litterman
|
148
157
|
* Factor Model
|
149
158
|
|
150
|
-
* Uncertainty Set
|
159
|
+
* Uncertainty Set Estimator:
|
151
160
|
* On Expected Returns:
|
152
161
|
* Empirical
|
153
162
|
* Circular Bootstrap
|
@@ -155,18 +164,18 @@ The current release contains:
|
|
155
164
|
* Empirical
|
156
165
|
* Circular bootstrap
|
157
166
|
|
158
|
-
* Pre-Selection
|
167
|
+
* Pre-Selection Transformer:
|
159
168
|
* Non-Dominated Selection
|
160
169
|
* Select K Extremes (Best or Worst)
|
161
170
|
* Drop Highly Correlated Assets
|
162
171
|
|
163
172
|
* Cross-Validation and Model Selection:
|
164
|
-
* Compatible with all `sklearn` methods (KFold,
|
173
|
+
* Compatible with all `sklearn` methods (KFold, etc.)
|
165
174
|
* Walk Forward
|
166
|
-
* Combinatorial Purged Cross-
|
175
|
+
* Combinatorial Purged Cross-Validation
|
167
176
|
|
168
177
|
* Hyper-Parameter Tuning:
|
169
|
-
* Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV
|
178
|
+
* Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV)
|
170
179
|
|
171
180
|
* Risk Measures:
|
172
181
|
* Variance
|
@@ -190,9 +199,24 @@ The current release contains:
|
|
190
199
|
* Skew
|
191
200
|
* Kurtosis
|
192
201
|
|
202
|
+
* Optimization Features:
|
203
|
+
* Minimize Risk
|
204
|
+
* Maximize Returns
|
205
|
+
* Maximize Utility
|
206
|
+
* Maximize Ratio
|
207
|
+
* Transaction Costs
|
208
|
+
* Management Fees
|
209
|
+
* L1 and L2 Regularization
|
210
|
+
* Weight Constraints
|
211
|
+
* Group Constraints
|
212
|
+
* Budget Constraints
|
213
|
+
* Tracking Error Constraints
|
214
|
+
* Turnover Constraints
|
215
|
+
|
193
216
|
Quickstart
|
194
217
|
~~~~~~~~~~
|
195
|
-
The code snippets below are designed to introduce
|
218
|
+
The code snippets below are designed to introduce the functionality of `skfolio` so you
|
219
|
+
can start using it quickly. It follows the same API as scikit-learn.
|
196
220
|
|
197
221
|
Imports
|
198
222
|
-------
|
@@ -504,9 +528,9 @@ Combinatorial Purged Cross-Validation
|
|
504
528
|
Recognition
|
505
529
|
~~~~~~~~~~~
|
506
530
|
|
507
|
-
We would like to
|
508
|
-
scikit-learn and cvxpy but also the contributors of the following packages that
|
509
|
-
|
531
|
+
We would like to thank all contributors behind our direct dependencies, such as
|
532
|
+
scikit-learn and cvxpy, but also the contributors of the following packages that were a
|
533
|
+
source of inspiration:
|
510
534
|
|
511
535
|
* PyPortfolioOpt
|
512
536
|
* Riskfolio-Lib
|
@@ -519,11 +543,11 @@ were a source of inspiration:
|
|
519
543
|
Citation
|
520
544
|
~~~~~~~~
|
521
545
|
|
522
|
-
If you use skfolio in a scientific publication, we would appreciate citations:
|
546
|
+
If you use `skfolio` in a scientific publication, we would appreciate citations:
|
523
547
|
|
524
548
|
Bibtex entry::
|
525
549
|
|
526
|
-
@misc{
|
550
|
+
@misc{skfolio,
|
527
551
|
author = {Hugo Delatte},
|
528
552
|
title = {skfolio},
|
529
553
|
year = {2023},
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "skfolio"
|
7
|
-
version = "0.0.
|
7
|
+
version = "0.0.9"
|
8
8
|
maintainers = [
|
9
9
|
{ name = "Hugo Delatte", email = "delatte.hugo@gmail.com" },
|
10
10
|
]
|
@@ -75,7 +75,6 @@ docs = [
|
|
75
75
|
"sphinx-copybutton",
|
76
76
|
"numpydoc",
|
77
77
|
"sphinx-togglebutton",
|
78
|
-
"jupyterlite-sphinx",
|
79
78
|
"sphinx-favicon",
|
80
79
|
"sphinx-prompt",
|
81
80
|
"sphinxext.opengraph",
|
@@ -44,7 +44,7 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
44
44
|
Provides train/test indices to split time series data samples based on
|
45
45
|
Combinatorial Purged Cross-Validation [1]_.
|
46
46
|
|
47
|
-
Compared to `KFold
|
47
|
+
Compared to `KFold`, which splits the data into `k` folds with `1` fold for the test
|
48
48
|
set and `k - 1` folds for the training set, `CombinatorialPurgedCV` uses `k - p`
|
49
49
|
folds for the training set with `p > 1` being the number of test folds.
|
50
50
|
|
@@ -57,7 +57,7 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
57
57
|
overlapped in time with those labels included in the testing set.
|
58
58
|
|
59
59
|
Embargoing consist of removing from the training set all observations that
|
60
|
-
immediately follow an observation in the testing set since financial features
|
60
|
+
immediately follow an observation in the testing set, since financial features
|
61
61
|
often incorporate series that exhibit serial correlation (like ARMA processes).
|
62
62
|
|
63
63
|
Parameters
|
@@ -16,7 +16,7 @@ from skfolio.portfolio import Portfolio
|
|
16
16
|
|
17
17
|
|
18
18
|
class BaseOptimization(skb.BaseEstimator, ABC):
|
19
|
-
"""Base class for all
|
19
|
+
"""Base class for all portfolio optimizations in skfolio.
|
20
20
|
|
21
21
|
portfolio_params : dict, optional
|
22
22
|
Portfolio parameters passed to the portfolio evaluated by the `predict` and
|
@@ -40,12 +40,12 @@ class NestedClustersOptimization(BaseOptimization):
|
|
40
40
|
.. note ::
|
41
41
|
|
42
42
|
The original paper uses KMeans as the clustering algorithm, minimum Variance for
|
43
|
-
the inner-estimator and equal-
|
44
|
-
it to all `sklearn` and `skfolio` clustering
|
45
|
-
KMeans,
|
46
|
-
and risk measures (Variance, CVaR
|
43
|
+
the inner-estimator and equal-weighted for the outer-estimator. Here we
|
44
|
+
generalize it to all `sklearn` and `skfolio` clustering algorithms
|
45
|
+
(HierarchicalClustering, KMeans, etc.), all portfolio optimizations
|
46
|
+
(Mean-Variance, HRP, etc.) and risk measures (Variance, CVaR, etc.).
|
47
47
|
To avoid data leakage at the outer-estimator, we use out-of-sample estimates to
|
48
|
-
fit the outer
|
48
|
+
fit the outer estimator.
|
49
49
|
|
50
50
|
Parameters
|
51
51
|
----------
|
@@ -93,7 +93,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
93
93
|
allowed. If a float is provided, it is applied to each asset. `None` is
|
94
94
|
equivalent to `+np.Inf` (no upper bound). If a dictionary is provided, its
|
95
95
|
(key/value) pair must be the (asset name/asset maximum weight) and the input `X`
|
96
|
-
of the `fit`
|
96
|
+
of the `fit` method must be a DataFrame with the assets names in columns. When
|
97
97
|
using a dictionary, assets values that are not provided are assigned a minimum
|
98
98
|
weight of `1.0`. The default is 1.0 (each asset is below 100%).
|
99
99
|
|
@@ -112,7 +112,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
112
112
|
|
113
113
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
114
114
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
115
|
-
The float :math:`total\_cost` is
|
115
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the optimization:
|
116
116
|
|
117
117
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
118
118
|
|
@@ -121,7 +121,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
121
121
|
|
122
122
|
If a float is provided, it is applied to each asset.
|
123
123
|
If a dictionary is provided, its (key/value) pair must be the
|
124
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
124
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
125
125
|
DataFrame with the assets names in columns.
|
126
126
|
The default value is `0.0`.
|
127
127
|
|
@@ -130,7 +130,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
130
130
|
Based on the above formula, the periodicity of the transaction costs
|
131
131
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
132
132
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
133
|
-
to be expressed
|
133
|
+
to be expressed as **daily** costs.
|
134
134
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
135
135
|
|
136
136
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -140,7 +140,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
140
140
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
141
141
|
|
142
142
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
143
|
-
The float :math:`total\_fee` is
|
143
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the optimization:
|
144
144
|
|
145
145
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
146
146
|
|
@@ -149,7 +149,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
149
149
|
|
150
150
|
If a float is provided, it is applied to each asset.
|
151
151
|
If a dictionary is provided, its (key/value) pair must be the
|
152
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
152
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
153
153
|
DataFrame with the assets names in columns.
|
154
154
|
The default value is `0.0`.
|
155
155
|
|
@@ -172,7 +172,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
172
172
|
Previous weights of the assets. Previous weights are used to compute the
|
173
173
|
portfolio total cost. If a float is provided, it is applied to each asset.
|
174
174
|
If a dictionary is provided, its (key/value) pair must be the
|
175
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
175
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
176
176
|
be a DataFrame with the assets names in columns.
|
177
177
|
The default (`None`) means no previous weights.
|
178
178
|
|