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