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.
- openseries/__init__.py +1 -8
- openseries/_common_model.py +375 -224
- openseries/_risk.py +3 -10
- openseries/datefixer.py +9 -16
- openseries/frame.py +100 -117
- openseries/load_plotly.py +3 -10
- openseries/owntypes.py +3 -10
- openseries/portfoliotools.py +19 -41
- openseries/py.typed +0 -0
- openseries/report.py +6 -12
- openseries/series.py +36 -54
- openseries/simulation.py +104 -39
- openseries-2.0.0.dist-info/METADATA +126 -0
- openseries-2.0.0.dist-info/RECORD +18 -0
- {openseries-1.9.6.dist-info → openseries-2.0.0.dist-info}/WHEEL +1 -1
- openseries-1.9.6.dist-info/METADATA +0 -369
- openseries-1.9.6.dist-info/RECORD +0 -17
- {openseries-1.9.6.dist-info → openseries-2.0.0.dist-info}/licenses/LICENSE.md +0 -0
openseries/_common_model.py
CHANGED
@@ -1,10 +1,6 @@
|
|
1
|
-
"""
|
1
|
+
"""The _CommonModel class.
|
2
2
|
|
3
|
-
|
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
|
-
|
91
|
-
|
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(
|
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("
|
222
|
+
return cast("SeriesOrFloat_co", arr) # type: ignore[redundant-cast]
|
106
223
|
return cast(
|
107
|
-
"
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
357
|
+
def value_ret(self: Self) -> SeriesOrFloat_co:
|
236
358
|
"""Simple return.
|
237
359
|
|
238
360
|
Returns:
|
239
|
-
|
240
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
473
|
+
def omega_ratio(self: Self) -> SeriesOrFloat_co:
|
343
474
|
"""https://en.wikipedia.org/wiki/Omega_ratio.
|
344
475
|
|
345
476
|
Returns:
|
346
|
-
|
347
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
541
|
+
def worst(self: Self) -> SeriesOrFloat_co:
|
405
542
|
"""Most negative percentage change.
|
406
543
|
|
407
544
|
Returns:
|
408
|
-
|
409
|
-
|
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) ->
|
556
|
+
def worst_month(self: Self) -> SeriesOrFloat_co:
|
418
557
|
"""Most negative month.
|
419
558
|
|
420
559
|
Returns:
|
421
|
-
|
422
|
-
|
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) ->
|
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
|
-
|
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) ->
|
616
|
+
def skew(self: Self) -> SeriesOrFloat_co:
|
474
617
|
"""https://www.investopedia.com/terms/s/skewness.asp.
|
475
618
|
|
476
619
|
Returns:
|
477
|
-
|
478
|
-
|
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) ->
|
630
|
+
def kurtosis(self: Self) -> SeriesOrFloat_co:
|
486
631
|
"""https://www.investopedia.com/terms/k/kurtosis.asp.
|
487
632
|
|
488
633
|
Returns:
|
489
|
-
|
490
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
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
|
-
) ->
|
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
|
-
|
1394
|
-
Annualized volatility
|
1533
|
+
--------
|
1534
|
+
SeriesOrFloat_co
|
1535
|
+
Annualized volatility.
|
1536
|
+
Returns float for OpenTimeSeries, Series[float] for OpenFrame.
|
1395
1537
|
|
1396
1538
|
"""
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
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
|
-
|
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
|
|