skfolio 0.0.1__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.
Files changed (85) hide show
  1. skfolio-0.0.1/LICENSE +29 -0
  2. skfolio-0.0.1/MANIFEST.in +1 -0
  3. skfolio-0.0.1/PKG-INFO +568 -0
  4. skfolio-0.0.1/README.rst +496 -0
  5. skfolio-0.0.1/pyproject.toml +109 -0
  6. skfolio-0.0.1/setup.cfg +4 -0
  7. skfolio-0.0.1/src/skfolio/__init__.py +29 -0
  8. skfolio-0.0.1/src/skfolio/cluster/__init__.py +8 -0
  9. skfolio-0.0.1/src/skfolio/cluster/_hierarchical.py +387 -0
  10. skfolio-0.0.1/src/skfolio/datasets/__init__.py +20 -0
  11. skfolio-0.0.1/src/skfolio/datasets/_base.py +389 -0
  12. skfolio-0.0.1/src/skfolio/datasets/data/__init__.py +0 -0
  13. skfolio-0.0.1/src/skfolio/datasets/data/factors_dataset.csv.gz +0 -0
  14. skfolio-0.0.1/src/skfolio/datasets/data/sp500_dataset.csv.gz +0 -0
  15. skfolio-0.0.1/src/skfolio/datasets/data/sp500_index.csv.gz +0 -0
  16. skfolio-0.0.1/src/skfolio/distance/__init__.py +26 -0
  17. skfolio-0.0.1/src/skfolio/distance/_base.py +55 -0
  18. skfolio-0.0.1/src/skfolio/distance/_distance.py +574 -0
  19. skfolio-0.0.1/src/skfolio/exceptions.py +30 -0
  20. skfolio-0.0.1/src/skfolio/measures/__init__.py +76 -0
  21. skfolio-0.0.1/src/skfolio/measures/_enums.py +355 -0
  22. skfolio-0.0.1/src/skfolio/measures/_measures.py +607 -0
  23. skfolio-0.0.1/src/skfolio/metrics/__init__.py +3 -0
  24. skfolio-0.0.1/src/skfolio/metrics/_scorer.py +121 -0
  25. skfolio-0.0.1/src/skfolio/model_selection/__init__.py +18 -0
  26. skfolio-0.0.1/src/skfolio/model_selection/_combinatorial.py +407 -0
  27. skfolio-0.0.1/src/skfolio/model_selection/_validation.py +194 -0
  28. skfolio-0.0.1/src/skfolio/model_selection/_walk_forward.py +221 -0
  29. skfolio-0.0.1/src/skfolio/moments/__init__.py +41 -0
  30. skfolio-0.0.1/src/skfolio/moments/covariance/__init__.py +29 -0
  31. skfolio-0.0.1/src/skfolio/moments/covariance/_base.py +101 -0
  32. skfolio-0.0.1/src/skfolio/moments/covariance/_covariance.py +1108 -0
  33. skfolio-0.0.1/src/skfolio/moments/expected_returns/__init__.py +21 -0
  34. skfolio-0.0.1/src/skfolio/moments/expected_returns/_base.py +31 -0
  35. skfolio-0.0.1/src/skfolio/moments/expected_returns/_expected_returns.py +415 -0
  36. skfolio-0.0.1/src/skfolio/optimization/__init__.py +36 -0
  37. skfolio-0.0.1/src/skfolio/optimization/_base.py +147 -0
  38. skfolio-0.0.1/src/skfolio/optimization/cluster/__init__.py +13 -0
  39. skfolio-0.0.1/src/skfolio/optimization/cluster/_nco.py +348 -0
  40. skfolio-0.0.1/src/skfolio/optimization/cluster/hierarchical/__init__.py +13 -0
  41. skfolio-0.0.1/src/skfolio/optimization/cluster/hierarchical/_base.py +440 -0
  42. skfolio-0.0.1/src/skfolio/optimization/cluster/hierarchical/_herc.py +406 -0
  43. skfolio-0.0.1/src/skfolio/optimization/cluster/hierarchical/_hrp.py +368 -0
  44. skfolio-0.0.1/src/skfolio/optimization/convex/__init__.py +16 -0
  45. skfolio-0.0.1/src/skfolio/optimization/convex/_base.py +1944 -0
  46. skfolio-0.0.1/src/skfolio/optimization/convex/_distributionally_robust.py +392 -0
  47. skfolio-0.0.1/src/skfolio/optimization/convex/_maximum_diversification.py +417 -0
  48. skfolio-0.0.1/src/skfolio/optimization/convex/_mean_risk.py +974 -0
  49. skfolio-0.0.1/src/skfolio/optimization/convex/_risk_budgeting.py +560 -0
  50. skfolio-0.0.1/src/skfolio/optimization/ensemble/__init__.py +6 -0
  51. skfolio-0.0.1/src/skfolio/optimization/ensemble/_base.py +87 -0
  52. skfolio-0.0.1/src/skfolio/optimization/ensemble/_stacking.py +326 -0
  53. skfolio-0.0.1/src/skfolio/optimization/naive/__init__.py +3 -0
  54. skfolio-0.0.1/src/skfolio/optimization/naive/_naive.py +173 -0
  55. skfolio-0.0.1/src/skfolio/population/__init__.py +3 -0
  56. skfolio-0.0.1/src/skfolio/population/_population.py +883 -0
  57. skfolio-0.0.1/src/skfolio/portfolio/__init__.py +13 -0
  58. skfolio-0.0.1/src/skfolio/portfolio/_base.py +1096 -0
  59. skfolio-0.0.1/src/skfolio/portfolio/_multi_period_portfolio.py +610 -0
  60. skfolio-0.0.1/src/skfolio/portfolio/_portfolio.py +842 -0
  61. skfolio-0.0.1/src/skfolio/pre_selection/__init__.py +7 -0
  62. skfolio-0.0.1/src/skfolio/pre_selection/_pre_selection.py +342 -0
  63. skfolio-0.0.1/src/skfolio/preprocessing/__init__.py +3 -0
  64. skfolio-0.0.1/src/skfolio/preprocessing/_returns.py +114 -0
  65. skfolio-0.0.1/src/skfolio/prior/__init__.py +18 -0
  66. skfolio-0.0.1/src/skfolio/prior/_base.py +63 -0
  67. skfolio-0.0.1/src/skfolio/prior/_black_litterman.py +238 -0
  68. skfolio-0.0.1/src/skfolio/prior/_empirical.py +163 -0
  69. skfolio-0.0.1/src/skfolio/prior/_factor_model.py +268 -0
  70. skfolio-0.0.1/src/skfolio/typing.py +50 -0
  71. skfolio-0.0.1/src/skfolio/uncertainty_set/__init__.py +23 -0
  72. skfolio-0.0.1/src/skfolio/uncertainty_set/_base.py +108 -0
  73. skfolio-0.0.1/src/skfolio/uncertainty_set/_bootstrap.py +281 -0
  74. skfolio-0.0.1/src/skfolio/uncertainty_set/_empirical.py +237 -0
  75. skfolio-0.0.1/src/skfolio/utils/__init__.py +0 -0
  76. skfolio-0.0.1/src/skfolio/utils/bootstrap.py +115 -0
  77. skfolio-0.0.1/src/skfolio/utils/equations.py +350 -0
  78. skfolio-0.0.1/src/skfolio/utils/sorting.py +117 -0
  79. skfolio-0.0.1/src/skfolio/utils/stats.py +466 -0
  80. skfolio-0.0.1/src/skfolio/utils/tools.py +567 -0
  81. skfolio-0.0.1/src/skfolio.egg-info/PKG-INFO +568 -0
  82. skfolio-0.0.1/src/skfolio.egg-info/SOURCES.txt +83 -0
  83. skfolio-0.0.1/src/skfolio.egg-info/dependency_links.txt +1 -0
  84. skfolio-0.0.1/src/skfolio.egg-info/requires.txt +14 -0
  85. skfolio-0.0.1/src/skfolio.egg-info/top_level.txt +1 -0
skfolio-0.0.1/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2007-2023 The skfolio developers.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ recursive-include src/skfolio/datasets *.csv.gz
skfolio-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,568 @@
1
+ Metadata-Version: 2.1
2
+ Name: skfolio
3
+ Version: 0.0.1
4
+ Summary: Portfolio optimization built on scikit-learn's API
5
+ Author-email: Hugo Delatte <delatte.hugo@gmail.com>
6
+ Maintainer-email: Hugo Delatte <delatte.hugo@gmail.com>
7
+ License: BSD 3-Clause License
8
+
9
+ Copyright (c) 2007-2023 The skfolio developers.
10
+ All rights reserved.
11
+
12
+ Redistribution and use in source and binary forms, with or without
13
+ modification, are permitted provided that the following conditions are met:
14
+
15
+ * Redistributions of source code must retain the above copyright notice, this
16
+ list of conditions and the following disclaimer.
17
+
18
+ * Redistributions in binary form must reproduce the above copyright notice,
19
+ this list of conditions and the following disclaimer in the documentation
20
+ and/or other materials provided with the distribution.
21
+
22
+ * Neither the name of the copyright holder nor the names of its
23
+ contributors may be used to endorse or promote products derived from
24
+ this software without specific prior written permission.
25
+
26
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ Project-URL: API Reference, https://www.skfolio.org/api_reference.html
37
+ Project-URL: Documentation, https://www.skfolio.org
38
+ Project-URL: Tutorials, https://www.skfolio.org
39
+ Project-URL: Repository, https://github.com/skfolio/skfolio
40
+ Keywords: portfolio,optimization,optimisation,finance,asset,allocation,quantitative,quant,investment,startegy,machine-learning,scikit-learn,data-mining,data-science
41
+ Classifier: Intended Audience :: Developers
42
+ Classifier: Intended Audience :: Science/Research
43
+ Classifier: Intended Audience :: Financial and Insurance Industry
44
+ Classifier: License :: OSI Approved :: BSD License
45
+ Classifier: Operating System :: Unix
46
+ Classifier: Operating System :: Microsoft :: Windows
47
+ Classifier: Operating System :: MacOS
48
+ Classifier: Programming Language :: Python
49
+ Classifier: Programming Language :: Python :: 3
50
+ Classifier: Programming Language :: Python :: 3.10
51
+ Classifier: Programming Language :: Python :: 3.11
52
+ Classifier: Programming Language :: Python :: 3.12
53
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
54
+ Classifier: Topic :: Office/Business :: Financial :: Investment
55
+ Classifier: Topic :: Software Development
56
+ Requires-Python: >=3.10
57
+ Description-Content-Type: text/x-rst
58
+ License-File: LICENSE
59
+ Requires-Dist: numpy>=1.26.2
60
+ Requires-Dist: scipy>=1.11.4
61
+ Requires-Dist: pandas>=2.1.4
62
+ Requires-Dist: cvxpy>=1.4.1
63
+ Requires-Dist: joblib>=1.3.2
64
+ Requires-Dist: scikit-learn>=1.3.2
65
+ Requires-Dist: plotly>=5.18.0
66
+ Provides-Extra: dev
67
+ Requires-Dist: pytest; extra == "dev"
68
+ Requires-Dist: pytest-cov; extra == "dev"
69
+ Requires-Dist: pydata-sphinx-theme; extra == "dev"
70
+ Requires-Dist: Sphinx>=7.2.6; extra == "dev"
71
+ Requires-Dist: sphinx-gallery; extra == "dev"
72
+
73
+ .. -*- mode: rst -*-
74
+
75
+ |Licence|_ |Codecov|_ |Black|_ |PythonVersion|_ |PyPi|_ |CI/CD|_
76
+
77
+ .. |Licence| image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
78
+ .. _Licence: https://github.com/skfolio/skfolio/blob/main/LICENSE
79
+
80
+ .. |Codecov| image:: https://codecov.io/gh/scikit-learn/scikit-learn/branch/main/graph/badge.svg?token=Pk8G9gg3y9
81
+ .. _Codecov: https://codecov.io/gh/scikit-learn/scikit-learn
82
+
83
+ .. |PythonVersion| image:: https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10-blue
84
+ .. _PythonVersion: https://pypi.org/project/scikit-learn/
85
+
86
+ .. |PyPi| image:: https://img.shields.io/pypi/v/scikit-learn
87
+ .. _PyPi: https://pypi.org/project/scikit-learn
88
+
89
+ .. |Black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
90
+ .. _Black: https://github.com/psf/black
91
+
92
+ .. |CI/CD| image:: https://img.shields.io/github/actions/workflow/status/sktime/sktime/wheels.yml?logo=github
93
+ .. _CI/CD: https://github.com/skfolio/skfolio/blob/main/LICENSE
94
+
95
+
96
+ .. |PythonMinVersion| replace:: 3.10
97
+ .. |NumpyMinVersion| replace:: 1.26
98
+ .. |ScipyMinVersion| replace:: 1.11
99
+ .. |PandasMinVersion| replace:: 2.1
100
+ .. |NumbaMinVersion| replace:: 0.58
101
+ .. |CvxpyMinVersion| replace:: 1.4
102
+ .. |SklearnMinVersion| replace:: 1.3
103
+ .. |JoblibMinVersion| replace:: 1.3
104
+ .. |PlotlyMinVersion| replace:: 5.18
105
+
106
+
107
+ ===============
108
+ |icon| skfolio
109
+ ===============
110
+ .. |icon| image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/logo.ico
111
+ :width: 100
112
+ :target: https://skfolio.org/
113
+
114
+
115
+ **skfolio** is a Python library for portfolio optimization built on top of scikit-learn.
116
+ It provides a unified interface and `sklearn` compatible tools to build, tune and
117
+ cross-validate portfolio models. It is distributed under the 3-Clause BSD license.
118
+
119
+ .. image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/expo.jpg
120
+
121
+ Important links
122
+ ~~~~~~~~~~~~~~~
123
+
124
+ - Documentation: https://skfolio.org
125
+ - Tutorials: https://skfolio.org
126
+ - Repository: https://github.com/skfolio/skfolio
127
+
128
+ Installation
129
+ ~~~~~~~~~~~~
130
+
131
+ The easiest way to install skfolio is using ``pip``::
132
+
133
+ pip install -U skfolio
134
+
135
+ or ``conda``::
136
+
137
+ conda install -c conda-forge skfolio
138
+
139
+
140
+ Dependencies
141
+ ~~~~~~~~~~~~
142
+
143
+ sklearn requires:
144
+
145
+ - python (>= |PythonMinVersion|)
146
+ - numpy (>= |NumpyMinVersion|)
147
+ - scipy (>= |ScipyMinVersion|)
148
+ - pandas (>= |PandasMinVersion|)
149
+ - cvxpy (>= |CvxpyMinVersion|)
150
+ - scikit-learn (>= |SklearnMinVersion|)
151
+ - joblib (>= |JoblibMinVersion|)
152
+ - plotly (>= |PlotlyMinVersion|)
153
+
154
+ Key Concepts
155
+ ~~~~~~~~~~~~
156
+ Since the development of modern portfolio theory by Markowitz (1952), mean-variance optimization (MVO)
157
+ has received considerable attention. Unfortunately it faces a number of shortcomings including high sensitivity to the
158
+ input parameters (expected returns and covariance), weight concentration, high turnover and poor out-of-sample
159
+ performance.
160
+ It is well known that naive allocation (1/N, inverse-vol, ...) tend to outperform MVO out-of-sample (DeMiguel, 2007).
161
+
162
+ Numerous approaches have been developed to alleviate these shortcomings (shrinkage, bayesian approaches,
163
+ additional constraints, regularization, uncertainty set, higher moments, coherent risk measures,
164
+ left-tail risk optimization, distributionally robust optimization, factor model, risk-parity, hierarchical clustering,
165
+ ensemble methods...)
166
+
167
+ With this large number of methods, added to the fact that they can be composed together there is the need for an
168
+ unified framework to perform model selection, validation and parameter tuning while reducing the risk of data leakage
169
+ and overfitting. This framework is build on scikit-learn's API.
170
+
171
+ Available models
172
+ ~~~~~~~~~~~~~~~~
173
+ The current release contains:
174
+
175
+ * Optimization estimators:
176
+ * Naive:
177
+ * Equal-Weighted
178
+ * Inverse-Volatility
179
+ * Random (dirichlet)
180
+ * Convex:
181
+ * Mean-Risk
182
+ * Risk Budgeting
183
+ * Maximum Diversification
184
+ * Distributionally Robust CVaR
185
+ * Clustering:
186
+ * Hierarchical Risk Parity
187
+ * Hierarchical Equal Risk Contribution
188
+ * Nested Clusters Optimization
189
+ * Ensemble methods:
190
+ * Stacking Optimization
191
+
192
+ * Moment estimators:
193
+ * Expected Returns:
194
+ * Empirical
195
+ * Exponentially Weighted
196
+ * Equilibrium
197
+ * Shrinkage (James-Stein, Bayes-Stein, ...)
198
+ * Covariance:
199
+ * Empirical
200
+ * Gerber
201
+ * Denoising
202
+ * Denoting
203
+ * Exponentially Weighted
204
+ * Ledoit-Wolf
205
+ * Oracle Approximating Shrinkage
206
+ * Shrunk Covariance
207
+ * Graphical lasso CV
208
+
209
+ * Distance estimator:
210
+ * Pearson Distance
211
+ * Kendall Distance
212
+ * Spearman Distance
213
+ * Covariance Distance (based on any of the above covariance estimators)
214
+ * Distance Correlation
215
+ * Variation of Information
216
+
217
+ * Prior estimators:
218
+ * Empirical
219
+ * Black & Litterman
220
+ * Factor Model
221
+
222
+ * Uncertainty Set estimators:
223
+ * On Expected Returns:
224
+ * Empirical
225
+ * Circular Bootstrap
226
+ * On Covariance:
227
+ * Empirical
228
+ * Circular bootstrap
229
+
230
+ * Pre-Selection transformers:
231
+ * Non-Dominated Selection
232
+ * Select K Extremes (Best or Worst)
233
+ * Drop Highly Correlated Assets
234
+
235
+ * Cross-Validation and Model Selection:
236
+ * Compatible with all `sklearn` methods (KFold, ...)
237
+ * Walk Forward
238
+ * Combinatorial Purged Cross-validation
239
+
240
+ * Hyper-Parameter Tuning:
241
+ * Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV, ...)
242
+
243
+ * Risk Measures:
244
+ * Variance
245
+ * Semi-Variance
246
+ * Mean Absolute Deviation
247
+ * First Lower Partial Moment
248
+ * CVaR (Conditional Value at Risk)
249
+ * EVaR (Entropic Value at Risk)
250
+ * Worst Realization
251
+ * CDaR (Conditional Drawdown at Risk)
252
+ * Maximum Drawdown
253
+ * Average Drawdown
254
+ * EDaR (Entropic Drawdown at Risk)
255
+ * Ulcer Index
256
+ * Gini Mean Difference
257
+ * Value at Risk
258
+ * Drawdown at Risk
259
+ * Entropic Risk Measure
260
+ * Fourth Central Moment
261
+ * Fourth Lower Partial Moment
262
+ * Skew
263
+ * Kurtosis
264
+
265
+ Quickstart
266
+ ~~~~~~~~~~
267
+ The code snippets below are designed to introduce ``skfolio``'s functionality so you can start using it quickly.
268
+
269
+ Preparing the data
270
+ ------------------
271
+ .. code-block:: python
272
+
273
+ from sklearn import set_config
274
+ from sklearn.model_selection import (
275
+ GridSearchCV,
276
+ KFold,
277
+ RandomizedSearchCV,
278
+ train_test_split,
279
+ )
280
+ from sklearn.pipeline import Pipeline
281
+ from scipy.stats import loguniform
282
+
283
+ from skfolio import RatioMeasure, RiskMeasure
284
+ from skfolio.datasets import load_factors_dataset, load_sp500_dataset
285
+ from skfolio.model_selection import (
286
+ CombinatorialPurgedCV,
287
+ WalkForward,
288
+ cross_val_predict,
289
+ )
290
+ from skfolio.moments import (
291
+ DenoiseCovariance,
292
+ DenoteCovariance,
293
+ EWMu,
294
+ GerberCovariance,
295
+ ShrunkMu,
296
+ )
297
+ from skfolio.optimization import (
298
+ MeanRisk,
299
+ NestedClustersOptimization,
300
+ ObjectiveFunction,
301
+ RiskBudgeting,
302
+ )
303
+ from skfolio.pre_selection import SelectKExtremes
304
+ from skfolio.preprocessing import prices_to_returns
305
+ from skfolio.prior import BlackLitterman, EmpiricalPrior, FactorModel
306
+ from skfolio.uncertainty_set import BootstrapMuUncertaintySet
307
+
308
+ prices = load_sp500_dataset()
309
+
310
+ X = prices_to_returns(prices)
311
+ X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)
312
+
313
+
314
+ Minimum Variance
315
+ ----------------
316
+ .. code-block:: python
317
+
318
+ model = MeanRisk()
319
+
320
+ Fit on training set
321
+ -------------------
322
+ .. code-block:: python
323
+
324
+ model.fit(X_train)
325
+ print(model.weights_)
326
+
327
+ Predict on test set
328
+ -------------------
329
+ .. code-block:: python
330
+
331
+ portfolio = model.predict(X_test)
332
+ print(portfolio.annualized_sharpe_ratio)
333
+ print(portfolio.summary())
334
+
335
+
336
+
337
+ Maximum Sortino Ratio
338
+ ---------------------
339
+ .. code-block:: python
340
+
341
+ model = MeanRisk(
342
+ objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
343
+ risk_measure=RiskMeasure.SEMI_VARIANCE,
344
+ )
345
+
346
+
347
+ Denoised Covariance & Shrunk Expected Returns
348
+ ---------------------------------------------
349
+ .. code-block:: python
350
+
351
+ model = MeanRisk(
352
+ objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
353
+ prior_estimator=EmpiricalPrior(
354
+ mu_estimator=ShrunkMu(), covariance_estimator=DenoiseCovariance()
355
+ ),
356
+ )
357
+
358
+ Uncertainty Set on Expected Returns
359
+ -----------------------------------
360
+ .. code-block:: python
361
+
362
+ model = MeanRisk(
363
+ objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
364
+ mu_uncertainty_set_estimator=BootstrapMuUncertaintySet(),
365
+ )
366
+
367
+
368
+ Weight Constraints & Transaction Costs
369
+ --------------------------------------
370
+ .. code-block:: python
371
+
372
+ model = MeanRisk(
373
+ min_weights={"AAPL": 0.10, "JPM": 0.05},
374
+ max_weights=0.8,
375
+ transaction_costs={"AAPL": 0.0001, "RRC": 0.0002},
376
+ groups=[
377
+ ["Equity"] * 3 + ["Fund"] * 5 + ["Bond"] * 12,
378
+ ["US"] * 2 + ["Europe"] * 8 + ["Japan"] * 10,
379
+ ],
380
+ linear_constraints=[
381
+ "Equity <= 0.5 * Bond",
382
+ "US >= 0.1",
383
+ "Europe >= 0.5 * Fund",
384
+ "Japan <= 1",
385
+ ],
386
+ )
387
+ model.fit(X_train)
388
+
389
+
390
+ Risk Parity on CVaR
391
+ -------------------
392
+ .. code-block:: python
393
+
394
+ model = RiskBudgeting(risk_measure=RiskMeasure.CVAR)
395
+
396
+ Risk Parity & Gerber Covariance
397
+ -------------------------------
398
+ .. code-block:: python
399
+
400
+ model = RiskBudgeting(
401
+ prior_estimator=EmpiricalPrior(covariance_estimator=GerberCovariance())
402
+ )
403
+
404
+ Nested Cluster Optimization with cross-validation and parallelization
405
+ ---------------------------------------------------------------------
406
+ .. code-block:: python
407
+
408
+ model = NestedClustersOptimization(
409
+ inner_estimator=MeanRisk(risk_measure=RiskMeasure.CVAR),
410
+ outer_estimator=RiskBudgeting(risk_measure=RiskMeasure.VARIANCE),
411
+ cv=KFold(),
412
+ n_jobs=-1,
413
+ )
414
+
415
+ Randomized Search of the L2 Norm
416
+ --------------------------------
417
+ .. code-block:: python
418
+
419
+ randomized_search = RandomizedSearchCV(
420
+ estimator=MeanRisk(),
421
+ cv=WalkForward(train_size=255, test_size=60),
422
+ param_distributions={
423
+ "l2_coef": loguniform(1e-3, 1e-1),
424
+ },
425
+ )
426
+ randomized_search.fit(X_train)
427
+ best_model = randomized_search.best_estimator_
428
+ print(best_model.weights_)
429
+
430
+
431
+ Grid Search on embedded parameters
432
+ ----------------------------------
433
+ .. code-block:: python
434
+
435
+ model = MeanRisk(
436
+ objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
437
+ risk_measure=RiskMeasure.VARIANCE,
438
+ prior_estimator=EmpiricalPrior(mu_estimator=EWMu(alpha=0.2)),
439
+ )
440
+
441
+ print(model.get_params(deep=True))
442
+
443
+ gs = GridSearchCV(
444
+ estimator=model,
445
+ cv=KFold(n_splits=5, shuffle=False),
446
+ n_jobs=-1,
447
+ param_grid={
448
+ "risk_measure": [
449
+ RiskMeasure.VARIANCE,
450
+ RiskMeasure.CVAR,
451
+ RiskMeasure.VARIANCE.CDAR,
452
+ ],
453
+ "prior_estimator__mu_estimator__alpha": [0.05, 0.1, 0.2, 0.5],
454
+ },
455
+ )
456
+ gs.fit(X)
457
+ best_model = gs.best_estimator_
458
+ print(best_model.weights_)
459
+
460
+
461
+ Black & Litterman Model
462
+ -----------------------
463
+ .. code-block:: python
464
+
465
+ views = ["AAPL - BBY == 0.03 ", "CVX - KO == 0.04", "MSFT == 0.06 "]
466
+ model = MeanRisk(
467
+ objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
468
+ prior_estimator=BlackLitterman(views=views),
469
+ )
470
+
471
+ Factor Model
472
+ ------------
473
+ .. code-block:: python
474
+
475
+ factor_prices = load_factors_dataset()
476
+
477
+ X, y = prices_to_returns(prices, factor_prices)
478
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, shuffle=False)
479
+
480
+ model = MeanRisk(prior_estimator=FactorModel())
481
+ model.fit(X_train, y_train)
482
+
483
+ print(model.weights_)
484
+ portfolio = model.predict(X_test)
485
+ print(portfolio.calmar_ratio)
486
+ print(portfolio.summary())
487
+
488
+
489
+ Factor Model & Covariance Detoning
490
+ ----------------------------------
491
+ .. code-block:: python
492
+
493
+ model = MeanRisk(
494
+ prior_estimator=FactorModel(
495
+ factor_prior_estimator=EmpiricalPrior(covariance_estimator=DenoteCovariance())
496
+ )
497
+ )
498
+
499
+ Black & Litterman Factor Model
500
+ ------------------------------
501
+ .. code-block:: python
502
+
503
+ factor_views = ["MTUM - QUAL == 0.03 ", "SIZE - TLT == 0.04", "VLUE == 0.06"]
504
+ model = MeanRisk(
505
+ objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
506
+ prior_estimator=FactorModel(
507
+ factor_prior_estimator=BlackLitterman(views=factor_views),
508
+ ),
509
+ )
510
+
511
+ Pre-Selection Pipeline
512
+ ----------------------
513
+ .. code-block:: python
514
+
515
+ set_config(transform_output="pandas")
516
+ model = Pipeline(
517
+ [
518
+ ("pre_selection", SelectKExtremes(k=10, highest=True)),
519
+ ("optimization", MeanRisk()),
520
+ ]
521
+ )
522
+ model.fit(X_train)
523
+ portfolio = model.predict(X_test)
524
+
525
+
526
+
527
+
528
+ K-fold Cross-Validation
529
+ -----------------------
530
+ .. code-block:: python
531
+
532
+ model = MeanRisk()
533
+ mmp = cross_val_predict(model, X_test, cv=KFold(n_splits=5))
534
+ # mmp is the predicted MultiPeriodPortfolio object composed of 5 Portfolios (1 per testing fold)
535
+ mmp.plot_cumulative_returns()
536
+ print(mmp.summary()
537
+
538
+
539
+ Combinatorial Purged Cross-Validation
540
+ -------------------------------------
541
+ .. code-block:: python
542
+
543
+ model = MeanRisk()
544
+ cv = CombinatorialPurgedCV(n_folds=10, n_test_folds=2)
545
+ print(cv.get_summary(X_train))
546
+ population = cross_val_predict(model, X_train, cv=cv)
547
+ population.plot_distribution(
548
+ measure_list=[RatioMeasure.SHARPE_RATIO, RatioMeasure.SORTINO_RATIO]
549
+ )
550
+ population.plot_cumulative_returns()
551
+ print(population.summary())
552
+
553
+
554
+
555
+ Citation
556
+ ~~~~~~~~
557
+
558
+ If you use scikit-learn in a scientific publication, we would appreciate citations:
559
+
560
+ Bibtex entry::
561
+
562
+ @misc{riskfolio,
563
+ author = {Hugo Delatte},
564
+ title = {skfolio},
565
+ year = {2023},
566
+ url = {https://github.com/skfolio/skfolio}
567
+
568
+