openseries 1.6.0__py3-none-any.whl → 1.7.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.
- openseries/_common_model.py +233 -292
- openseries/_risk.py +9 -10
- openseries/datefixer.py +31 -36
- openseries/frame.py +113 -149
- openseries/load_plotly.py +8 -8
- openseries/portfoliotools.py +25 -26
- openseries/series.py +44 -64
- openseries/simulation.py +25 -34
- openseries/types.py +17 -24
- {openseries-1.6.0.dist-info → openseries-1.7.0.dist-info}/LICENSE.md +1 -1
- {openseries-1.6.0.dist-info → openseries-1.7.0.dist-info}/METADATA +4 -5
- openseries-1.7.0.dist-info/RECORD +16 -0
- openseries-1.6.0.dist-info/RECORD +0 -16
- {openseries-1.6.0.dist-info → openseries-1.7.0.dist-info}/WHEEL +0 -0
openseries/_common_model.py
CHANGED
@@ -9,10 +9,12 @@ from math import ceil
|
|
9
9
|
from pathlib import Path
|
10
10
|
from secrets import choice
|
11
11
|
from string import ascii_letters
|
12
|
-
from typing import
|
12
|
+
from typing import TYPE_CHECKING, Any, SupportsFloat, cast
|
13
13
|
|
14
14
|
from numpy import float64, inf, isnan, log, maximum, sqrt
|
15
|
-
|
15
|
+
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from numpy.typing import NDArray # pragma: no cover
|
16
18
|
from openpyxl.utils.dataframe import dataframe_to_rows
|
17
19
|
from openpyxl.workbook.workbook import Workbook
|
18
20
|
from openpyxl.worksheet.worksheet import Worksheet
|
@@ -29,13 +31,13 @@ from scipy.stats import ( # type: ignore[import-untyped,unused-ignore]
|
|
29
31
|
)
|
30
32
|
from typing_extensions import Self
|
31
33
|
|
32
|
-
from
|
34
|
+
from ._risk import (
|
33
35
|
_cvar_down_calc,
|
34
36
|
_var_down_calc,
|
35
37
|
)
|
36
|
-
from
|
37
|
-
from
|
38
|
-
from
|
38
|
+
from .datefixer import date_offset_foll, holiday_calendar
|
39
|
+
from .load_plotly import load_plotly_dict
|
40
|
+
from .types import (
|
39
41
|
CountriesType,
|
40
42
|
DaysInYearType,
|
41
43
|
LiteralBarPlotMode,
|
@@ -50,7 +52,6 @@ from openseries.types import (
|
|
50
52
|
|
51
53
|
|
52
54
|
class _CommonModel(BaseModel):
|
53
|
-
|
54
55
|
"""Declare _CommonModel."""
|
55
56
|
|
56
57
|
tsdf: DataFrame = DataFrame(dtype="float64")
|
@@ -63,8 +64,7 @@ class _CommonModel(BaseModel):
|
|
63
64
|
|
64
65
|
@property
|
65
66
|
def length(self: Self) -> int:
|
66
|
-
"""
|
67
|
-
Number of observations.
|
67
|
+
"""Number of observations.
|
68
68
|
|
69
69
|
Returns
|
70
70
|
-------
|
@@ -76,8 +76,7 @@ class _CommonModel(BaseModel):
|
|
76
76
|
|
77
77
|
@property
|
78
78
|
def first_idx(self: Self) -> dt.date:
|
79
|
-
"""
|
80
|
-
The first date in the timeseries.
|
79
|
+
"""The first date in the timeseries.
|
81
80
|
|
82
81
|
Returns
|
83
82
|
-------
|
@@ -89,8 +88,7 @@ class _CommonModel(BaseModel):
|
|
89
88
|
|
90
89
|
@property
|
91
90
|
def last_idx(self: Self) -> dt.date:
|
92
|
-
"""
|
93
|
-
The last date in the timeseries.
|
91
|
+
"""The last date in the timeseries.
|
94
92
|
|
95
93
|
Returns
|
96
94
|
-------
|
@@ -102,8 +100,7 @@ class _CommonModel(BaseModel):
|
|
102
100
|
|
103
101
|
@property
|
104
102
|
def span_of_days(self: Self) -> int:
|
105
|
-
"""
|
106
|
-
Number of days from the first date to the last.
|
103
|
+
"""Number of days from the first date to the last.
|
107
104
|
|
108
105
|
Returns
|
109
106
|
-------
|
@@ -115,8 +112,7 @@ class _CommonModel(BaseModel):
|
|
115
112
|
|
116
113
|
@property
|
117
114
|
def yearfrac(self: Self) -> float:
|
118
|
-
"""
|
119
|
-
Length of series expressed in years assuming all years have 365.25 days.
|
115
|
+
"""Length of series expressed in years assuming all years have 365.25 days.
|
120
116
|
|
121
117
|
Returns
|
122
118
|
-------
|
@@ -129,8 +125,7 @@ class _CommonModel(BaseModel):
|
|
129
125
|
|
130
126
|
@property
|
131
127
|
def periods_in_a_year(self: Self) -> float:
|
132
|
-
"""
|
133
|
-
The average number of observations per year.
|
128
|
+
"""The average number of observations per year.
|
134
129
|
|
135
130
|
Returns
|
136
131
|
-------
|
@@ -141,13 +136,12 @@ class _CommonModel(BaseModel):
|
|
141
136
|
return self.length / self.yearfrac
|
142
137
|
|
143
138
|
@property
|
144
|
-
def max_drawdown_cal_year(self: Self) ->
|
145
|
-
"""
|
146
|
-
https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
|
139
|
+
def max_drawdown_cal_year(self: Self) -> float | Series[float]:
|
140
|
+
"""https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
|
147
141
|
|
148
142
|
Returns
|
149
143
|
-------
|
150
|
-
|
144
|
+
float | Pandas.Series[float]
|
151
145
|
Maximum drawdown in a single calendar year.
|
152
146
|
|
153
147
|
"""
|
@@ -170,64 +164,59 @@ class _CommonModel(BaseModel):
|
|
170
164
|
)
|
171
165
|
|
172
166
|
@property
|
173
|
-
def geo_ret(self: Self) ->
|
174
|
-
"""
|
175
|
-
https://www.investopedia.com/terms/c/cagr.asp.
|
167
|
+
def geo_ret(self: Self) -> float | Series[float]:
|
168
|
+
"""https://www.investopedia.com/terms/c/cagr.asp.
|
176
169
|
|
177
170
|
Returns
|
178
171
|
-------
|
179
|
-
|
172
|
+
float | Pandas.Series[float]
|
180
173
|
Compounded Annual Growth Rate (CAGR)
|
181
174
|
|
182
175
|
"""
|
183
176
|
return self.geo_ret_func()
|
184
177
|
|
185
178
|
@property
|
186
|
-
def arithmetic_ret(self: Self) ->
|
187
|
-
"""
|
188
|
-
https://www.investopedia.com/terms/a/arithmeticmean.asp.
|
179
|
+
def arithmetic_ret(self: Self) -> float | Series[float]:
|
180
|
+
"""https://www.investopedia.com/terms/a/arithmeticmean.asp.
|
189
181
|
|
190
182
|
Returns
|
191
183
|
-------
|
192
|
-
|
184
|
+
float | Pandas.Series[float]
|
193
185
|
Annualized arithmetic mean of returns
|
194
186
|
|
195
187
|
"""
|
196
188
|
return self.arithmetic_ret_func()
|
197
189
|
|
198
190
|
@property
|
199
|
-
def value_ret(self: Self) ->
|
200
|
-
"""
|
201
|
-
Simple return.
|
191
|
+
def value_ret(self: Self) -> float | Series[float]:
|
192
|
+
"""Simple return.
|
202
193
|
|
203
194
|
Returns
|
204
195
|
-------
|
205
|
-
|
196
|
+
float | Pandas.Series[float]
|
206
197
|
Simple return
|
207
198
|
|
208
199
|
"""
|
209
200
|
return self.value_ret_func()
|
210
201
|
|
211
202
|
@property
|
212
|
-
def vol(self: Self) ->
|
213
|
-
"""
|
214
|
-
Annualized volatility.
|
203
|
+
def vol(self: Self) -> float | Series[float]:
|
204
|
+
"""Annualized volatility.
|
215
205
|
|
216
206
|
Based on Pandas .std() which is the equivalent of stdev.s([...]) in MS Excel.
|
217
207
|
https://www.investopedia.com/terms/v/volatility.asp.
|
218
208
|
|
219
209
|
Returns
|
220
210
|
-------
|
221
|
-
|
211
|
+
float | Pandas.Series[float]
|
222
212
|
Annualized volatility
|
223
213
|
|
224
214
|
"""
|
225
215
|
return self.vol_func()
|
226
216
|
|
227
217
|
@property
|
228
|
-
def downside_deviation(self: Self) ->
|
229
|
-
"""
|
230
|
-
Downside Deviation.
|
218
|
+
def downside_deviation(self: Self) -> float | Series[float]:
|
219
|
+
"""Downside Deviation.
|
231
220
|
|
232
221
|
Standard deviation of returns that are below a Minimum Accepted Return
|
233
222
|
of zero. It is used to calculate the Sortino Ratio.
|
@@ -235,7 +224,7 @@ class _CommonModel(BaseModel):
|
|
235
224
|
|
236
225
|
Returns
|
237
226
|
-------
|
238
|
-
|
227
|
+
float | Pandas.Series[float]
|
239
228
|
Downside deviation
|
240
229
|
|
241
230
|
"""
|
@@ -243,13 +232,12 @@ class _CommonModel(BaseModel):
|
|
243
232
|
return self.downside_deviation_func(min_accepted_return=min_accepted_return)
|
244
233
|
|
245
234
|
@property
|
246
|
-
def ret_vol_ratio(self: Self) ->
|
247
|
-
"""
|
248
|
-
Ratio of annualized arithmetic mean of returns and annualized volatility.
|
235
|
+
def ret_vol_ratio(self: Self) -> float | Series[float]:
|
236
|
+
"""Ratio of annualized arithmetic mean of returns and annualized volatility.
|
249
237
|
|
250
238
|
Returns
|
251
239
|
-------
|
252
|
-
|
240
|
+
float | Pandas.Series[float]
|
253
241
|
Ratio of the annualized arithmetic mean of returns and annualized
|
254
242
|
volatility.
|
255
243
|
|
@@ -258,13 +246,12 @@ class _CommonModel(BaseModel):
|
|
258
246
|
return self.ret_vol_ratio_func(riskfree_rate=riskfree_rate)
|
259
247
|
|
260
248
|
@property
|
261
|
-
def sortino_ratio(self: Self) ->
|
262
|
-
"""
|
263
|
-
https://www.investopedia.com/terms/s/sortinoratio.asp.
|
249
|
+
def sortino_ratio(self: Self) -> float | Series[float]:
|
250
|
+
"""https://www.investopedia.com/terms/s/sortinoratio.asp.
|
264
251
|
|
265
252
|
Returns
|
266
253
|
-------
|
267
|
-
|
254
|
+
float | Pandas.Series[float]
|
268
255
|
Sortino ratio calculated as the annualized arithmetic mean of returns
|
269
256
|
/ downside deviation. The ratio implies that the riskfree asset has zero
|
270
257
|
volatility, and a minimum acceptable return of zero.
|
@@ -278,13 +265,12 @@ class _CommonModel(BaseModel):
|
|
278
265
|
)
|
279
266
|
|
280
267
|
@property
|
281
|
-
def omega_ratio(self: Self) ->
|
282
|
-
"""
|
283
|
-
https://en.wikipedia.org/wiki/Omega_ratio.
|
268
|
+
def omega_ratio(self: Self) -> float | Series[float]:
|
269
|
+
"""https://en.wikipedia.org/wiki/Omega_ratio.
|
284
270
|
|
285
271
|
Returns
|
286
272
|
-------
|
287
|
-
|
273
|
+
float | Pandas.Series[float]
|
288
274
|
Omega ratio calculation
|
289
275
|
|
290
276
|
"""
|
@@ -292,41 +278,38 @@ class _CommonModel(BaseModel):
|
|
292
278
|
return self.omega_ratio_func(min_accepted_return=minimum_accepted_return)
|
293
279
|
|
294
280
|
@property
|
295
|
-
def z_score(self: Self) ->
|
296
|
-
"""
|
297
|
-
https://www.investopedia.com/terms/z/zscore.asp.
|
281
|
+
def z_score(self: Self) -> float | Series[float]:
|
282
|
+
"""https://www.investopedia.com/terms/z/zscore.asp.
|
298
283
|
|
299
284
|
Returns
|
300
285
|
-------
|
301
|
-
|
286
|
+
float | Pandas.Series[float]
|
302
287
|
Z-score as (last return - mean return) / standard deviation of returns.
|
303
288
|
|
304
289
|
"""
|
305
290
|
return self.z_score_func()
|
306
291
|
|
307
292
|
@property
|
308
|
-
def max_drawdown(self: Self) ->
|
309
|
-
"""
|
310
|
-
https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
|
293
|
+
def max_drawdown(self: Self) -> float | Series[float]:
|
294
|
+
"""https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
|
311
295
|
|
312
296
|
Returns
|
313
297
|
-------
|
314
|
-
|
298
|
+
float | Pandas.Series[float]
|
315
299
|
Maximum drawdown without any limit on date range
|
316
300
|
|
317
301
|
"""
|
318
302
|
return self.max_drawdown_func()
|
319
303
|
|
320
304
|
@property
|
321
|
-
def max_drawdown_date(self: Self) ->
|
322
|
-
"""
|
323
|
-
Date when the maximum drawdown occurred.
|
305
|
+
def max_drawdown_date(self: Self) -> dt.date | Series[dt.date]:
|
306
|
+
"""Date when the maximum drawdown occurred.
|
324
307
|
|
325
308
|
https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
|
326
309
|
|
327
310
|
Returns
|
328
311
|
-------
|
329
|
-
|
312
|
+
datetime.date | pandas.Series[dt.date]
|
330
313
|
Date when the maximum drawdown occurred
|
331
314
|
|
332
315
|
"""
|
@@ -344,13 +327,12 @@ class _CommonModel(BaseModel):
|
|
344
327
|
).dt.date
|
345
328
|
|
346
329
|
@property
|
347
|
-
def worst(self: Self) ->
|
348
|
-
"""
|
349
|
-
Most negative percentage change.
|
330
|
+
def worst(self: Self) -> float | Series[float]:
|
331
|
+
"""Most negative percentage change.
|
350
332
|
|
351
333
|
Returns
|
352
334
|
-------
|
353
|
-
|
335
|
+
float | Pandas.Series[float]
|
354
336
|
Most negative percentage change
|
355
337
|
|
356
338
|
"""
|
@@ -358,9 +340,8 @@ class _CommonModel(BaseModel):
|
|
358
340
|
return self.worst_func(observations=observations)
|
359
341
|
|
360
342
|
@property
|
361
|
-
def worst_month(self: Self) ->
|
362
|
-
"""
|
363
|
-
Most negative month.
|
343
|
+
def worst_month(self: Self) -> float | Series[float]:
|
344
|
+
"""Most negative month.
|
364
345
|
|
365
346
|
Returns
|
366
347
|
-------
|
@@ -384,52 +365,48 @@ class _CommonModel(BaseModel):
|
|
384
365
|
)
|
385
366
|
|
386
367
|
@property
|
387
|
-
def positive_share(self: Self) ->
|
388
|
-
"""
|
389
|
-
The share of percentage changes that are greater than zero.
|
368
|
+
def positive_share(self: Self) -> float | Series[float]:
|
369
|
+
"""The share of percentage changes that are greater than zero.
|
390
370
|
|
391
371
|
Returns
|
392
372
|
-------
|
393
|
-
|
373
|
+
float | Pandas.Series[float]
|
394
374
|
The share of percentage changes that are greater than zero
|
395
375
|
|
396
376
|
"""
|
397
377
|
return self.positive_share_func()
|
398
378
|
|
399
379
|
@property
|
400
|
-
def skew(self: Self) ->
|
401
|
-
"""
|
402
|
-
https://www.investopedia.com/terms/s/skewness.asp.
|
380
|
+
def skew(self: Self) -> float | Series[float]:
|
381
|
+
"""https://www.investopedia.com/terms/s/skewness.asp.
|
403
382
|
|
404
383
|
Returns
|
405
384
|
-------
|
406
|
-
|
385
|
+
float | Pandas.Series[float]
|
407
386
|
Skew of the return distribution
|
408
387
|
|
409
388
|
"""
|
410
389
|
return self.skew_func()
|
411
390
|
|
412
391
|
@property
|
413
|
-
def kurtosis(self: Self) ->
|
414
|
-
"""
|
415
|
-
https://www.investopedia.com/terms/k/kurtosis.asp.
|
392
|
+
def kurtosis(self: Self) -> float | Series[float]:
|
393
|
+
"""https://www.investopedia.com/terms/k/kurtosis.asp.
|
416
394
|
|
417
395
|
Returns
|
418
396
|
-------
|
419
|
-
|
397
|
+
float | Pandas.Series[float]
|
420
398
|
Kurtosis of the return distribution
|
421
399
|
|
422
400
|
"""
|
423
401
|
return self.kurtosis_func()
|
424
402
|
|
425
403
|
@property
|
426
|
-
def cvar_down(self: Self) ->
|
427
|
-
"""
|
428
|
-
https://www.investopedia.com/terms/c/conditional_value_at_risk.asp.
|
404
|
+
def cvar_down(self: Self) -> float | Series[float]:
|
405
|
+
"""https://www.investopedia.com/terms/c/conditional_value_at_risk.asp.
|
429
406
|
|
430
407
|
Returns
|
431
408
|
-------
|
432
|
-
|
409
|
+
float | Pandas.Series[float]
|
433
410
|
Downside 95% Conditional Value At Risk "CVaR"
|
434
411
|
|
435
412
|
"""
|
@@ -437,16 +414,15 @@ class _CommonModel(BaseModel):
|
|
437
414
|
return self.cvar_down_func(level=level)
|
438
415
|
|
439
416
|
@property
|
440
|
-
def var_down(self: Self) ->
|
441
|
-
"""
|
442
|
-
Downside 95% Value At Risk (VaR).
|
417
|
+
def var_down(self: Self) -> float | Series[float]:
|
418
|
+
"""Downside 95% Value At Risk (VaR).
|
443
419
|
|
444
420
|
The equivalent of percentile.inc([...], 1-level) over returns in MS Excel.
|
445
421
|
https://www.investopedia.com/terms/v/var.asp.
|
446
422
|
|
447
423
|
Returns
|
448
424
|
-------
|
449
|
-
|
425
|
+
float | Pandas.Series[float]
|
450
426
|
Downside 95% Value At Risk (VaR)
|
451
427
|
|
452
428
|
"""
|
@@ -455,15 +431,14 @@ class _CommonModel(BaseModel):
|
|
455
431
|
return self.var_down_func(level=level, interpolation=interpolation)
|
456
432
|
|
457
433
|
@property
|
458
|
-
def vol_from_var(self: Self) ->
|
459
|
-
"""
|
460
|
-
Implied annualized volatility from Downside 95% Value at Risk.
|
434
|
+
def vol_from_var(self: Self) -> float | Series[float]:
|
435
|
+
"""Implied annualized volatility from Downside 95% Value at Risk.
|
461
436
|
|
462
437
|
Assumes that returns are normally distributed.
|
463
438
|
|
464
439
|
Returns
|
465
440
|
-------
|
466
|
-
|
441
|
+
float | Pandas.Series[float]
|
467
442
|
Implied annualized volatility from the Downside 95% VaR using the
|
468
443
|
assumption that returns are normally distributed.
|
469
444
|
|
@@ -474,12 +449,11 @@ class _CommonModel(BaseModel):
|
|
474
449
|
|
475
450
|
def calc_range( # noqa: C901
|
476
451
|
self: Self,
|
477
|
-
months_offset:
|
478
|
-
from_dt:
|
479
|
-
to_dt:
|
452
|
+
months_offset: int | None = None,
|
453
|
+
from_dt: dt.date | None = None,
|
454
|
+
to_dt: dt.date | None = None,
|
480
455
|
) -> tuple[dt.date, dt.date]:
|
481
|
-
"""
|
482
|
-
Create user defined date range.
|
456
|
+
"""Create user defined date range.
|
483
457
|
|
484
458
|
Parameters
|
485
459
|
----------
|
@@ -540,8 +514,7 @@ class _CommonModel(BaseModel):
|
|
540
514
|
self: Self,
|
541
515
|
countries: CountriesType = "SE",
|
542
516
|
) -> Self:
|
543
|
-
"""
|
544
|
-
Align the index of .tsdf with local calendar business days.
|
517
|
+
"""Align the index of .tsdf with local calendar business days.
|
545
518
|
|
546
519
|
Parameters
|
547
520
|
----------
|
@@ -575,8 +548,7 @@ class _CommonModel(BaseModel):
|
|
575
548
|
return self
|
576
549
|
|
577
550
|
def value_to_log(self: Self) -> Self:
|
578
|
-
"""
|
579
|
-
Series of values converted into logarithmic weighted series.
|
551
|
+
"""Series of values converted into logarithmic weighted series.
|
580
552
|
|
581
553
|
Equivalent to LN(value[t] / value[t=0]) in Excel.
|
582
554
|
|
@@ -594,8 +566,7 @@ class _CommonModel(BaseModel):
|
|
594
566
|
return self
|
595
567
|
|
596
568
|
def value_nan_handle(self: Self, method: LiteralNanMethod = "fill") -> Self:
|
597
|
-
"""
|
598
|
-
Handle missing values in a valueseries.
|
569
|
+
"""Handle missing values in a valueseries.
|
599
570
|
|
600
571
|
Parameters
|
601
572
|
----------
|
@@ -615,8 +586,7 @@ class _CommonModel(BaseModel):
|
|
615
586
|
return self
|
616
587
|
|
617
588
|
def return_nan_handle(self: Self, method: LiteralNanMethod = "fill") -> Self:
|
618
|
-
"""
|
619
|
-
Handle missing values in a returnseries.
|
589
|
+
"""Handle missing values in a returnseries.
|
620
590
|
|
621
591
|
Parameters
|
622
592
|
----------
|
@@ -636,8 +606,7 @@ class _CommonModel(BaseModel):
|
|
636
606
|
return self
|
637
607
|
|
638
608
|
def to_drawdown_series(self: Self) -> Self:
|
639
|
-
"""
|
640
|
-
Convert timeseries into a drawdown series.
|
609
|
+
"""Convert timeseries into a drawdown series.
|
641
610
|
|
642
611
|
Returns
|
643
612
|
-------
|
@@ -655,10 +624,9 @@ class _CommonModel(BaseModel):
|
|
655
624
|
self: Self,
|
656
625
|
what_output: LiteralJsonOutput,
|
657
626
|
filename: str,
|
658
|
-
directory:
|
659
|
-
) -> list[dict[str,
|
660
|
-
"""
|
661
|
-
Dump timeseries data into a json file.
|
627
|
+
directory: DirectoryPath | None = None,
|
628
|
+
) -> list[dict[str, str | bool | ValueType | list[str] | list[float]]]:
|
629
|
+
"""Dump timeseries data into a json file.
|
662
630
|
|
663
631
|
Parameters
|
664
632
|
----------
|
@@ -672,7 +640,7 @@ class _CommonModel(BaseModel):
|
|
672
640
|
|
673
641
|
Returns
|
674
642
|
-------
|
675
|
-
list[
|
643
|
+
list[dict[str, str | bool | ValueType | list[str] | list[float]]]
|
676
644
|
A list of dictionaries with the data of the series
|
677
645
|
|
678
646
|
"""
|
@@ -719,13 +687,12 @@ class _CommonModel(BaseModel):
|
|
719
687
|
def to_xlsx(
|
720
688
|
self: Self,
|
721
689
|
filename: str,
|
722
|
-
sheet_title:
|
723
|
-
directory:
|
690
|
+
sheet_title: str | None = None,
|
691
|
+
directory: DirectoryPath | None = None,
|
724
692
|
*,
|
725
693
|
overwrite: bool = True,
|
726
694
|
) -> str:
|
727
|
-
"""
|
728
|
-
Save .tsdf DataFrame to an Excel spreadsheet file.
|
695
|
+
"""Save .tsdf DataFrame to an Excel spreadsheet file.
|
729
696
|
|
730
697
|
Parameters
|
731
698
|
----------
|
@@ -777,18 +744,17 @@ class _CommonModel(BaseModel):
|
|
777
744
|
def plot_bars(
|
778
745
|
self: Self,
|
779
746
|
mode: LiteralBarPlotMode = "group",
|
780
|
-
tick_fmt:
|
781
|
-
filename:
|
782
|
-
directory:
|
783
|
-
labels:
|
747
|
+
tick_fmt: str | None = None,
|
748
|
+
filename: str | None = None,
|
749
|
+
directory: DirectoryPath | None = None,
|
750
|
+
labels: list[str] | None = None,
|
784
751
|
output_type: LiteralPlotlyOutput = "file",
|
785
752
|
include_plotlyjs: LiteralPlotlyJSlib = "cdn",
|
786
753
|
*,
|
787
754
|
auto_open: bool = True,
|
788
755
|
add_logo: bool = True,
|
789
756
|
) -> tuple[Figure, str]:
|
790
|
-
"""
|
791
|
-
Create a Plotly Bar Figure.
|
757
|
+
"""Create a Plotly Bar Figure.
|
792
758
|
|
793
759
|
Parameters
|
794
760
|
----------
|
@@ -892,10 +858,10 @@ class _CommonModel(BaseModel):
|
|
892
858
|
def plot_series( # noqa: C901
|
893
859
|
self: Self,
|
894
860
|
mode: LiteralLinePlotMode = "lines",
|
895
|
-
tick_fmt:
|
896
|
-
filename:
|
897
|
-
directory:
|
898
|
-
labels:
|
861
|
+
tick_fmt: str | None = None,
|
862
|
+
filename: str | None = None,
|
863
|
+
directory: DirectoryPath | None = None,
|
864
|
+
labels: list[str] | None = None,
|
899
865
|
output_type: LiteralPlotlyOutput = "file",
|
900
866
|
include_plotlyjs: LiteralPlotlyJSlib = "cdn",
|
901
867
|
*,
|
@@ -903,8 +869,7 @@ class _CommonModel(BaseModel):
|
|
903
869
|
add_logo: bool = True,
|
904
870
|
show_last: bool = False,
|
905
871
|
) -> tuple[Figure, str]:
|
906
|
-
"""
|
907
|
-
Create a Plotly Scatter Figure.
|
872
|
+
"""Create a Plotly Scatter Figure.
|
908
873
|
|
909
874
|
Parameters
|
910
875
|
----------
|
@@ -1024,13 +989,12 @@ class _CommonModel(BaseModel):
|
|
1024
989
|
|
1025
990
|
def arithmetic_ret_func(
|
1026
991
|
self: Self,
|
1027
|
-
months_from_last:
|
1028
|
-
from_date:
|
1029
|
-
to_date:
|
1030
|
-
periods_in_a_year_fixed:
|
1031
|
-
) ->
|
1032
|
-
"""
|
1033
|
-
https://www.investopedia.com/terms/a/arithmeticmean.asp.
|
992
|
+
months_from_last: int | None = None,
|
993
|
+
from_date: dt.date | None = None,
|
994
|
+
to_date: dt.date | None = None,
|
995
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
996
|
+
) -> float | Series[float]:
|
997
|
+
"""https://www.investopedia.com/terms/a/arithmeticmean.asp.
|
1034
998
|
|
1035
999
|
Parameters
|
1036
1000
|
----------
|
@@ -1047,7 +1011,7 @@ class _CommonModel(BaseModel):
|
|
1047
1011
|
|
1048
1012
|
Returns
|
1049
1013
|
-------
|
1050
|
-
|
1014
|
+
float | Pandas.Series[float]
|
1051
1015
|
Annualized arithmetic mean of returns
|
1052
1016
|
|
1053
1017
|
"""
|
@@ -1084,13 +1048,12 @@ class _CommonModel(BaseModel):
|
|
1084
1048
|
|
1085
1049
|
def vol_func(
|
1086
1050
|
self: Self,
|
1087
|
-
months_from_last:
|
1088
|
-
from_date:
|
1089
|
-
to_date:
|
1090
|
-
periods_in_a_year_fixed:
|
1091
|
-
) ->
|
1092
|
-
"""
|
1093
|
-
Annualized volatility.
|
1051
|
+
months_from_last: int | None = None,
|
1052
|
+
from_date: dt.date | None = None,
|
1053
|
+
to_date: dt.date | None = None,
|
1054
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
1055
|
+
) -> float | Series[float]:
|
1056
|
+
"""Annualized volatility.
|
1094
1057
|
|
1095
1058
|
Based on Pandas .std() which is the equivalent of stdev.s([...]) in MS Excel.
|
1096
1059
|
https://www.investopedia.com/terms/v/volatility.asp.
|
@@ -1109,7 +1072,7 @@ class _CommonModel(BaseModel):
|
|
1109
1072
|
|
1110
1073
|
Returns
|
1111
1074
|
-------
|
1112
|
-
|
1075
|
+
float | Pandas.Series[float]
|
1113
1076
|
Annualized volatility
|
1114
1077
|
|
1115
1078
|
"""
|
@@ -1144,16 +1107,15 @@ class _CommonModel(BaseModel):
|
|
1144
1107
|
def vol_from_var_func(
|
1145
1108
|
self: Self,
|
1146
1109
|
level: float = 0.95,
|
1147
|
-
months_from_last:
|
1148
|
-
from_date:
|
1149
|
-
to_date:
|
1110
|
+
months_from_last: int | None = None,
|
1111
|
+
from_date: dt.date | None = None,
|
1112
|
+
to_date: dt.date | None = None,
|
1150
1113
|
interpolation: LiteralQuantileInterp = "lower",
|
1151
|
-
periods_in_a_year_fixed:
|
1114
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
1152
1115
|
*,
|
1153
1116
|
drift_adjust: bool = False,
|
1154
|
-
) ->
|
1155
|
-
"""
|
1156
|
-
Implied annualized volatility.
|
1117
|
+
) -> float | Series[float]:
|
1118
|
+
"""Implied annualized volatility.
|
1157
1119
|
|
1158
1120
|
Implied annualized volatility from the Downside VaR using the assumption
|
1159
1121
|
that returns are normally distributed.
|
@@ -1179,7 +1141,7 @@ class _CommonModel(BaseModel):
|
|
1179
1141
|
|
1180
1142
|
Returns
|
1181
1143
|
-------
|
1182
|
-
|
1144
|
+
float | Pandas.Series[float]
|
1183
1145
|
Implied annualized volatility from the Downside VaR using the
|
1184
1146
|
assumption that returns are normally distributed.
|
1185
1147
|
|
@@ -1200,16 +1162,15 @@ class _CommonModel(BaseModel):
|
|
1200
1162
|
level: float = 0.95,
|
1201
1163
|
min_leverage_local: float = 0.0,
|
1202
1164
|
max_leverage_local: float = 99999.0,
|
1203
|
-
months_from_last:
|
1204
|
-
from_date:
|
1205
|
-
to_date:
|
1165
|
+
months_from_last: int | None = None,
|
1166
|
+
from_date: dt.date | None = None,
|
1167
|
+
to_date: dt.date | None = None,
|
1206
1168
|
interpolation: LiteralQuantileInterp = "lower",
|
1207
|
-
periods_in_a_year_fixed:
|
1169
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
1208
1170
|
*,
|
1209
1171
|
drift_adjust: bool = False,
|
1210
|
-
) ->
|
1211
|
-
"""
|
1212
|
-
Target weight from VaR.
|
1172
|
+
) -> float | Series[float]:
|
1173
|
+
"""Target weight from VaR.
|
1213
1174
|
|
1214
1175
|
A position weight multiplier from the ratio between a VaR implied
|
1215
1176
|
volatility and a given target volatility. Multiplier = 1.0 -> target met.
|
@@ -1241,7 +1202,7 @@ class _CommonModel(BaseModel):
|
|
1241
1202
|
|
1242
1203
|
Returns
|
1243
1204
|
-------
|
1244
|
-
|
1205
|
+
float | Pandas.Series[float]
|
1245
1206
|
A position weight multiplier from the ratio between a VaR implied
|
1246
1207
|
volatility and a given target volatility. Multiplier = 1.0 -> target met
|
1247
1208
|
|
@@ -1262,19 +1223,18 @@ class _CommonModel(BaseModel):
|
|
1262
1223
|
def _var_implied_vol_and_target_func(
|
1263
1224
|
self: Self,
|
1264
1225
|
level: float,
|
1265
|
-
target_vol:
|
1226
|
+
target_vol: float | None = None,
|
1266
1227
|
min_leverage_local: float = 0.0,
|
1267
1228
|
max_leverage_local: float = 99999.0,
|
1268
|
-
months_from_last:
|
1269
|
-
from_date:
|
1270
|
-
to_date:
|
1229
|
+
months_from_last: int | None = None,
|
1230
|
+
from_date: dt.date | None = None,
|
1231
|
+
to_date: dt.date | None = None,
|
1271
1232
|
interpolation: LiteralQuantileInterp = "lower",
|
1272
|
-
periods_in_a_year_fixed:
|
1233
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
1273
1234
|
*,
|
1274
1235
|
drift_adjust: bool = False,
|
1275
|
-
) ->
|
1276
|
-
"""
|
1277
|
-
Volatility implied from VaR or Target Weight.
|
1236
|
+
) -> float | Series[float]:
|
1237
|
+
"""Volatility implied from VaR or Target Weight.
|
1278
1238
|
|
1279
1239
|
The function returns a position weight multiplier from the ratio between
|
1280
1240
|
a VaR implied volatility and a given target volatility if the argument
|
@@ -1285,7 +1245,7 @@ class _CommonModel(BaseModel):
|
|
1285
1245
|
----------
|
1286
1246
|
level: float
|
1287
1247
|
The sought VaR level
|
1288
|
-
target_vol:
|
1248
|
+
target_vol: float | None
|
1289
1249
|
Target Volatility
|
1290
1250
|
min_leverage_local: float, default: 0.0
|
1291
1251
|
A minimum adjustment factor
|
@@ -1308,7 +1268,7 @@ class _CommonModel(BaseModel):
|
|
1308
1268
|
|
1309
1269
|
Returns
|
1310
1270
|
-------
|
1311
|
-
|
1271
|
+
float | Pandas.Series[float]
|
1312
1272
|
Target volatility if target_vol is provided otherwise the VaR
|
1313
1273
|
implied volatility.
|
1314
1274
|
|
@@ -1373,12 +1333,11 @@ class _CommonModel(BaseModel):
|
|
1373
1333
|
def cvar_down_func(
|
1374
1334
|
self: Self,
|
1375
1335
|
level: float = 0.95,
|
1376
|
-
months_from_last:
|
1377
|
-
from_date:
|
1378
|
-
to_date:
|
1379
|
-
) ->
|
1380
|
-
"""
|
1381
|
-
Downside Conditional Value At Risk "CVaR".
|
1336
|
+
months_from_last: int | None = None,
|
1337
|
+
from_date: dt.date | None = None,
|
1338
|
+
to_date: dt.date | None = None,
|
1339
|
+
) -> float | Series[float]:
|
1340
|
+
"""Downside Conditional Value At Risk "CVaR".
|
1382
1341
|
|
1383
1342
|
https://www.investopedia.com/terms/c/conditional_value_at_risk.asp.
|
1384
1343
|
|
@@ -1396,7 +1355,7 @@ class _CommonModel(BaseModel):
|
|
1396
1355
|
|
1397
1356
|
Returns
|
1398
1357
|
-------
|
1399
|
-
|
1358
|
+
float | Pandas.Series[float]
|
1400
1359
|
Downside Conditional Value At Risk "CVaR"
|
1401
1360
|
|
1402
1361
|
"""
|
@@ -1435,13 +1394,12 @@ class _CommonModel(BaseModel):
|
|
1435
1394
|
def downside_deviation_func(
|
1436
1395
|
self: Self,
|
1437
1396
|
min_accepted_return: float = 0.0,
|
1438
|
-
months_from_last:
|
1439
|
-
from_date:
|
1440
|
-
to_date:
|
1441
|
-
periods_in_a_year_fixed:
|
1442
|
-
) ->
|
1443
|
-
"""
|
1444
|
-
Downside Deviation.
|
1397
|
+
months_from_last: int | None = None,
|
1398
|
+
from_date: dt.date | None = None,
|
1399
|
+
to_date: dt.date | None = None,
|
1400
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
1401
|
+
) -> float | Series[float]:
|
1402
|
+
"""Downside Deviation.
|
1445
1403
|
|
1446
1404
|
The standard deviation of returns that are below a Minimum Accepted
|
1447
1405
|
Return of zero. It is used to calculate the Sortino Ratio.
|
@@ -1464,7 +1422,7 @@ class _CommonModel(BaseModel):
|
|
1464
1422
|
|
1465
1423
|
Returns
|
1466
1424
|
-------
|
1467
|
-
|
1425
|
+
float | Pandas.Series[float]
|
1468
1426
|
Downside deviation
|
1469
1427
|
|
1470
1428
|
"""
|
@@ -1510,12 +1468,11 @@ class _CommonModel(BaseModel):
|
|
1510
1468
|
|
1511
1469
|
def geo_ret_func(
|
1512
1470
|
self: Self,
|
1513
|
-
months_from_last:
|
1514
|
-
from_date:
|
1515
|
-
to_date:
|
1516
|
-
) ->
|
1517
|
-
"""
|
1518
|
-
Compounded Annual Growth Rate (CAGR).
|
1471
|
+
months_from_last: int | None = None,
|
1472
|
+
from_date: dt.date | None = None,
|
1473
|
+
to_date: dt.date | None = None,
|
1474
|
+
) -> float | Series[float]:
|
1475
|
+
"""Compounded Annual Growth Rate (CAGR).
|
1519
1476
|
|
1520
1477
|
https://www.investopedia.com/terms/c/cagr.asp.
|
1521
1478
|
|
@@ -1531,7 +1488,7 @@ class _CommonModel(BaseModel):
|
|
1531
1488
|
|
1532
1489
|
Returns
|
1533
1490
|
-------
|
1534
|
-
|
1491
|
+
float | Pandas.Series[float]
|
1535
1492
|
Compounded Annual Growth Rate (CAGR)
|
1536
1493
|
|
1537
1494
|
"""
|
@@ -1564,12 +1521,11 @@ class _CommonModel(BaseModel):
|
|
1564
1521
|
|
1565
1522
|
def skew_func(
|
1566
1523
|
self: Self,
|
1567
|
-
months_from_last:
|
1568
|
-
from_date:
|
1569
|
-
to_date:
|
1570
|
-
) ->
|
1571
|
-
"""
|
1572
|
-
Skew of the return distribution.
|
1524
|
+
months_from_last: int | None = None,
|
1525
|
+
from_date: dt.date | None = None,
|
1526
|
+
to_date: dt.date | None = None,
|
1527
|
+
) -> float | Series[float]:
|
1528
|
+
"""Skew of the return distribution.
|
1573
1529
|
|
1574
1530
|
https://www.investopedia.com/terms/s/skewness.asp.
|
1575
1531
|
|
@@ -1585,7 +1541,7 @@ class _CommonModel(BaseModel):
|
|
1585
1541
|
|
1586
1542
|
Returns
|
1587
1543
|
-------
|
1588
|
-
|
1544
|
+
float | Pandas.Series[float]
|
1589
1545
|
Skew of the return distribution
|
1590
1546
|
|
1591
1547
|
"""
|
@@ -1613,12 +1569,11 @@ class _CommonModel(BaseModel):
|
|
1613
1569
|
|
1614
1570
|
def kurtosis_func(
|
1615
1571
|
self: Self,
|
1616
|
-
months_from_last:
|
1617
|
-
from_date:
|
1618
|
-
to_date:
|
1619
|
-
) ->
|
1620
|
-
"""
|
1621
|
-
Kurtosis of the return distribution.
|
1572
|
+
months_from_last: int | None = None,
|
1573
|
+
from_date: dt.date | None = None,
|
1574
|
+
to_date: dt.date | None = None,
|
1575
|
+
) -> float | Series[float]:
|
1576
|
+
"""Kurtosis of the return distribution.
|
1622
1577
|
|
1623
1578
|
https://www.investopedia.com/terms/k/kurtosis.asp.
|
1624
1579
|
|
@@ -1634,7 +1589,7 @@ class _CommonModel(BaseModel):
|
|
1634
1589
|
|
1635
1590
|
Returns
|
1636
1591
|
-------
|
1637
|
-
|
1592
|
+
float | Pandas.Series[float]
|
1638
1593
|
Kurtosis of the return distribution
|
1639
1594
|
|
1640
1595
|
"""
|
@@ -1663,13 +1618,12 @@ class _CommonModel(BaseModel):
|
|
1663
1618
|
|
1664
1619
|
def max_drawdown_func(
|
1665
1620
|
self: Self,
|
1666
|
-
months_from_last:
|
1667
|
-
from_date:
|
1668
|
-
to_date:
|
1621
|
+
months_from_last: int | None = None,
|
1622
|
+
from_date: dt.date | None = None,
|
1623
|
+
to_date: dt.date | None = None,
|
1669
1624
|
min_periods: int = 1,
|
1670
|
-
) ->
|
1671
|
-
"""
|
1672
|
-
Maximum drawdown without any limit on date range.
|
1625
|
+
) -> float | Series[float]:
|
1626
|
+
"""Maximum drawdown without any limit on date range.
|
1673
1627
|
|
1674
1628
|
https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
|
1675
1629
|
|
@@ -1687,7 +1641,7 @@ class _CommonModel(BaseModel):
|
|
1687
1641
|
|
1688
1642
|
Returns
|
1689
1643
|
-------
|
1690
|
-
|
1644
|
+
float | Pandas.Series[float]
|
1691
1645
|
Maximum drawdown without any limit on date range
|
1692
1646
|
|
1693
1647
|
"""
|
@@ -1713,12 +1667,11 @@ class _CommonModel(BaseModel):
|
|
1713
1667
|
|
1714
1668
|
def positive_share_func(
|
1715
1669
|
self: Self,
|
1716
|
-
months_from_last:
|
1717
|
-
from_date:
|
1718
|
-
to_date:
|
1719
|
-
) ->
|
1720
|
-
"""
|
1721
|
-
Calculate share of percentage changes that are greater than zero.
|
1670
|
+
months_from_last: int | None = None,
|
1671
|
+
from_date: dt.date | None = None,
|
1672
|
+
to_date: dt.date | None = None,
|
1673
|
+
) -> float | Series[float]:
|
1674
|
+
"""Calculate share of percentage changes that are greater than zero.
|
1722
1675
|
|
1723
1676
|
Parameters
|
1724
1677
|
----------
|
@@ -1732,7 +1685,7 @@ class _CommonModel(BaseModel):
|
|
1732
1685
|
|
1733
1686
|
Returns
|
1734
1687
|
-------
|
1735
|
-
|
1688
|
+
float | Pandas.Series[float]
|
1736
1689
|
Calculate share of percentage changes that are greater than zero
|
1737
1690
|
|
1738
1691
|
"""
|
@@ -1770,13 +1723,12 @@ class _CommonModel(BaseModel):
|
|
1770
1723
|
def ret_vol_ratio_func(
|
1771
1724
|
self: Self,
|
1772
1725
|
riskfree_rate: float = 0.0,
|
1773
|
-
months_from_last:
|
1774
|
-
from_date:
|
1775
|
-
to_date:
|
1776
|
-
periods_in_a_year_fixed:
|
1777
|
-
) ->
|
1778
|
-
"""
|
1779
|
-
Ratio between arithmetic mean of returns and annualized volatility.
|
1726
|
+
months_from_last: int | None = None,
|
1727
|
+
from_date: dt.date | None = None,
|
1728
|
+
to_date: dt.date | None = None,
|
1729
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
1730
|
+
) -> float | Series[float]:
|
1731
|
+
"""Ratio between arithmetic mean of returns and annualized volatility.
|
1780
1732
|
|
1781
1733
|
The ratio of annualized arithmetic mean of returns and annualized
|
1782
1734
|
volatility or, if riskfree return provided, Sharpe ratio calculated
|
@@ -1801,7 +1753,7 @@ class _CommonModel(BaseModel):
|
|
1801
1753
|
|
1802
1754
|
Returns
|
1803
1755
|
-------
|
1804
|
-
|
1756
|
+
float | Pandas.Series[float]
|
1805
1757
|
Ratio of the annualized arithmetic mean of returns and annualized
|
1806
1758
|
volatility or, if risk-free return provided, Sharpe ratio
|
1807
1759
|
|
@@ -1834,13 +1786,12 @@ class _CommonModel(BaseModel):
|
|
1834
1786
|
self: Self,
|
1835
1787
|
riskfree_rate: float = 0.0,
|
1836
1788
|
min_accepted_return: float = 0.0,
|
1837
|
-
months_from_last:
|
1838
|
-
from_date:
|
1839
|
-
to_date:
|
1840
|
-
periods_in_a_year_fixed:
|
1841
|
-
) ->
|
1842
|
-
"""
|
1843
|
-
Sortino Ratio.
|
1789
|
+
months_from_last: int | None = None,
|
1790
|
+
from_date: dt.date | None = None,
|
1791
|
+
to_date: dt.date | None = None,
|
1792
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
1793
|
+
) -> float | Series[float]:
|
1794
|
+
"""Sortino Ratio.
|
1844
1795
|
|
1845
1796
|
The Sortino ratio calculated as ( return - risk free return )
|
1846
1797
|
/ downside deviation. The ratio implies that the riskfree asset has zero
|
@@ -1867,7 +1818,7 @@ class _CommonModel(BaseModel):
|
|
1867
1818
|
|
1868
1819
|
Returns
|
1869
1820
|
-------
|
1870
|
-
|
1821
|
+
float | Pandas.Series[float]
|
1871
1822
|
Sortino ratio calculated as ( return - riskfree return ) /
|
1872
1823
|
downside deviation (std dev of returns below MAR)
|
1873
1824
|
|
@@ -1900,12 +1851,11 @@ class _CommonModel(BaseModel):
|
|
1900
1851
|
def omega_ratio_func(
|
1901
1852
|
self: Self,
|
1902
1853
|
min_accepted_return: float = 0.0,
|
1903
|
-
months_from_last:
|
1904
|
-
from_date:
|
1905
|
-
to_date:
|
1906
|
-
) ->
|
1907
|
-
"""
|
1908
|
-
Omega Ratio.
|
1854
|
+
months_from_last: int | None = None,
|
1855
|
+
from_date: dt.date | None = None,
|
1856
|
+
to_date: dt.date | None = None,
|
1857
|
+
) -> float | Series[float]:
|
1858
|
+
"""Omega Ratio.
|
1909
1859
|
|
1910
1860
|
The Omega Ratio compares returns above a certain target level
|
1911
1861
|
(often referred to as the “minimum acceptable return” or “MAR”)
|
@@ -1926,7 +1876,7 @@ class _CommonModel(BaseModel):
|
|
1926
1876
|
|
1927
1877
|
Returns
|
1928
1878
|
-------
|
1929
|
-
|
1879
|
+
float | Pandas.Series[float]
|
1930
1880
|
Omega ratio calculation
|
1931
1881
|
|
1932
1882
|
"""
|
@@ -1953,12 +1903,11 @@ class _CommonModel(BaseModel):
|
|
1953
1903
|
|
1954
1904
|
def value_ret_func(
|
1955
1905
|
self: Self,
|
1956
|
-
months_from_last:
|
1957
|
-
from_date:
|
1958
|
-
to_date:
|
1959
|
-
) ->
|
1960
|
-
"""
|
1961
|
-
Calculate simple return.
|
1906
|
+
months_from_last: int | None = None,
|
1907
|
+
from_date: dt.date | None = None,
|
1908
|
+
to_date: dt.date | None = None,
|
1909
|
+
) -> float | Series[float]:
|
1910
|
+
"""Calculate simple return.
|
1962
1911
|
|
1963
1912
|
Parameters
|
1964
1913
|
----------
|
@@ -1972,7 +1921,7 @@ class _CommonModel(BaseModel):
|
|
1972
1921
|
|
1973
1922
|
Returns
|
1974
1923
|
-------
|
1975
|
-
|
1924
|
+
float | Pandas.Series[float]
|
1976
1925
|
Calculate simple return
|
1977
1926
|
|
1978
1927
|
"""
|
@@ -2005,10 +1954,9 @@ class _CommonModel(BaseModel):
|
|
2005
1954
|
def value_ret_calendar_period(
|
2006
1955
|
self: Self,
|
2007
1956
|
year: int,
|
2008
|
-
month:
|
2009
|
-
) ->
|
2010
|
-
"""
|
2011
|
-
Calculate simple return for a specific calendar period.
|
1957
|
+
month: int | None = None,
|
1958
|
+
) -> float | Series[float]:
|
1959
|
+
"""Calculate simple return for a specific calendar period.
|
2012
1960
|
|
2013
1961
|
Parameters
|
2014
1962
|
----------
|
@@ -2019,7 +1967,7 @@ class _CommonModel(BaseModel):
|
|
2019
1967
|
|
2020
1968
|
Returns
|
2021
1969
|
-------
|
2022
|
-
|
1970
|
+
float | Pandas.Series[float]
|
2023
1971
|
Calculate simple return for a specific calendar period
|
2024
1972
|
|
2025
1973
|
"""
|
@@ -2029,7 +1977,7 @@ class _CommonModel(BaseModel):
|
|
2029
1977
|
period = "-".join([str(year), str(month).zfill(2)])
|
2030
1978
|
vrdf = self.tsdf.copy()
|
2031
1979
|
vrdf.index = DatetimeIndex(vrdf.index)
|
2032
|
-
resultdf = DataFrame(vrdf.pct_change(fill_method=
|
1980
|
+
resultdf = DataFrame(vrdf.pct_change(fill_method=None)) # type: ignore[arg-type]
|
2033
1981
|
result = resultdf.loc[period] + 1
|
2034
1982
|
cal_period = result.cumprod(axis="index").iloc[-1] - 1
|
2035
1983
|
if self.tsdf.shape[1] == 1:
|
@@ -2044,13 +1992,12 @@ class _CommonModel(BaseModel):
|
|
2044
1992
|
def var_down_func(
|
2045
1993
|
self: Self,
|
2046
1994
|
level: float = 0.95,
|
2047
|
-
months_from_last:
|
2048
|
-
from_date:
|
2049
|
-
to_date:
|
1995
|
+
months_from_last: int | None = None,
|
1996
|
+
from_date: dt.date | None = None,
|
1997
|
+
to_date: dt.date | None = None,
|
2050
1998
|
interpolation: LiteralQuantileInterp = "lower",
|
2051
|
-
) ->
|
2052
|
-
"""
|
2053
|
-
Downside Value At Risk, "VaR".
|
1999
|
+
) -> float | Series[float]:
|
2000
|
+
"""Downside Value At Risk, "VaR".
|
2054
2001
|
|
2055
2002
|
The equivalent of percentile.inc([...], 1-level) over returns in MS Excel.
|
2056
2003
|
https://www.investopedia.com/terms/v/var.asp.
|
@@ -2071,7 +2018,7 @@ class _CommonModel(BaseModel):
|
|
2071
2018
|
|
2072
2019
|
Returns
|
2073
2020
|
-------
|
2074
|
-
|
2021
|
+
float | Pandas.Series[float]
|
2075
2022
|
Downside Value At Risk
|
2076
2023
|
|
2077
2024
|
"""
|
@@ -2098,12 +2045,11 @@ class _CommonModel(BaseModel):
|
|
2098
2045
|
def worst_func(
|
2099
2046
|
self: Self,
|
2100
2047
|
observations: int = 1,
|
2101
|
-
months_from_last:
|
2102
|
-
from_date:
|
2103
|
-
to_date:
|
2104
|
-
) ->
|
2105
|
-
"""
|
2106
|
-
Most negative percentage change over a rolling number of observations.
|
2048
|
+
months_from_last: int | None = None,
|
2049
|
+
from_date: dt.date | None = None,
|
2050
|
+
to_date: dt.date | None = None,
|
2051
|
+
) -> float | Series[float]:
|
2052
|
+
"""Most negative percentage change over a rolling number of observations.
|
2107
2053
|
|
2108
2054
|
Parameters
|
2109
2055
|
----------
|
@@ -2119,7 +2065,7 @@ class _CommonModel(BaseModel):
|
|
2119
2065
|
|
2120
2066
|
Returns
|
2121
2067
|
-------
|
2122
|
-
|
2068
|
+
float | Pandas.Series[float]
|
2123
2069
|
Most negative percentage change over a rolling number of observations
|
2124
2070
|
within a chosen date range
|
2125
2071
|
|
@@ -2148,12 +2094,11 @@ class _CommonModel(BaseModel):
|
|
2148
2094
|
|
2149
2095
|
def z_score_func(
|
2150
2096
|
self: Self,
|
2151
|
-
months_from_last:
|
2152
|
-
from_date:
|
2153
|
-
to_date:
|
2154
|
-
) ->
|
2155
|
-
"""
|
2156
|
-
Z-score as (last return - mean return) / standard deviation of returns.
|
2097
|
+
months_from_last: int | None = None,
|
2098
|
+
from_date: dt.date | None = None,
|
2099
|
+
to_date: dt.date | None = None,
|
2100
|
+
) -> float | Series[float]:
|
2101
|
+
"""Z-score as (last return - mean return) / standard deviation of returns.
|
2157
2102
|
|
2158
2103
|
https://www.investopedia.com/terms/z/zscore.asp.
|
2159
2104
|
|
@@ -2169,7 +2114,7 @@ class _CommonModel(BaseModel):
|
|
2169
2114
|
|
2170
2115
|
Returns
|
2171
2116
|
-------
|
2172
|
-
|
2117
|
+
float | Pandas.Series[float]
|
2173
2118
|
Z-score as (last return - mean return) / standard deviation of returns
|
2174
2119
|
|
2175
2120
|
"""
|
@@ -2198,8 +2143,7 @@ class _CommonModel(BaseModel):
|
|
2198
2143
|
level: float = 0.95,
|
2199
2144
|
observations: int = 252,
|
2200
2145
|
) -> DataFrame:
|
2201
|
-
"""
|
2202
|
-
Calculate rolling annualized downside CVaR.
|
2146
|
+
"""Calculate rolling annualized downside CVaR.
|
2203
2147
|
|
2204
2148
|
Parameters
|
2205
2149
|
----------
|
@@ -2232,8 +2176,7 @@ class _CommonModel(BaseModel):
|
|
2232
2176
|
column: int = 0,
|
2233
2177
|
observations: int = 21,
|
2234
2178
|
) -> DataFrame:
|
2235
|
-
"""
|
2236
|
-
Calculate rolling returns.
|
2179
|
+
"""Calculate rolling returns.
|
2237
2180
|
|
2238
2181
|
Parameters
|
2239
2182
|
----------
|
@@ -2267,8 +2210,7 @@ class _CommonModel(BaseModel):
|
|
2267
2210
|
observations: int = 252,
|
2268
2211
|
interpolation: LiteralQuantileInterp = "lower",
|
2269
2212
|
) -> DataFrame:
|
2270
|
-
"""
|
2271
|
-
Calculate rolling annualized downside Value At Risk "VaR".
|
2213
|
+
"""Calculate rolling annualized downside Value At Risk "VaR".
|
2272
2214
|
|
2273
2215
|
Parameters
|
2274
2216
|
----------
|
@@ -2304,10 +2246,9 @@ class _CommonModel(BaseModel):
|
|
2304
2246
|
self: Self,
|
2305
2247
|
column: int = 0,
|
2306
2248
|
observations: int = 21,
|
2307
|
-
periods_in_a_year_fixed:
|
2249
|
+
periods_in_a_year_fixed: DaysInYearType | None = None,
|
2308
2250
|
) -> DataFrame:
|
2309
|
-
"""
|
2310
|
-
Calculate rolling annualised volatilities.
|
2251
|
+
"""Calculate rolling annualised volatilities.
|
2311
2252
|
|
2312
2253
|
Parameters
|
2313
2254
|
----------
|