openseries 1.9.6__py3-none-any.whl → 2.0.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.
@@ -1,10 +1,6 @@
1
- """Defining the _CommonModel class.
1
+ """The _CommonModel class.
2
2
 
3
- Copyright (c) Captor Fund Management AB. This file is part of the openseries project.
4
-
5
- Licensed under the BSD 3-Clause License. You may obtain a copy of the License at:
6
- https://github.com/CaptorAB/openseries/blob/master/LICENSE.md
7
- SPDX-License-Identifier: BSD-3-Clause
3
+ _CommonModel class which is the base class for OpenFrame and OpenTimeSeries.
8
4
  """
9
5
 
10
6
  from __future__ import annotations
@@ -22,13 +18,13 @@ from numpy import asarray, float64, inf, isnan, log, maximum, sqrt
22
18
 
23
19
  from .owntypes import (
24
20
  CaptorLogoType,
25
- Combo_co,
26
21
  DateAlignmentError,
27
22
  InitialValueZeroError,
28
23
  NumberOfItemsAndLabelsNotSameError,
29
24
  PlotlyConfigType,
30
25
  ResampleDataLossError,
31
26
  Self,
27
+ SeriesOrFloat_co,
32
28
  ValueType,
33
29
  )
34
30
 
@@ -87,8 +83,127 @@ from .datefixer import (
87
83
  from .load_plotly import load_plotly_dict
88
84
 
89
85
 
90
- # noinspection PyTypeChecker
91
- class _CommonModel(BaseModel, Generic[Combo_co]):
86
+ def _get_date_range_and_factor(
87
+ self: _CommonModel[SeriesOrFloat_co],
88
+ months_from_last: int | None = None,
89
+ from_date: dt.date | None = None,
90
+ to_date: dt.date | None = None,
91
+ periods_in_a_year_fixed: DaysInYearType | None = None,
92
+ ) -> tuple[dt.date, dt.date, float, DataFrame]:
93
+ """Common logic for date range and time factor calculation.
94
+
95
+ Parameters
96
+ ----------
97
+ months_from_last : int, optional
98
+ Number of months offset as positive integer. Overrides use of from_date
99
+ and to_date
100
+ from_date : datetime.date, optional
101
+ Specific from date
102
+ to_date : datetime.date, optional
103
+ Specific to date
104
+ periods_in_a_year_fixed : DaysInYearType, optional
105
+ Allows locking the periods-in-a-year to simplify test cases and
106
+ comparisons
107
+
108
+ Returns:
109
+ --------
110
+ tuple[dt.date, dt.date, float, DataFrame]
111
+ earlier, later, time_factor, data
112
+ """
113
+ earlier, later = self.calc_range(
114
+ months_offset=months_from_last,
115
+ from_dt=from_date,
116
+ to_dt=to_date,
117
+ )
118
+
119
+ if periods_in_a_year_fixed:
120
+ time_factor = float(periods_in_a_year_fixed)
121
+ else:
122
+ how_many = (
123
+ self.tsdf.loc[cast("Timestamp", earlier) : cast("Timestamp", later)]
124
+ .count()
125
+ .iloc[0]
126
+ )
127
+ fraction = (later - earlier).days / 365.25
128
+ time_factor = how_many / fraction
129
+
130
+ data = self.tsdf.loc[cast("Timestamp", earlier) : cast("Timestamp", later)]
131
+ return earlier, later, time_factor, data
132
+
133
+
134
+ def _get_base_column_data(
135
+ self: _CommonModel[SeriesOrFloat_co],
136
+ base_column: tuple[str, ValueType] | int,
137
+ earlier: dt.date,
138
+ later: dt.date,
139
+ ) -> tuple[Series[float], tuple[str, ValueType], str]:
140
+ """Common logic for base column data extraction.
141
+
142
+ Parameters
143
+ ----------
144
+ base_column : tuple[str, ValueType] | int
145
+ Column reference
146
+ earlier : dt.date
147
+ Start date
148
+ later : dt.date
149
+ End date
150
+
151
+ Returns:
152
+ --------
153
+ tuple[Series[float], tuple[str, ValueType], str]
154
+ data, item, label
155
+ """
156
+ if isinstance(base_column, tuple):
157
+ data = self.tsdf.loc[cast("Timestamp", earlier) : cast("Timestamp", later)][
158
+ base_column
159
+ ]
160
+ item = base_column
161
+ label = cast("tuple[str, str]", self.tsdf[base_column].name)[0]
162
+ elif isinstance(base_column, int):
163
+ data = self.tsdf.loc[
164
+ cast("Timestamp", earlier) : cast("Timestamp", later)
165
+ ].iloc[:, base_column]
166
+ item = cast("tuple[str, ValueType]", self.tsdf.iloc[:, base_column].name)
167
+ label = cast("tuple[str, str]", self.tsdf.iloc[:, base_column].name)[0]
168
+ else:
169
+ msg = "base_column should be a tuple[str, ValueType] or an integer."
170
+ raise TypeError(msg)
171
+
172
+ return data, item, label
173
+
174
+
175
+ def _calculate_time_factor(
176
+ data: Series[float],
177
+ earlier: dt.date,
178
+ later: dt.date,
179
+ periods_in_a_year_fixed: DaysInYearType | None = None,
180
+ ) -> float:
181
+ """Calculate time factor for annualization.
182
+
183
+ Parameters
184
+ ----------
185
+ data : Series[float]
186
+ Data series for counting observations
187
+ earlier : dt.date
188
+ Start date
189
+ later : dt.date
190
+ End date
191
+ periods_in_a_year_fixed : DaysInYearType, optional
192
+ Fixed periods in year
193
+
194
+ Returns:
195
+ --------
196
+ float
197
+ Time factor
198
+ """
199
+ if periods_in_a_year_fixed:
200
+ return float(periods_in_a_year_fixed)
201
+
202
+ fraction = (later - earlier).days / 365.25
203
+ return data.count() / fraction
204
+
205
+
206
+ class _CommonModel(BaseModel, Generic[SeriesOrFloat_co]):
92
207
  """Declare _CommonModel."""
93
208
 
94
209
  tsdf: DataFrame = DataFrame(dtype="float64")
@@ -99,12 +214,14 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
99
214
  revalidate_instances="always",
100
215
  )
101
216
 
102
- def _coerce_result(self: Self, result: Series[float], name: str) -> Combo_co:
217
+ def _coerce_result(
218
+ self: Self, result: Series[float], name: str
219
+ ) -> SeriesOrFloat_co:
103
220
  if self.tsdf.shape[1] == 1:
104
221
  arr = float(asarray(a=result, dtype=float64).squeeze())
105
- return cast("Combo_co", arr) # type: ignore[redundant-cast]
222
+ return cast("SeriesOrFloat_co", arr) # type: ignore[redundant-cast]
106
223
  return cast(
107
- "Combo_co",
224
+ "SeriesOrFloat_co",
108
225
  Series(
109
226
  data=result,
110
227
  index=self.tsdf.columns,
@@ -118,7 +235,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
118
235
  """Number of observations.
119
236
 
120
237
  Returns:
121
- -------
238
+ --------
122
239
  int
123
240
  Number of observations
124
241
 
@@ -130,7 +247,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
130
247
  """The first date in the timeseries.
131
248
 
132
249
  Returns:
133
- -------
250
+ --------
134
251
  datetime.date
135
252
  The first date in the timeseries
136
253
 
@@ -142,7 +259,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
142
259
  """The last date in the timeseries.
143
260
 
144
261
  Returns:
145
- -------
262
+ --------
146
263
  datetime.date
147
264
  The last date in the timeseries
148
265
 
@@ -154,7 +271,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
154
271
  """Number of days from the first date to the last.
155
272
 
156
273
  Returns:
157
- -------
274
+ --------
158
275
  int
159
276
  Number of days from the first date to the last
160
277
 
@@ -166,7 +283,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
166
283
  """Length of series expressed in years assuming all years have 365.25 days.
167
284
 
168
285
  Returns:
169
- -------
286
+ --------
170
287
  float
171
288
  Length of the timeseries expressed in years assuming all years
172
289
  have 365.25 days
@@ -179,7 +296,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
179
296
  """The average number of observations per year.
180
297
 
181
298
  Returns:
182
- -------
299
+ --------
183
300
  float
184
301
  The average number of observations per year
185
302
 
@@ -187,13 +304,14 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
187
304
  return self.length / self.yearfrac
188
305
 
189
306
  @property
190
- def max_drawdown_cal_year(self: Self) -> Combo_co:
307
+ def max_drawdown_cal_year(self: Self) -> SeriesOrFloat_co:
191
308
  """https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
192
309
 
193
310
  Returns:
194
- -------
195
- Combo_co
311
+ --------
312
+ SeriesOrFloat_co
196
313
  Maximum drawdown in a single calendar year.
314
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
197
315
 
198
316
  """
199
317
  years = Index(d.year for d in self.tsdf.index)
@@ -208,58 +326,66 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
208
326
  return self._coerce_result(result=result, name="Max drawdown in cal yr")
209
327
 
210
328
  @property
211
- def geo_ret(self: Self) -> Combo_co:
329
+ def geo_ret(self: Self) -> SeriesOrFloat_co:
212
330
  """https://www.investopedia.com/terms/c/cagr.asp.
213
331
 
214
332
  Returns:
215
- -------
216
- Combo_co
217
- Compounded Annual Growth Rate (CAGR)
333
+ --------
334
+ SeriesOrFloat_co
335
+ Compounded Annual Growth Rate (CAGR).
336
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
337
+
218
338
 
219
339
  """
220
340
  return self.geo_ret_func()
221
341
 
222
342
  @property
223
- def arithmetic_ret(self: Self) -> Combo_co:
343
+ def arithmetic_ret(self: Self) -> SeriesOrFloat_co:
224
344
  """https://www.investopedia.com/terms/a/arithmeticmean.asp.
225
345
 
226
346
  Returns:
227
- -------
228
- Combo_co
229
- Annualized arithmetic mean of returns
347
+ --------
348
+ SeriesOrFloat_co
349
+ Annualized arithmetic mean of returns.
350
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
351
+
230
352
 
231
353
  """
232
354
  return self.arithmetic_ret_func()
233
355
 
234
356
  @property
235
- def value_ret(self: Self) -> Combo_co:
357
+ def value_ret(self: Self) -> SeriesOrFloat_co:
236
358
  """Simple return.
237
359
 
238
360
  Returns:
239
- -------
240
- Combo_co
241
- Simple return
361
+ --------
362
+ SeriesOrFloat_co
363
+ Simple return.
364
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
365
+
242
366
 
243
367
  """
244
368
  return self.value_ret_func()
245
369
 
246
370
  @property
247
- def vol(self: Self) -> Combo_co:
371
+ def vol(self: Self) -> SeriesOrFloat_co:
248
372
  """Annualized volatility.
249
373
 
250
374
  Based on Pandas .std() which is the equivalent of stdev.s([...]) in MS Excel.
251
375
  https://www.investopedia.com/terms/v/volatility.asp.
252
376
 
253
377
  Returns:
254
- -------
255
- Combo_co
256
- Annualized volatility
378
+ --------
379
+ SeriesOrFloat_co
380
+ Annualized volatility.
381
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
382
+
257
383
 
258
384
  """
259
385
  return self.vol_func()
260
386
 
261
387
  @property
262
- def downside_deviation(self: Self) -> Combo_co:
388
+ def downside_deviation(self: Self) -> SeriesOrFloat_co:
263
389
  """Downside Deviation.
264
390
 
265
391
  Standard deviation of returns that are below a Minimum Accepted Return
@@ -267,9 +393,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
267
393
  https://www.investopedia.com/terms/d/downside-deviation.asp.
268
394
 
269
395
  Returns:
270
- -------
271
- Combo_co
272
- Downside deviation
396
+ --------
397
+ SeriesOrFloat_co
398
+ Downside deviation.
399
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
400
+
273
401
 
274
402
  """
275
403
  min_accepted_return: float = 0.0
@@ -280,29 +408,31 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
280
408
  )
281
409
 
282
410
  @property
283
- def ret_vol_ratio(self: Self) -> Combo_co:
411
+ def ret_vol_ratio(self: Self) -> SeriesOrFloat_co:
284
412
  """Ratio of annualized arithmetic mean of returns and annualized volatility.
285
413
 
286
414
  Returns:
287
- -------
288
- Combo_co
415
+ --------
416
+ SeriesOrFloat_co
289
417
  Ratio of the annualized arithmetic mean of returns and annualized
290
418
  volatility.
419
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
291
420
 
292
421
  """
293
422
  riskfree_rate: float = 0.0
294
423
  return self.ret_vol_ratio_func(riskfree_rate=riskfree_rate)
295
424
 
296
425
  @property
297
- def sortino_ratio(self: Self) -> Combo_co:
426
+ def sortino_ratio(self: Self) -> SeriesOrFloat_co:
298
427
  """https://www.investopedia.com/terms/s/sortinoratio.asp.
299
428
 
300
429
  Returns:
301
- -------
302
- Combo_co
430
+ --------
431
+ SeriesOrFloat_co
303
432
  Sortino ratio calculated as the annualized arithmetic mean of returns
304
433
  / downside deviation. The ratio implies that the riskfree asset has zero
305
434
  volatility, and a minimum acceptable return of zero.
435
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
306
436
 
307
437
  """
308
438
  riskfree_rate: float = 0.0
@@ -313,7 +443,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
313
443
  )
314
444
 
315
445
  @property
316
- def kappa3_ratio(self: Self) -> Combo_co:
446
+ def kappa3_ratio(self: Self) -> SeriesOrFloat_co:
317
447
  """Kappa-3 ratio.
318
448
 
319
449
  The Kappa-3 ratio is a generalized downside-risk ratio defined as
@@ -323,10 +453,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
323
453
  the Sortino ratio (which uses order 2).
324
454
 
325
455
  Returns:
326
- -------
327
- Combo_co
328
- Kappa-3 ratio calculation with the riskfree rate and
456
+ --------
457
+ SeriesOrFloat_co
458
+ Kappa-3 ratio calculation with the riskfree rate and.
329
459
  Minimum Acceptable Return (MAR) both set to zero.
460
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
330
461
 
331
462
  """
332
463
  riskfree_rate: float = 0.0
@@ -339,38 +470,44 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
339
470
  )
340
471
 
341
472
  @property
342
- def omega_ratio(self: Self) -> Combo_co:
473
+ def omega_ratio(self: Self) -> SeriesOrFloat_co:
343
474
  """https://en.wikipedia.org/wiki/Omega_ratio.
344
475
 
345
476
  Returns:
346
- -------
347
- Combo_co
348
- Omega ratio calculation
477
+ --------
478
+ SeriesOrFloat_co
479
+ Omega ratio calculation.
480
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
481
+
349
482
 
350
483
  """
351
484
  minimum_accepted_return: float = 0.0
352
485
  return self.omega_ratio_func(min_accepted_return=minimum_accepted_return)
353
486
 
354
487
  @property
355
- def z_score(self: Self) -> Combo_co:
488
+ def z_score(self: Self) -> SeriesOrFloat_co:
356
489
  """https://www.investopedia.com/terms/z/zscore.asp.
357
490
 
358
491
  Returns:
359
- -------
360
- Combo_co
492
+ --------
493
+ SeriesOrFloat_co
361
494
  Z-score as (last return - mean return) / standard deviation of returns.
495
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
496
+
362
497
 
363
498
  """
364
499
  return self.z_score_func()
365
500
 
366
501
  @property
367
- def max_drawdown(self: Self) -> Combo_co:
502
+ def max_drawdown(self: Self) -> SeriesOrFloat_co:
368
503
  """https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
369
504
 
370
505
  Returns:
371
- -------
372
- Combo_co
373
- Maximum drawdown without any limit on date range
506
+ --------
507
+ SeriesOrFloat_co
508
+ Maximum drawdown without any limit on date range.
509
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
510
+
374
511
 
375
512
  """
376
513
  return self.max_drawdown_func()
@@ -382,7 +519,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
382
519
  https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
383
520
 
384
521
  Returns:
385
- -------
522
+ --------
386
523
  datetime.date | pandas.Series[dt.date]
387
524
  Date when the maximum drawdown occurred
388
525
 
@@ -401,26 +538,30 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
401
538
  ).dt.date
402
539
 
403
540
  @property
404
- def worst(self: Self) -> Combo_co:
541
+ def worst(self: Self) -> SeriesOrFloat_co:
405
542
  """Most negative percentage change.
406
543
 
407
544
  Returns:
408
- -------
409
- Combo_co
410
- Most negative percentage change
545
+ --------
546
+ SeriesOrFloat_co
547
+ Most negative percentage change.
548
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
549
+
411
550
 
412
551
  """
413
552
  observations: int = 1
414
553
  return self.worst_func(observations=observations)
415
554
 
416
555
  @property
417
- def worst_month(self: Self) -> Combo_co:
556
+ def worst_month(self: Self) -> SeriesOrFloat_co:
418
557
  """Most negative month.
419
558
 
420
559
  Returns:
421
- -------
422
- Pandas.Series[float]
423
- Most negative month
560
+ --------
561
+ SeriesOrFloat_co
562
+ Most negative month.
563
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
564
+
424
565
 
425
566
  """
426
567
  method: LiteralPandasReindexMethod = "nearest"
@@ -458,65 +599,75 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
458
599
  return self._coerce_result(result=result, name="Worst month")
459
600
 
460
601
  @property
461
- def positive_share(self: Self) -> Combo_co:
602
+ def positive_share(self: Self) -> SeriesOrFloat_co:
462
603
  """The share of percentage changes that are greater than zero.
463
604
 
464
605
  Returns:
465
- -------
466
- Combo_co
467
- The share of percentage changes that are greater than zero
606
+ --------
607
+ SeriesOrFloat_co
608
+ The share of percentage changes that are greater than zero.
609
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
610
+
468
611
 
469
612
  """
470
613
  return self.positive_share_func()
471
614
 
472
615
  @property
473
- def skew(self: Self) -> Combo_co:
616
+ def skew(self: Self) -> SeriesOrFloat_co:
474
617
  """https://www.investopedia.com/terms/s/skewness.asp.
475
618
 
476
619
  Returns:
477
- -------
478
- Combo_co
479
- Skew of the return distribution
620
+ --------
621
+ SeriesOrFloat_co
622
+ Skew of the return distribution.
623
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
624
+
480
625
 
481
626
  """
482
627
  return self.skew_func()
483
628
 
484
629
  @property
485
- def kurtosis(self: Self) -> Combo_co:
630
+ def kurtosis(self: Self) -> SeriesOrFloat_co:
486
631
  """https://www.investopedia.com/terms/k/kurtosis.asp.
487
632
 
488
633
  Returns:
489
- -------
490
- Combo_co
491
- Kurtosis of the return distribution
634
+ --------
635
+ SeriesOrFloat_co
636
+ Kurtosis of the return distribution.
637
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
638
+
492
639
 
493
640
  """
494
641
  return self.kurtosis_func()
495
642
 
496
643
  @property
497
- def cvar_down(self: Self) -> Combo_co:
644
+ def cvar_down(self: Self) -> SeriesOrFloat_co:
498
645
  """https://www.investopedia.com/terms/c/conditional_value_at_risk.asp.
499
646
 
500
647
  Returns:
501
- -------
502
- Combo_co
503
- Downside 95% Conditional Value At Risk "CVaR"
648
+ --------
649
+ SeriesOrFloat_co
650
+ Downside 95% Conditional Value At Risk "CVaR".
651
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
652
+
504
653
 
505
654
  """
506
655
  level: float = 0.95
507
656
  return self.cvar_down_func(level=level)
508
657
 
509
658
  @property
510
- def var_down(self: Self) -> Combo_co:
659
+ def var_down(self: Self) -> SeriesOrFloat_co:
511
660
  """Downside 95% Value At Risk (VaR).
512
661
 
513
662
  The equivalent of percentile.inc([...], 1-level) over returns in MS Excel.
514
663
  https://www.investopedia.com/terms/v/var.asp.
515
664
 
516
665
  Returns:
517
- -------
518
- Combo_co
519
- Downside 95% Value At Risk (VaR)
666
+ --------
667
+ SeriesOrFloat_co
668
+ Downside 95% Value At Risk (VaR).
669
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
670
+
520
671
 
521
672
  """
522
673
  level: float = 0.95
@@ -524,16 +675,17 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
524
675
  return self.var_down_func(level=level, interpolation=interpolation)
525
676
 
526
677
  @property
527
- def vol_from_var(self: Self) -> Combo_co:
678
+ def vol_from_var(self: Self) -> SeriesOrFloat_co:
528
679
  """Implied annualized volatility from Downside 95% Value at Risk.
529
680
 
530
681
  Assumes that returns are normally distributed.
531
682
 
532
683
  Returns:
533
- -------
534
- Combo_co
684
+ --------
685
+ SeriesOrFloat_co
535
686
  Implied annualized volatility from the Downside 95% VaR using the
536
687
  assumption that returns are normally distributed.
688
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
537
689
 
538
690
  """
539
691
  level: float = 0.95
@@ -559,7 +711,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
559
711
  Specific from date
560
712
 
561
713
  Returns:
562
- -------
714
+ --------
563
715
  tuple[datetime.date, datetime.date]
564
716
  Start and end date of the chosen date range
565
717
 
@@ -616,8 +768,9 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
616
768
  Argument where missing holidays can be added
617
769
  method: LiteralPandasReindexMethod, default: "nearest"
618
770
 
771
+
619
772
  Returns:
620
- -------
773
+ --------
621
774
  OpenFrame
622
775
  An OpenFrame object
623
776
 
@@ -652,7 +805,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
652
805
  calendar = holiday_calendar(
653
806
  startyear=startyear,
654
807
  endyear=endyear,
655
- countries=countries,
808
+ countries=countries or "SE",
656
809
  markets=markets,
657
810
  custom_holidays=custom_holidays,
658
811
  )
@@ -677,7 +830,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
677
830
  Equivalent to LN(value[t] / value[t=0]) in Excel.
678
831
 
679
832
  Returns:
680
- -------
833
+ --------
681
834
  self
682
835
  An object of the same class
683
836
 
@@ -698,7 +851,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
698
851
  Method used to handle NaN. Either fill with last known or drop
699
852
 
700
853
  Returns:
701
- -------
854
+ --------
702
855
  self
703
856
  An object of the same class
704
857
 
@@ -718,7 +871,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
718
871
  Method used to handle NaN. Either fill with zero or drop
719
872
 
720
873
  Returns:
721
- -------
874
+ --------
722
875
  self
723
876
  An object of the same class
724
877
 
@@ -733,7 +886,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
733
886
  """Convert timeseries into a drawdown series.
734
887
 
735
888
  Returns:
736
- -------
889
+ --------
737
890
  self
738
891
  An object of the same class
739
892
 
@@ -763,7 +916,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
763
916
  File folder location
764
917
 
765
918
  Returns:
766
- -------
919
+ --------
767
920
  list[dict[str, str | bool | ValueType | list[str] | list[float]]]
768
921
  A list of dictionaries with the data of the series
769
922
 
@@ -830,7 +983,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
830
983
  Flag whether to overwrite an existing file
831
984
 
832
985
  Returns:
833
- -------
986
+ --------
834
987
  str
835
988
  The Excel file path
836
989
 
@@ -1001,7 +1154,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1001
1154
  If True a Captor logo is added to the plot
1002
1155
 
1003
1156
  Returns:
1004
- -------
1157
+ --------
1005
1158
  tuple[plotly.go.Figure, str]
1006
1159
  Plotly Figure and a div section or a html filename with location
1007
1160
 
@@ -1098,7 +1251,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1098
1251
  If True the last self.tsdf point is highlighted as red dot with a label
1099
1252
 
1100
1253
  Returns:
1101
- -------
1254
+ --------
1102
1255
  tuple[plotly.go.Figure, str]
1103
1256
  Plotly Figure and a div section or a html filename with location
1104
1257
 
@@ -1235,7 +1388,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1235
1388
  If True a Captor logo is added to the plot
1236
1389
 
1237
1390
  Returns:
1238
- -------
1391
+ --------
1239
1392
  tuple[plotly.go.Figure, str]
1240
1393
  Plotly Figure and a div section or a html filename with location
1241
1394
 
@@ -1316,7 +1469,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1316
1469
  from_date: dt.date | None = None,
1317
1470
  to_date: dt.date | None = None,
1318
1471
  periods_in_a_year_fixed: DaysInYearType | None = None,
1319
- ) -> Combo_co:
1472
+ ) -> SeriesOrFloat_co:
1320
1473
  """https://www.investopedia.com/terms/a/arithmeticmean.asp.
1321
1474
 
1322
1475
  Parameters
@@ -1333,34 +1486,22 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1333
1486
  comparisons
1334
1487
 
1335
1488
  Returns:
1336
- -------
1337
- Combo_co
1338
- Annualized arithmetic mean of returns
1489
+ --------
1490
+ SeriesOrFloat_co
1491
+ Annualized arithmetic mean of returns.
1492
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1493
+
1339
1494
 
1340
1495
  """
1341
- earlier, later = self.calc_range(
1342
- months_offset=months_from_last,
1343
- from_dt=from_date,
1344
- to_dt=to_date,
1496
+ _earlier, _later, time_factor, data = _get_date_range_and_factor(
1497
+ self=self,
1498
+ months_from_last=months_from_last,
1499
+ from_date=from_date,
1500
+ to_date=to_date,
1501
+ periods_in_a_year_fixed=periods_in_a_year_fixed,
1345
1502
  )
1346
- if periods_in_a_year_fixed:
1347
- time_factor = float(periods_in_a_year_fixed)
1348
- else:
1349
- how_many = (
1350
- self.tsdf.loc[cast("Timestamp", earlier) : cast("Timestamp", later)]
1351
- .count()
1352
- .iloc[0]
1353
- )
1354
- fraction = (later - earlier).days / 365.25
1355
- time_factor = how_many / fraction
1356
1503
 
1357
- result = (
1358
- self.tsdf.loc[cast("Timestamp", earlier) : cast("Timestamp", later)]
1359
- .ffill()
1360
- .pct_change()
1361
- .mean()
1362
- * time_factor
1363
- )
1504
+ result = data.ffill().pct_change().mean() * time_factor
1364
1505
 
1365
1506
  return self._coerce_result(result=result, name="Arithmetic return")
1366
1507
 
@@ -1370,7 +1511,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1370
1511
  from_date: dt.date | None = None,
1371
1512
  to_date: dt.date | None = None,
1372
1513
  periods_in_a_year_fixed: DaysInYearType | None = None,
1373
- ) -> Combo_co:
1514
+ ) -> SeriesOrFloat_co:
1374
1515
  """Annualized volatility.
1375
1516
 
1376
1517
  Based on Pandas .std() which is the equivalent of stdev.s([...]) in MS Excel.
@@ -1389,28 +1530,20 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1389
1530
  Allows locking the periods-in-a-year to simplify test cases and comparisons
1390
1531
 
1391
1532
  Returns:
1392
- -------
1393
- Combo_co
1394
- Annualized volatility
1533
+ --------
1534
+ SeriesOrFloat_co
1535
+ Annualized volatility.
1536
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1395
1537
 
1396
1538
  """
1397
- earlier, later = self.calc_range(
1398
- months_offset=months_from_last,
1399
- from_dt=from_date,
1400
- to_dt=to_date,
1539
+ _earlier, _later, time_factor, data = _get_date_range_and_factor(
1540
+ self=self,
1541
+ months_from_last=months_from_last,
1542
+ from_date=from_date,
1543
+ to_date=to_date,
1544
+ periods_in_a_year_fixed=periods_in_a_year_fixed,
1401
1545
  )
1402
- if periods_in_a_year_fixed:
1403
- time_factor = float(periods_in_a_year_fixed)
1404
- else:
1405
- how_many = (
1406
- self.tsdf.loc[cast("Timestamp", earlier) : cast("Timestamp", later)]
1407
- .count()
1408
- .iloc[0]
1409
- )
1410
- fraction = (later - earlier).days / 365.25
1411
- time_factor = how_many / fraction
1412
1546
 
1413
- data = self.tsdf.loc[cast("Timestamp", earlier) : cast("Timestamp", later)]
1414
1547
  result = data.ffill().pct_change().std().mul(sqrt(time_factor))
1415
1548
 
1416
1549
  return self._coerce_result(result=result, name="Volatility")
@@ -1425,7 +1558,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1425
1558
  periods_in_a_year_fixed: DaysInYearType | None = None,
1426
1559
  *,
1427
1560
  drift_adjust: bool = False,
1428
- ) -> Combo_co:
1561
+ ) -> SeriesOrFloat_co:
1429
1562
  """Implied annualized volatility.
1430
1563
 
1431
1564
  Implied annualized volatility from the Downside VaR using the assumption
@@ -1451,10 +1584,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1451
1584
  An adjustment to remove the bias implied by the average return
1452
1585
 
1453
1586
  Returns:
1454
- -------
1455
- Combo_co
1587
+ --------
1588
+ SeriesOrFloat_co
1456
1589
  Implied annualized volatility from the Downside VaR using the
1457
1590
  assumption that returns are normally distributed.
1591
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1458
1592
 
1459
1593
  """
1460
1594
  return self._var_implied_vol_and_target_func(
@@ -1480,7 +1614,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1480
1614
  periods_in_a_year_fixed: DaysInYearType | None = None,
1481
1615
  *,
1482
1616
  drift_adjust: bool = False,
1483
- ) -> Combo_co:
1617
+ ) -> SeriesOrFloat_co:
1484
1618
  """Target weight from VaR.
1485
1619
 
1486
1620
  A position weight multiplier from the ratio between a VaR implied
@@ -1512,10 +1646,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1512
1646
  An adjustment to remove the bias implied by the average return
1513
1647
 
1514
1648
  Returns:
1515
- -------
1516
- Combo_co
1649
+ --------
1650
+ SeriesOrFloat_co
1517
1651
  A position weight multiplier from the ratio between a VaR implied
1518
- volatility and a given target volatility. Multiplier = 1.0 -> target met
1652
+ volatility and a given target volatility. Multiplier = 1.0 -> target met.
1653
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1519
1654
 
1520
1655
  """
1521
1656
  return self._var_implied_vol_and_target_func(
@@ -1544,7 +1679,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1544
1679
  periods_in_a_year_fixed: DaysInYearType | None = None,
1545
1680
  *,
1546
1681
  drift_adjust: bool = False,
1547
- ) -> Combo_co:
1682
+ ) -> SeriesOrFloat_co:
1548
1683
  """Volatility implied from VaR or Target Weight.
1549
1684
 
1550
1685
  The function returns a position weight multiplier from the ratio between
@@ -1578,10 +1713,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1578
1713
  An adjustment to remove the bias implied by the average return
1579
1714
 
1580
1715
  Returns:
1581
- -------
1582
- Combo_co
1716
+ --------
1717
+ SeriesOrFloat_co
1583
1718
  Target volatility if target_vol is provided otherwise the VaR
1584
1719
  implied volatility.
1720
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1585
1721
 
1586
1722
  """
1587
1723
  earlier, later = self.calc_range(
@@ -1647,7 +1783,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1647
1783
  months_from_last: int | None = None,
1648
1784
  from_date: dt.date | None = None,
1649
1785
  to_date: dt.date | None = None,
1650
- ) -> Combo_co:
1786
+ ) -> SeriesOrFloat_co:
1651
1787
  """Downside Conditional Value At Risk "CVaR".
1652
1788
 
1653
1789
  https://www.investopedia.com/terms/c/conditional_value_at_risk.asp.
@@ -1665,9 +1801,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1665
1801
  Specific to date
1666
1802
 
1667
1803
  Returns:
1668
- -------
1669
- Combo_co
1670
- Downside Conditional Value At Risk "CVaR"
1804
+ --------
1805
+ SeriesOrFloat_co
1806
+ Downside Conditional Value At Risk "CVaR".
1807
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1671
1808
 
1672
1809
  """
1673
1810
  earlier, later = self.calc_range(
@@ -1698,7 +1835,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1698
1835
  from_date: dt.date | None = None,
1699
1836
  to_date: dt.date | None = None,
1700
1837
  periods_in_a_year_fixed: DaysInYearType | None = None,
1701
- ) -> Combo_co:
1838
+ ) -> SeriesOrFloat_co:
1702
1839
  """Downside Deviation if order set to 2.
1703
1840
 
1704
1841
  If order is set to 2 the function calculates the standard
@@ -1724,9 +1861,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1724
1861
  comparisons
1725
1862
 
1726
1863
  Returns:
1727
- -------
1728
- Combo_co
1729
- Downside deviation if order set to 2
1864
+ --------
1865
+ SeriesOrFloat_co
1866
+ Downside deviation if order set to 2.
1867
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1730
1868
 
1731
1869
  """
1732
1870
  msg = f"'order' must be 2 or 3, got {order!r}."
@@ -1781,7 +1919,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1781
1919
  months_from_last: int | None = None,
1782
1920
  from_date: dt.date | None = None,
1783
1921
  to_date: dt.date | None = None,
1784
- ) -> Combo_co:
1922
+ ) -> SeriesOrFloat_co:
1785
1923
  """Compounded Annual Growth Rate (CAGR).
1786
1924
 
1787
1925
  https://www.investopedia.com/terms/c/cagr.asp.
@@ -1797,9 +1935,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1797
1935
  Specific to date
1798
1936
 
1799
1937
  Returns:
1800
- -------
1801
- Combo_co
1802
- Compounded Annual Growth Rate (CAGR)
1938
+ --------
1939
+ SeriesOrFloat_co
1940
+ Compounded Annual Growth Rate (CAGR).
1941
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1803
1942
 
1804
1943
  """
1805
1944
  zero = 0.0
@@ -1830,7 +1969,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1830
1969
  months_from_last: int | None = None,
1831
1970
  from_date: dt.date | None = None,
1832
1971
  to_date: dt.date | None = None,
1833
- ) -> Combo_co:
1972
+ ) -> SeriesOrFloat_co:
1834
1973
  """Skew of the return distribution.
1835
1974
 
1836
1975
  https://www.investopedia.com/terms/s/skewness.asp.
@@ -1846,9 +1985,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1846
1985
  Specific to date
1847
1986
 
1848
1987
  Returns:
1849
- -------
1850
- Combo_co
1851
- Skew of the return distribution
1988
+ --------
1989
+ SeriesOrFloat_co
1990
+ Skew of the return distribution.
1991
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1852
1992
 
1853
1993
  """
1854
1994
  earlier, later = self.calc_range(
@@ -1873,7 +2013,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1873
2013
  months_from_last: int | None = None,
1874
2014
  from_date: dt.date | None = None,
1875
2015
  to_date: dt.date | None = None,
1876
- ) -> Combo_co:
2016
+ ) -> SeriesOrFloat_co:
1877
2017
  """Kurtosis of the return distribution.
1878
2018
 
1879
2019
  https://www.investopedia.com/terms/k/kurtosis.asp.
@@ -1889,9 +2029,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1889
2029
  Specific to date
1890
2030
 
1891
2031
  Returns:
1892
- -------
1893
- Combo_co
1894
- Kurtosis of the return distribution
2032
+ --------
2033
+ SeriesOrFloat_co
2034
+ Kurtosis of the return distribution.
2035
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1895
2036
 
1896
2037
  """
1897
2038
  earlier, later = self.calc_range(
@@ -1921,7 +2062,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1921
2062
  from_date: dt.date | None = None,
1922
2063
  to_date: dt.date | None = None,
1923
2064
  min_periods: int = 1,
1924
- ) -> Combo_co:
2065
+ ) -> SeriesOrFloat_co:
1925
2066
  """Maximum drawdown without any limit on date range.
1926
2067
 
1927
2068
  https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp.
@@ -1939,9 +2080,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1939
2080
  Smallest number of observations to use to find the maximum drawdown
1940
2081
 
1941
2082
  Returns:
1942
- -------
1943
- Combo_co
1944
- Maximum drawdown without any limit on date range
2083
+ --------
2084
+ SeriesOrFloat_co
2085
+ Maximum drawdown without any limit on date range.
2086
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1945
2087
 
1946
2088
  """
1947
2089
  earlier, later = self.calc_range(
@@ -1963,7 +2105,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1963
2105
  months_from_last: int | None = None,
1964
2106
  from_date: dt.date | None = None,
1965
2107
  to_date: dt.date | None = None,
1966
- ) -> Combo_co:
2108
+ ) -> SeriesOrFloat_co:
1967
2109
  """Calculate share of percentage changes that are greater than zero.
1968
2110
 
1969
2111
  Parameters
@@ -1977,9 +2119,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
1977
2119
  Specific to date
1978
2120
 
1979
2121
  Returns:
1980
- -------
1981
- Combo_co
1982
- Calculate share of percentage changes that are greater than zero
2122
+ --------
2123
+ SeriesOrFloat_co
2124
+ Calculate share of percentage changes that are greater than zero.
2125
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
1983
2126
 
1984
2127
  """
1985
2128
  zero: float = 0.0
@@ -2016,7 +2159,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2016
2159
  from_date: dt.date | None = None,
2017
2160
  to_date: dt.date | None = None,
2018
2161
  periods_in_a_year_fixed: DaysInYearType | None = None,
2019
- ) -> Combo_co:
2162
+ ) -> SeriesOrFloat_co:
2020
2163
  """Ratio between arithmetic mean of returns and annualized volatility.
2021
2164
 
2022
2165
  The ratio of annualized arithmetic mean of returns and annualized
@@ -2041,10 +2184,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2041
2184
  comparisons
2042
2185
 
2043
2186
  Returns:
2044
- -------
2045
- Combo_co
2187
+ --------
2188
+ SeriesOrFloat_co
2046
2189
  Ratio of the annualized arithmetic mean of returns and annualized
2047
- volatility or, if risk-free return provided, Sharpe ratio
2190
+ volatility or, if risk-free return provided, Sharpe ratio.
2191
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2048
2192
 
2049
2193
  """
2050
2194
  result = Series(
@@ -2073,7 +2217,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2073
2217
  from_date: dt.date | None = None,
2074
2218
  to_date: dt.date | None = None,
2075
2219
  periods_in_a_year_fixed: DaysInYearType | None = None,
2076
- ) -> Combo_co:
2220
+ ) -> SeriesOrFloat_co:
2077
2221
  """Sortino Ratio or Kappa3 Ratio.
2078
2222
 
2079
2223
  The Sortino ratio calculated as ( return - risk free return )
@@ -2105,10 +2249,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2105
2249
  comparisons
2106
2250
 
2107
2251
  Returns:
2108
- -------
2109
- Combo_co
2252
+ --------
2253
+ SeriesOrFloat_co
2110
2254
  Sortino ratio calculated as ( return - riskfree return ) /
2111
- downside deviation (std dev of returns below MAR)
2255
+ downside deviation (std dev of returns below MAR).
2256
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2112
2257
 
2113
2258
  """
2114
2259
  result = Series(
@@ -2139,7 +2284,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2139
2284
  months_from_last: int | None = None,
2140
2285
  from_date: dt.date | None = None,
2141
2286
  to_date: dt.date | None = None,
2142
- ) -> Combo_co:
2287
+ ) -> SeriesOrFloat_co:
2143
2288
  """Omega Ratio.
2144
2289
 
2145
2290
  The Omega Ratio compares returns above a certain target level
@@ -2160,9 +2305,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2160
2305
  Specific to date
2161
2306
 
2162
2307
  Returns:
2163
- -------
2164
- Combo_co
2165
- Omega ratio calculation
2308
+ --------
2309
+ SeriesOrFloat_co
2310
+ Omega ratio calculation.
2311
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2166
2312
 
2167
2313
  """
2168
2314
  earlier, later = self.calc_range(
@@ -2186,7 +2332,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2186
2332
  months_from_last: int | None = None,
2187
2333
  from_date: dt.date | None = None,
2188
2334
  to_date: dt.date | None = None,
2189
- ) -> Combo_co:
2335
+ ) -> SeriesOrFloat_co:
2190
2336
  """Calculate simple return.
2191
2337
 
2192
2338
  Parameters
@@ -2200,9 +2346,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2200
2346
  Specific to date
2201
2347
 
2202
2348
  Returns:
2203
- -------
2204
- Combo_co
2205
- Calculate simple return
2349
+ --------
2350
+ SeriesOrFloat_co
2351
+ Calculate simple return.
2352
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2206
2353
 
2207
2354
  """
2208
2355
  zero: float = 0.0
@@ -2229,7 +2376,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2229
2376
  self: Self,
2230
2377
  year: int,
2231
2378
  month: int | None = None,
2232
- ) -> Combo_co:
2379
+ ) -> SeriesOrFloat_co:
2233
2380
  """Calculate simple return for a specific calendar period.
2234
2381
 
2235
2382
  Parameters
@@ -2240,9 +2387,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2240
2387
  Calendar month of the period to calculate.
2241
2388
 
2242
2389
  Returns:
2243
- -------
2244
- Combo_co
2245
- Calculate simple return for a specific calendar period
2390
+ --------
2391
+ SeriesOrFloat_co
2392
+ Calculate simple return for a specific calendar period.
2393
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2246
2394
 
2247
2395
  """
2248
2396
  if month is None:
@@ -2264,7 +2412,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2264
2412
  from_date: dt.date | None = None,
2265
2413
  to_date: dt.date | None = None,
2266
2414
  interpolation: LiteralQuantileInterp = "lower",
2267
- ) -> Combo_co:
2415
+ ) -> SeriesOrFloat_co:
2268
2416
  """Downside Value At Risk, "VaR".
2269
2417
 
2270
2418
  The equivalent of percentile.inc([...], 1-level) over returns in MS Excel.
@@ -2285,9 +2433,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2285
2433
  Type of interpolation in Pandas.DataFrame.quantile() function.
2286
2434
 
2287
2435
  Returns:
2288
- -------
2289
- Combo_co
2290
- Downside Value At Risk
2436
+ --------
2437
+ SeriesOrFloat_co
2438
+ Downside Value At Risk.
2439
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2291
2440
 
2292
2441
  """
2293
2442
  earlier, later = self.calc_range(
@@ -2310,7 +2459,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2310
2459
  months_from_last: int | None = None,
2311
2460
  from_date: dt.date | None = None,
2312
2461
  to_date: dt.date | None = None,
2313
- ) -> Combo_co:
2462
+ ) -> SeriesOrFloat_co:
2314
2463
  """Most negative percentage change over a rolling number of observations.
2315
2464
 
2316
2465
  Parameters
@@ -2326,10 +2475,11 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2326
2475
  Specific to date
2327
2476
 
2328
2477
  Returns:
2329
- -------
2330
- Combo_co
2478
+ --------
2479
+ SeriesOrFloat_co
2331
2480
  Most negative percentage change over a rolling number of observations
2332
- within a chosen date range
2481
+ within a chosen date range.
2482
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2333
2483
 
2334
2484
  """
2335
2485
  earlier, later = self.calc_range(
@@ -2353,7 +2503,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2353
2503
  months_from_last: int | None = None,
2354
2504
  from_date: dt.date | None = None,
2355
2505
  to_date: dt.date | None = None,
2356
- ) -> Combo_co:
2506
+ ) -> SeriesOrFloat_co:
2357
2507
  """Z-score as (last return - mean return) / standard deviation of returns.
2358
2508
 
2359
2509
  https://www.investopedia.com/terms/z/zscore.asp.
@@ -2369,9 +2519,10 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2369
2519
  Specific to date
2370
2520
 
2371
2521
  Returns:
2372
- -------
2373
- Combo_co
2374
- Z-score as (last return - mean return) / standard deviation of returns
2522
+ --------
2523
+ SeriesOrFloat_co
2524
+ Z-score as (last return - mean return) / standard deviation of returns.
2525
+ Returns float for OpenTimeSeries, Series[float] for OpenFrame.
2375
2526
 
2376
2527
  """
2377
2528
  earlier, later = self.calc_range(
@@ -2406,7 +2557,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2406
2557
  Number of observations in the overlapping window.
2407
2558
 
2408
2559
  Returns:
2409
- -------
2560
+ --------
2410
2561
  Pandas.DataFrame
2411
2562
  Calculate rolling annualized downside CVaR
2412
2563
 
@@ -2437,7 +2588,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2437
2588
  Number of observations in the overlapping window.
2438
2589
 
2439
2590
  Returns:
2440
- -------
2591
+ --------
2441
2592
  Pandas.DataFrame
2442
2593
  Calculate rolling returns
2443
2594
 
@@ -2476,7 +2627,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2476
2627
  Type of interpolation in Pandas.DataFrame.quantile() function.
2477
2628
 
2478
2629
  Returns:
2479
- -------
2630
+ --------
2480
2631
  Pandas.DataFrame
2481
2632
  Calculate rolling annualized downside Value At Risk "VaR"
2482
2633
 
@@ -2516,7 +2667,7 @@ class _CommonModel(BaseModel, Generic[Combo_co]):
2516
2667
  Variance bias factor taking the value 0 or 1.
2517
2668
 
2518
2669
  Returns:
2519
- -------
2670
+ --------
2520
2671
  Pandas.DataFrame
2521
2672
  Calculate rolling annualised volatilities
2522
2673