skfolio 0.0.1__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/__init__.py +29 -0
- skfolio/cluster/__init__.py +8 -0
- skfolio/cluster/_hierarchical.py +387 -0
- skfolio/datasets/__init__.py +20 -0
- skfolio/datasets/_base.py +389 -0
- skfolio/datasets/data/__init__.py +0 -0
- skfolio/datasets/data/factors_dataset.csv.gz +0 -0
- skfolio/datasets/data/sp500_dataset.csv.gz +0 -0
- skfolio/datasets/data/sp500_index.csv.gz +0 -0
- skfolio/distance/__init__.py +26 -0
- skfolio/distance/_base.py +55 -0
- skfolio/distance/_distance.py +574 -0
- skfolio/exceptions.py +30 -0
- skfolio/measures/__init__.py +76 -0
- skfolio/measures/_enums.py +355 -0
- skfolio/measures/_measures.py +607 -0
- skfolio/metrics/__init__.py +3 -0
- skfolio/metrics/_scorer.py +121 -0
- skfolio/model_selection/__init__.py +18 -0
- skfolio/model_selection/_combinatorial.py +407 -0
- skfolio/model_selection/_validation.py +194 -0
- skfolio/model_selection/_walk_forward.py +221 -0
- skfolio/moments/__init__.py +41 -0
- skfolio/moments/covariance/__init__.py +29 -0
- skfolio/moments/covariance/_base.py +101 -0
- skfolio/moments/covariance/_covariance.py +1108 -0
- skfolio/moments/expected_returns/__init__.py +21 -0
- skfolio/moments/expected_returns/_base.py +31 -0
- skfolio/moments/expected_returns/_expected_returns.py +415 -0
- skfolio/optimization/__init__.py +36 -0
- skfolio/optimization/_base.py +147 -0
- skfolio/optimization/cluster/__init__.py +13 -0
- skfolio/optimization/cluster/_nco.py +348 -0
- skfolio/optimization/cluster/hierarchical/__init__.py +13 -0
- skfolio/optimization/cluster/hierarchical/_base.py +440 -0
- skfolio/optimization/cluster/hierarchical/_herc.py +406 -0
- skfolio/optimization/cluster/hierarchical/_hrp.py +368 -0
- skfolio/optimization/convex/__init__.py +16 -0
- skfolio/optimization/convex/_base.py +1944 -0
- skfolio/optimization/convex/_distributionally_robust.py +392 -0
- skfolio/optimization/convex/_maximum_diversification.py +417 -0
- skfolio/optimization/convex/_mean_risk.py +974 -0
- skfolio/optimization/convex/_risk_budgeting.py +560 -0
- skfolio/optimization/ensemble/__init__.py +6 -0
- skfolio/optimization/ensemble/_base.py +87 -0
- skfolio/optimization/ensemble/_stacking.py +326 -0
- skfolio/optimization/naive/__init__.py +3 -0
- skfolio/optimization/naive/_naive.py +173 -0
- skfolio/population/__init__.py +3 -0
- skfolio/population/_population.py +883 -0
- skfolio/portfolio/__init__.py +13 -0
- skfolio/portfolio/_base.py +1096 -0
- skfolio/portfolio/_multi_period_portfolio.py +610 -0
- skfolio/portfolio/_portfolio.py +842 -0
- skfolio/pre_selection/__init__.py +7 -0
- skfolio/pre_selection/_pre_selection.py +342 -0
- skfolio/preprocessing/__init__.py +3 -0
- skfolio/preprocessing/_returns.py +114 -0
- skfolio/prior/__init__.py +18 -0
- skfolio/prior/_base.py +63 -0
- skfolio/prior/_black_litterman.py +238 -0
- skfolio/prior/_empirical.py +163 -0
- skfolio/prior/_factor_model.py +268 -0
- skfolio/typing.py +50 -0
- skfolio/uncertainty_set/__init__.py +23 -0
- skfolio/uncertainty_set/_base.py +108 -0
- skfolio/uncertainty_set/_bootstrap.py +281 -0
- skfolio/uncertainty_set/_empirical.py +237 -0
- skfolio/utils/__init__.py +0 -0
- skfolio/utils/bootstrap.py +115 -0
- skfolio/utils/equations.py +350 -0
- skfolio/utils/sorting.py +117 -0
- skfolio/utils/stats.py +466 -0
- skfolio/utils/tools.py +567 -0
- skfolio-0.0.1.dist-info/LICENSE +29 -0
- skfolio-0.0.1.dist-info/METADATA +568 -0
- skfolio-0.0.1.dist-info/RECORD +79 -0
- skfolio-0.0.1.dist-info/WHEEL +5 -0
- skfolio-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,355 @@
|
|
1
|
+
"""Module that includes all Measures enums used across `skfolio`."""
|
2
|
+
|
3
|
+
# Author: Hugo Delatte <delatte.hugo@gmail.com>
|
4
|
+
# License: BSD 3 clause
|
5
|
+
|
6
|
+
from abc import abstractmethod
|
7
|
+
from enum import auto
|
8
|
+
|
9
|
+
from skfolio.utils.tools import AutoEnum
|
10
|
+
|
11
|
+
|
12
|
+
class BaseMeasure(AutoEnum):
|
13
|
+
"""Base Enum of measures"""
|
14
|
+
|
15
|
+
def __repr__(self) -> str:
|
16
|
+
"""Enum representation for improved reading"""
|
17
|
+
words = [
|
18
|
+
(
|
19
|
+
word.capitalize()
|
20
|
+
if len(word) > 3
|
21
|
+
else word.upper() if len(word) != 2 else word.lower()
|
22
|
+
)
|
23
|
+
for word in self.value.split("_")
|
24
|
+
]
|
25
|
+
if len(words[0]) in [3, 4] and words[0][-2:].lower() == "ar":
|
26
|
+
s = list(words[0].upper())
|
27
|
+
s[-2] = str(s[-2].lower())
|
28
|
+
words[0] = "".join(s)
|
29
|
+
string = " ".join(words).replace("Semi ", "Semi-")
|
30
|
+
return string
|
31
|
+
|
32
|
+
def __str__(self) -> str:
|
33
|
+
return self.__repr__()
|
34
|
+
|
35
|
+
@property
|
36
|
+
@abstractmethod
|
37
|
+
def is_perf(self):
|
38
|
+
pass
|
39
|
+
|
40
|
+
@property
|
41
|
+
@abstractmethod
|
42
|
+
def is_risk(self):
|
43
|
+
pass
|
44
|
+
|
45
|
+
@property
|
46
|
+
@abstractmethod
|
47
|
+
def is_ratio(self):
|
48
|
+
pass
|
49
|
+
|
50
|
+
@property
|
51
|
+
def is_annualized(self) -> bool:
|
52
|
+
return self.name[:10] == "ANNUALIZED"
|
53
|
+
|
54
|
+
@property
|
55
|
+
def annualized_measure(self):
|
56
|
+
if self.is_annualized:
|
57
|
+
raise ValueError(f"{self.name} is already an annualized measure")
|
58
|
+
try:
|
59
|
+
return getattr(self.__class__, f"ANNUALIZED_{self.name}")
|
60
|
+
except AttributeError:
|
61
|
+
raise AttributeError(
|
62
|
+
f"{self.name} doesn't have a annualized version"
|
63
|
+
) from None
|
64
|
+
|
65
|
+
@property
|
66
|
+
def non_annualized_measure(self):
|
67
|
+
if not self.is_annualized:
|
68
|
+
raise ValueError(f"{self.name} is already a non-annualized measure")
|
69
|
+
return getattr(self.__class__, self.name[11:])
|
70
|
+
|
71
|
+
|
72
|
+
class PerfMeasure(BaseMeasure):
|
73
|
+
"""Enumeration of performance measures
|
74
|
+
|
75
|
+
Attributes
|
76
|
+
----------
|
77
|
+
MEAN : str
|
78
|
+
Mean
|
79
|
+
|
80
|
+
ANNUALIZED_MEAN : str
|
81
|
+
Annualized Mean
|
82
|
+
"""
|
83
|
+
|
84
|
+
MEAN = auto()
|
85
|
+
|
86
|
+
# Annualized measures
|
87
|
+
ANNUALIZED_MEAN = auto()
|
88
|
+
|
89
|
+
@property
|
90
|
+
def is_perf(self) -> bool:
|
91
|
+
return True
|
92
|
+
|
93
|
+
@property
|
94
|
+
def is_risk(self) -> bool:
|
95
|
+
return False
|
96
|
+
|
97
|
+
@property
|
98
|
+
def is_ratio(self) -> bool:
|
99
|
+
return False
|
100
|
+
|
101
|
+
|
102
|
+
class RiskMeasure(BaseMeasure):
|
103
|
+
"""Enumeration of risk measures
|
104
|
+
|
105
|
+
Attributes
|
106
|
+
----------
|
107
|
+
VARIANCE : str
|
108
|
+
Variance.
|
109
|
+
|
110
|
+
ANNUALIZED_VARIANCE : str
|
111
|
+
Annualized Variance.
|
112
|
+
|
113
|
+
SEMI_VARIANCE : str
|
114
|
+
Semi-variance (Second Lower Partial Moment or Downside Variance).
|
115
|
+
|
116
|
+
ANNUALIZED_SEMI_VARIANCE : str
|
117
|
+
Annualized Semi-variance.
|
118
|
+
|
119
|
+
STANDARD_DEVIATION : str
|
120
|
+
Standard-deviation
|
121
|
+
|
122
|
+
ANNUALIZED_STANDARD_DEVIATION : str
|
123
|
+
Annualized Standard-deviation.
|
124
|
+
|
125
|
+
SEMI_DEVIATION : str
|
126
|
+
Semi-deviation.
|
127
|
+
|
128
|
+
ANNUALIZED_SEMI_DEVIATION : str
|
129
|
+
Annualized Semi-deviation.
|
130
|
+
|
131
|
+
MEAN_ABSOLUTE_DEVIATION : str
|
132
|
+
Mean Absolute Deviation.
|
133
|
+
|
134
|
+
CVAR : str
|
135
|
+
Conditional Value at Risk or Expected Shortfall.
|
136
|
+
|
137
|
+
EVAR : str
|
138
|
+
Entropic Value at Risk.
|
139
|
+
|
140
|
+
WORST_REALIZATION : str
|
141
|
+
Worst Realization (Worst Return).
|
142
|
+
|
143
|
+
CDAR : str
|
144
|
+
Conditional Drawdown at Risk.
|
145
|
+
|
146
|
+
MAX_DRAWDOWN : str
|
147
|
+
Maximum Drawdown.
|
148
|
+
|
149
|
+
AVERAGE_DRAWDOWN : str
|
150
|
+
Average Drawdown.
|
151
|
+
|
152
|
+
EDAR : str
|
153
|
+
Entropic Drawdown at Risk.
|
154
|
+
|
155
|
+
FIRST_LOWER_PARTIAL_MOMENT : str
|
156
|
+
First Lower Partial Moment.
|
157
|
+
|
158
|
+
ULCER_INDEX : str
|
159
|
+
Ulcer Index.
|
160
|
+
|
161
|
+
GINI_MEAN_DIFFERENCE : str
|
162
|
+
Gini Mean Difference.
|
163
|
+
"""
|
164
|
+
|
165
|
+
VARIANCE = auto()
|
166
|
+
ANNUALIZED_VARIANCE = auto()
|
167
|
+
SEMI_VARIANCE = auto()
|
168
|
+
ANNUALIZED_SEMI_VARIANCE = auto()
|
169
|
+
STANDARD_DEVIATION = auto()
|
170
|
+
ANNUALIZED_STANDARD_DEVIATION = auto()
|
171
|
+
SEMI_DEVIATION = auto()
|
172
|
+
ANNUALIZED_SEMI_DEVIATION = auto()
|
173
|
+
MEAN_ABSOLUTE_DEVIATION = auto()
|
174
|
+
CVAR = auto()
|
175
|
+
EVAR = auto()
|
176
|
+
WORST_REALIZATION = auto()
|
177
|
+
CDAR = auto()
|
178
|
+
MAX_DRAWDOWN = auto()
|
179
|
+
AVERAGE_DRAWDOWN = auto()
|
180
|
+
EDAR = auto()
|
181
|
+
FIRST_LOWER_PARTIAL_MOMENT = auto()
|
182
|
+
ULCER_INDEX = auto()
|
183
|
+
GINI_MEAN_DIFFERENCE = auto()
|
184
|
+
|
185
|
+
@property
|
186
|
+
def is_perf(self) -> bool:
|
187
|
+
return False
|
188
|
+
|
189
|
+
@property
|
190
|
+
def is_risk(self) -> bool:
|
191
|
+
return True
|
192
|
+
|
193
|
+
@property
|
194
|
+
def is_ratio(self) -> bool:
|
195
|
+
return False
|
196
|
+
|
197
|
+
|
198
|
+
class ExtraRiskMeasure(BaseMeasure):
|
199
|
+
"""Enumeration of other risk measures not used in convex optimization
|
200
|
+
|
201
|
+
Attributes
|
202
|
+
----------
|
203
|
+
VALUE_AT_RISK : str
|
204
|
+
Value at Risk (VaR).
|
205
|
+
|
206
|
+
DRAWDOWN_AT_RISK : str
|
207
|
+
Drawdown at Risk.
|
208
|
+
|
209
|
+
ENTROPIC_RISK_MEASURE : str
|
210
|
+
Entropic Risk Measure.
|
211
|
+
|
212
|
+
FOURTH_CENTRAL_MOMENT : str
|
213
|
+
Fourth Central Moment.
|
214
|
+
|
215
|
+
FOURTH_LOWER_PARTIAL_MOMENT : str
|
216
|
+
Fourth Lower Central Moment.
|
217
|
+
|
218
|
+
SKEW : str
|
219
|
+
Skew.
|
220
|
+
|
221
|
+
KURTOSIS : str
|
222
|
+
Kurtosis.
|
223
|
+
"""
|
224
|
+
|
225
|
+
VALUE_AT_RISK = auto()
|
226
|
+
DRAWDOWN_AT_RISK = auto()
|
227
|
+
ENTROPIC_RISK_MEASURE = auto()
|
228
|
+
FOURTH_CENTRAL_MOMENT = auto()
|
229
|
+
FOURTH_LOWER_PARTIAL_MOMENT = auto()
|
230
|
+
SKEW = auto()
|
231
|
+
KURTOSIS = auto()
|
232
|
+
|
233
|
+
@property
|
234
|
+
def is_perf(self) -> bool:
|
235
|
+
return False
|
236
|
+
|
237
|
+
@property
|
238
|
+
def is_risk(self) -> bool:
|
239
|
+
return True
|
240
|
+
|
241
|
+
@property
|
242
|
+
def is_ratio(self) -> bool:
|
243
|
+
return False
|
244
|
+
|
245
|
+
|
246
|
+
class RatioMeasure(BaseMeasure):
|
247
|
+
"""Enumeration of ratio measures
|
248
|
+
|
249
|
+
Attributes
|
250
|
+
----------
|
251
|
+
SHARPE_RATIO : str
|
252
|
+
Ratio of the excess Mean divided by the Standard-deviation.
|
253
|
+
|
254
|
+
ANNUALIZED_SHARPE_RATIO : str
|
255
|
+
Annualized Sharpe ratio.
|
256
|
+
|
257
|
+
SORTINO_RATIO : str
|
258
|
+
Ratio of the excess Mean divided by the Semi standard-deviation.
|
259
|
+
|
260
|
+
ANNUALIZED_SORTINO_RATIO : str
|
261
|
+
Annualized Sortino ratio.
|
262
|
+
|
263
|
+
MEAN_ABSOLUTE_DEVIATION_RATIO : str
|
264
|
+
Ratio of the excess Mean divided by the Mean Absolute Deviation.
|
265
|
+
|
266
|
+
FIRST_LOWER_PARTIAL_MOMENT_RATIO : str
|
267
|
+
Ratio of the excess Mean divided by the First Lower Partial Moment.
|
268
|
+
|
269
|
+
VALUE_AT_RISK_RATIO : str
|
270
|
+
Ratio of the excess Mean divided by the Value at Risk.
|
271
|
+
|
272
|
+
CVAR_RATIO : str
|
273
|
+
Ratio of the excess Mean divided by the Conditional Value at Risk.
|
274
|
+
|
275
|
+
ENTROPIC_RISK_MEASURE_RATIO : str
|
276
|
+
Ratio of the excess Mean divided by the Entropic Risk Measure.
|
277
|
+
|
278
|
+
EVAR_RATIO : str
|
279
|
+
Ratio of the excess Mean divided by the Entropic Value at Risk.
|
280
|
+
|
281
|
+
WORST_REALIZATION_RATIO : str
|
282
|
+
Ratio of the excess Mean divided by the Worst Realization.
|
283
|
+
|
284
|
+
DRAWDOWN_AT_RISK_RATIO : str
|
285
|
+
Ratio of the excess Mean divided by the Drawdown at Risk.
|
286
|
+
|
287
|
+
CDAR_RATIO : str
|
288
|
+
Ratio of the excess Mean divided by the Conditional Drawdown at Risk.
|
289
|
+
|
290
|
+
CALMAR_RATIO : str
|
291
|
+
Ratio of the excess Mean divided by the Maximum Drawdown.
|
292
|
+
|
293
|
+
AVERAGE_DRAWDOWN_RATIO : str
|
294
|
+
Ratio of the excess Mean divided by the Average Drawdown.
|
295
|
+
|
296
|
+
EDAR_RATIO : str
|
297
|
+
Ratio of the excess Mean divided by the Entropic Drawdown at Risk.
|
298
|
+
|
299
|
+
ULCER_INDEX_RATIO : str
|
300
|
+
Ratio of the excess Mean divided by the Ulcer Index.
|
301
|
+
|
302
|
+
GINI_MEAN_DIFFERENCE_RATIO : str
|
303
|
+
Ratio of the excess Mean divided by the Gini Mean Difference.
|
304
|
+
"""
|
305
|
+
|
306
|
+
SHARPE_RATIO = auto()
|
307
|
+
ANNUALIZED_SHARPE_RATIO = auto()
|
308
|
+
SORTINO_RATIO = auto()
|
309
|
+
ANNUALIZED_SORTINO_RATIO = auto()
|
310
|
+
MEAN_ABSOLUTE_DEVIATION_RATIO = auto()
|
311
|
+
FIRST_LOWER_PARTIAL_MOMENT_RATIO = auto()
|
312
|
+
VALUE_AT_RISK_RATIO = auto()
|
313
|
+
CVAR_RATIO = auto()
|
314
|
+
ENTROPIC_RISK_MEASURE_RATIO = auto()
|
315
|
+
EVAR_RATIO = auto()
|
316
|
+
WORST_REALIZATION_RATIO = auto()
|
317
|
+
DRAWDOWN_AT_RISK_RATIO = auto()
|
318
|
+
CDAR_RATIO = auto()
|
319
|
+
CALMAR_RATIO = auto()
|
320
|
+
AVERAGE_DRAWDOWN_RATIO = auto()
|
321
|
+
EDAR_RATIO = auto()
|
322
|
+
ULCER_INDEX_RATIO = auto()
|
323
|
+
GINI_MEAN_DIFFERENCE_RATIO = auto()
|
324
|
+
|
325
|
+
@property
|
326
|
+
def is_perf(self) -> bool:
|
327
|
+
return False
|
328
|
+
|
329
|
+
@property
|
330
|
+
def is_risk(self) -> bool:
|
331
|
+
return False
|
332
|
+
|
333
|
+
@property
|
334
|
+
def is_ratio(self) -> bool:
|
335
|
+
return True
|
336
|
+
|
337
|
+
@property
|
338
|
+
def linked_risk_measure(self) -> RiskMeasure | ExtraRiskMeasure:
|
339
|
+
match self:
|
340
|
+
case RatioMeasure.SHARPE_RATIO:
|
341
|
+
return RiskMeasure.STANDARD_DEVIATION
|
342
|
+
case RatioMeasure.ANNUALIZED_SHARPE_RATIO:
|
343
|
+
return RiskMeasure.ANNUALIZED_STANDARD_DEVIATION
|
344
|
+
case RatioMeasure.SORTINO_RATIO:
|
345
|
+
return RiskMeasure.SEMI_DEVIATION
|
346
|
+
case RatioMeasure.ANNUALIZED_SORTINO_RATIO:
|
347
|
+
return RiskMeasure.ANNUALIZED_SEMI_DEVIATION
|
348
|
+
case RatioMeasure.CALMAR_RATIO:
|
349
|
+
return RiskMeasure.MAX_DRAWDOWN
|
350
|
+
case _:
|
351
|
+
risk_measure = str(self.value).replace("_ratio", "")
|
352
|
+
try:
|
353
|
+
return RiskMeasure(risk_measure)
|
354
|
+
except ValueError:
|
355
|
+
return ExtraRiskMeasure(risk_measure)
|