openseries 1.3.8__py3-none-any.whl → 1.3.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openseries/common_model.py +52 -44
- openseries/datefixer.py +7 -6
- openseries/frame.py +36 -29
- openseries/load_plotly.py +2 -1
- openseries/series.py +16 -11
- openseries/simulation.py +4 -8
- {openseries-1.3.8.dist-info → openseries-1.3.9.dist-info}/METADATA +4 -4
- openseries-1.3.9.dist-info/RECORD +15 -0
- openseries-1.3.8.dist-info/RECORD +0 -15
- {openseries-1.3.8.dist-info → openseries-1.3.9.dist-info}/LICENSE.md +0 -0
- {openseries-1.3.8.dist-info → openseries-1.3.9.dist-info}/WHEEL +0 -0
openseries/common_model.py
CHANGED
@@ -12,8 +12,9 @@ from string import ascii_letters
|
|
12
12
|
from typing import Any, Optional, Union, cast
|
13
13
|
|
14
14
|
from numpy import log, sqrt
|
15
|
-
from openpyxl import Workbook
|
16
15
|
from openpyxl.utils.dataframe import dataframe_to_rows
|
16
|
+
from openpyxl.workbook.workbook import Workbook
|
17
|
+
from openpyxl.worksheet.worksheet import Worksheet
|
17
18
|
from pandas import DataFrame, DatetimeIndex, Series
|
18
19
|
from plotly.graph_objs import Figure # type: ignore[import-untyped]
|
19
20
|
from plotly.offline import plot # type: ignore[import-untyped]
|
@@ -24,6 +25,7 @@ from openseries.datefixer import get_calc_range
|
|
24
25
|
from openseries.load_plotly import load_plotly_dict
|
25
26
|
from openseries.risk import cvar_down_calc, drawdown_series, var_down_calc
|
26
27
|
from openseries.types import (
|
28
|
+
DaysInYearType,
|
27
29
|
LiteralBarPlotMode,
|
28
30
|
LiteralLinePlotMode,
|
29
31
|
LiteralNanMethod,
|
@@ -503,7 +505,8 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
503
505
|
filename: str,
|
504
506
|
sheet_title: Optional[str] = None,
|
505
507
|
directory: Optional[DirectoryPath] = None,
|
506
|
-
|
508
|
+
*,
|
509
|
+
overwrite: bool = True,
|
507
510
|
) -> str:
|
508
511
|
"""
|
509
512
|
Save .tsdf DataFrame to an Excel spreadsheet file.
|
@@ -541,10 +544,10 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
541
544
|
wrksheet = wrkbook.active
|
542
545
|
|
543
546
|
if sheet_title:
|
544
|
-
wrksheet.title = sheet_title
|
547
|
+
cast(Worksheet, wrksheet).title = sheet_title
|
545
548
|
|
546
549
|
for row in dataframe_to_rows(df=self.tsdf, index=True, header=True):
|
547
|
-
wrksheet.append(row)
|
550
|
+
cast(Worksheet, wrksheet).append(row)
|
548
551
|
|
549
552
|
if not overwrite and Path(sheetfile).exists():
|
550
553
|
msg = f"{sheetfile!s} already exists."
|
@@ -561,9 +564,10 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
561
564
|
filename: Optional[str] = None,
|
562
565
|
directory: Optional[DirectoryPath] = None,
|
563
566
|
labels: Optional[list[str]] = None,
|
564
|
-
auto_open: bool = True, # noqa: FBT001, FBT002
|
565
|
-
add_logo: bool = True, # noqa: FBT001, FBT002
|
566
567
|
output_type: LiteralPlotlyOutput = "file",
|
568
|
+
*,
|
569
|
+
auto_open: bool = True,
|
570
|
+
add_logo: bool = True,
|
567
571
|
) -> tuple[Figure, str]:
|
568
572
|
"""
|
569
573
|
Create a Plotly Bar Figure.
|
@@ -583,12 +587,12 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
583
587
|
labels: list[str], optional
|
584
588
|
A list of labels to manually override using the names of
|
585
589
|
the input self.tsdf
|
590
|
+
output_type: LiteralPlotlyOutput, default: "file"
|
591
|
+
Determines output type
|
586
592
|
auto_open: bool, default: True
|
587
593
|
Determines whether to open a browser window with the plot
|
588
594
|
add_logo: bool, default: True
|
589
595
|
If True a Captor logo is added to the plot
|
590
|
-
output_type: LiteralPlotlyOutput, default: "file"
|
591
|
-
Determines output type
|
592
596
|
|
593
597
|
Returns
|
594
598
|
-------
|
@@ -655,10 +659,11 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
655
659
|
filename: Optional[str] = None,
|
656
660
|
directory: Optional[DirectoryPath] = None,
|
657
661
|
labels: Optional[list[str]] = None,
|
658
|
-
auto_open: bool = True, # noqa: FBT001, FBT002
|
659
|
-
add_logo: bool = True, # noqa: FBT001, FBT002
|
660
|
-
show_last: bool = False, # noqa: FBT001, FBT002
|
661
662
|
output_type: LiteralPlotlyOutput = "file",
|
663
|
+
*,
|
664
|
+
auto_open: bool = True,
|
665
|
+
add_logo: bool = True,
|
666
|
+
show_last: bool = False,
|
662
667
|
) -> tuple[Figure, str]:
|
663
668
|
"""
|
664
669
|
Create a Plotly Scatter Figure.
|
@@ -678,14 +683,14 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
678
683
|
labels: list[str], optional
|
679
684
|
A list of labels to manually override using the names of
|
680
685
|
the input self.tsdf
|
686
|
+
output_type: LiteralPlotlyOutput, default: "file"
|
687
|
+
Determines output type
|
681
688
|
auto_open: bool, default: True
|
682
689
|
Determines whether to open a browser window with the plot
|
683
690
|
add_logo: bool, default: True
|
684
691
|
If True a Captor logo is added to the plot
|
685
692
|
show_last: bool, default: False
|
686
693
|
If True the last self.tsdf point is highlighted as red dot with a label
|
687
|
-
output_type: LiteralPlotlyOutput, default: "file"
|
688
|
-
Determines output type
|
689
694
|
|
690
695
|
Returns
|
691
696
|
-------
|
@@ -765,7 +770,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
765
770
|
months_from_last: Optional[int] = None,
|
766
771
|
from_date: Optional[dt.date] = None,
|
767
772
|
to_date: Optional[dt.date] = None,
|
768
|
-
periods_in_a_year_fixed: Optional[
|
773
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
769
774
|
) -> Union[float, Series[type[float]]]:
|
770
775
|
"""
|
771
776
|
https://www.investopedia.com/terms/a/arithmeticmean.asp.
|
@@ -779,7 +784,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
779
784
|
Specific from date
|
780
785
|
to_date : datetime.date, optional
|
781
786
|
Specific to date
|
782
|
-
periods_in_a_year_fixed :
|
787
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
783
788
|
Allows locking the periods-in-a-year to simplify test cases and
|
784
789
|
comparisons
|
785
790
|
|
@@ -825,8 +830,8 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
825
830
|
months_from_last: Optional[int] = None,
|
826
831
|
from_date: Optional[dt.date] = None,
|
827
832
|
to_date: Optional[dt.date] = None,
|
828
|
-
periods_in_a_year_fixed: Optional[
|
829
|
-
) -> Union[float, Series
|
833
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
834
|
+
) -> Union[float, Series[type[float]]]:
|
830
835
|
"""
|
831
836
|
Annualized volatility.
|
832
837
|
|
@@ -842,7 +847,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
842
847
|
Specific from date
|
843
848
|
to_date : datetime.date, optional
|
844
849
|
Specific to date
|
845
|
-
periods_in_a_year_fixed :
|
850
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
846
851
|
Allows locking the periods-in-a-year to simplify test cases and comparisons
|
847
852
|
|
848
853
|
Returns
|
@@ -865,9 +870,9 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
865
870
|
)
|
866
871
|
time_factor = how_many / fraction
|
867
872
|
|
868
|
-
|
869
|
-
|
870
|
-
result =
|
873
|
+
data = self.tsdf.loc[cast(int, earlier) : cast(int, later)]
|
874
|
+
data = data.ffill()
|
875
|
+
result = data.pct_change().std().mul(sqrt(time_factor))
|
871
876
|
|
872
877
|
if self.tsdf.shape[1] == 1:
|
873
878
|
return float(result.iloc[0])
|
@@ -885,8 +890,9 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
885
890
|
from_date: Optional[dt.date] = None,
|
886
891
|
to_date: Optional[dt.date] = None,
|
887
892
|
interpolation: LiteralQuantileInterp = "lower",
|
888
|
-
|
889
|
-
|
893
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
894
|
+
*,
|
895
|
+
drift_adjust: bool = False,
|
890
896
|
) -> Union[float, Series[type[float]]]:
|
891
897
|
"""
|
892
898
|
Implied annualized volatility.
|
@@ -907,11 +913,11 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
907
913
|
Specific to date
|
908
914
|
interpolation: LiteralQuantileInterp, default: "lower"
|
909
915
|
type of interpolation in Pandas.DataFrame.quantile() function.
|
910
|
-
|
911
|
-
An adjustment to remove the bias implied by the average return
|
912
|
-
periods_in_a_year_fixed : int, optional
|
916
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
913
917
|
Allows locking the periods-in-a-year to simplify test cases and
|
914
918
|
comparisons
|
919
|
+
drift_adjust: bool, default: False
|
920
|
+
An adjustment to remove the bias implied by the average return
|
915
921
|
|
916
922
|
Returns
|
917
923
|
-------
|
@@ -940,8 +946,9 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
940
946
|
from_date: Optional[dt.date] = None,
|
941
947
|
to_date: Optional[dt.date] = None,
|
942
948
|
interpolation: LiteralQuantileInterp = "lower",
|
943
|
-
|
944
|
-
|
949
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
950
|
+
*,
|
951
|
+
drift_adjust: bool = False,
|
945
952
|
) -> Union[float, Series[type[float]]]:
|
946
953
|
"""
|
947
954
|
Target weight from VaR.
|
@@ -968,11 +975,11 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
968
975
|
Specific to date
|
969
976
|
interpolation: LiteralQuantileInterp, default: "lower"
|
970
977
|
type of interpolation in Pandas.DataFrame.quantile() function.
|
971
|
-
|
972
|
-
An adjustment to remove the bias implied by the average return
|
973
|
-
periods_in_a_year_fixed : int, optional
|
978
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
974
979
|
Allows locking the periods-in-a-year to simplify test cases and
|
975
980
|
comparisons
|
981
|
+
drift_adjust: bool, default: False
|
982
|
+
An adjustment to remove the bias implied by the average return
|
976
983
|
|
977
984
|
Returns
|
978
985
|
-------
|
@@ -1064,7 +1071,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1064
1071
|
months_from_last: Optional[int] = None,
|
1065
1072
|
from_date: Optional[dt.date] = None,
|
1066
1073
|
to_date: Optional[dt.date] = None,
|
1067
|
-
periods_in_a_year_fixed: Optional[
|
1074
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1068
1075
|
) -> Union[float, Series[type[float]]]:
|
1069
1076
|
"""
|
1070
1077
|
Downside Deviation.
|
@@ -1084,7 +1091,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1084
1091
|
Specific from date
|
1085
1092
|
to_date : datetime.date, optional
|
1086
1093
|
Specific to date
|
1087
|
-
periods_in_a_year_fixed :
|
1094
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1088
1095
|
Allows locking the periods-in-a-year to simplify test cases and
|
1089
1096
|
comparisons
|
1090
1097
|
|
@@ -1424,7 +1431,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1424
1431
|
months_from_last: Optional[int] = None,
|
1425
1432
|
from_date: Optional[dt.date] = None,
|
1426
1433
|
to_date: Optional[dt.date] = None,
|
1427
|
-
periods_in_a_year_fixed: Optional[
|
1434
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1428
1435
|
) -> Union[float, Series[type[float]]]:
|
1429
1436
|
"""
|
1430
1437
|
Ratio between arithmetic mean of returns and annualized volatility.
|
@@ -1446,7 +1453,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1446
1453
|
Specific from date
|
1447
1454
|
to_date : datetime.date, optional
|
1448
1455
|
Specific to date
|
1449
|
-
periods_in_a_year_fixed :
|
1456
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1450
1457
|
Allows locking the periods-in-a-year to simplify test cases and
|
1451
1458
|
comparisons
|
1452
1459
|
|
@@ -1484,7 +1491,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1484
1491
|
months_from_last: Optional[int] = None,
|
1485
1492
|
from_date: Optional[dt.date] = None,
|
1486
1493
|
to_date: Optional[dt.date] = None,
|
1487
|
-
periods_in_a_year_fixed: Optional[
|
1494
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1488
1495
|
) -> Union[float, Series[type[float]]]:
|
1489
1496
|
"""
|
1490
1497
|
Sortino Ratio.
|
@@ -1508,7 +1515,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1508
1515
|
Specific from date
|
1509
1516
|
to_date : datetime.date, optional
|
1510
1517
|
Specific to date
|
1511
|
-
periods_in_a_year_fixed :
|
1518
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1512
1519
|
Allows locking the periods-in-a-year to simplify test cases and
|
1513
1520
|
comparisons
|
1514
1521
|
|
@@ -1889,7 +1896,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1889
1896
|
self: CommonModel,
|
1890
1897
|
column: int = 0,
|
1891
1898
|
observations: int = 21,
|
1892
|
-
periods_in_a_year_fixed: Optional[
|
1899
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1893
1900
|
) -> DataFrame:
|
1894
1901
|
"""
|
1895
1902
|
Calculate rolling annualised volatilities.
|
@@ -1900,7 +1907,7 @@ class CommonModel(BaseModel): # type: ignore[misc]
|
|
1900
1907
|
Position as integer of column to calculate
|
1901
1908
|
observations: int, default: 21
|
1902
1909
|
Number of observations in the overlapping window.
|
1903
|
-
periods_in_a_year_fixed :
|
1910
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1904
1911
|
Allows locking the periods-in-a-year to simplify test cases and
|
1905
1912
|
comparisons
|
1906
1913
|
|
@@ -1940,8 +1947,9 @@ def _var_implied_vol_and_target_func(
|
|
1940
1947
|
from_date: Optional[dt.date] = None,
|
1941
1948
|
to_date: Optional[dt.date] = None,
|
1942
1949
|
interpolation: LiteralQuantileInterp = "lower",
|
1943
|
-
|
1944
|
-
|
1950
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1951
|
+
*,
|
1952
|
+
drift_adjust: bool = False,
|
1945
1953
|
) -> Union[float, Series[type[float]]]:
|
1946
1954
|
"""
|
1947
1955
|
Volatility implied from VaR or Target Weight.
|
@@ -1972,11 +1980,11 @@ def _var_implied_vol_and_target_func(
|
|
1972
1980
|
Specific to date
|
1973
1981
|
interpolation: LiteralQuantileInterp, default: "lower"
|
1974
1982
|
type of interpolation in Pandas.DataFrame.quantile() function.
|
1975
|
-
|
1976
|
-
An adjustment to remove the bias implied by the average return
|
1977
|
-
periods_in_a_year_fixed : int, optional
|
1983
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1978
1984
|
Allows locking the periods-in-a-year to simplify test cases and
|
1979
1985
|
comparisons
|
1986
|
+
drift_adjust: bool, default: False
|
1987
|
+
An adjustment to remove the bias implied by the average return
|
1980
1988
|
|
1981
1989
|
Returns
|
1982
1990
|
-------
|
openseries/datefixer.py
CHANGED
@@ -124,10 +124,11 @@ def date_fix(
|
|
124
124
|
def date_offset_foll(
|
125
125
|
raw_date: DateType,
|
126
126
|
months_offset: int = 12,
|
127
|
-
adjust: bool = False, # noqa: FBT001, FBT002
|
128
|
-
following: bool = True, # noqa: FBT001, FBT002
|
129
127
|
countries: CountriesType = "SE",
|
130
128
|
custom_holidays: Optional[HolidayType] = None,
|
129
|
+
*,
|
130
|
+
adjust: bool = False,
|
131
|
+
following: bool = True,
|
131
132
|
) -> dt.date:
|
132
133
|
"""
|
133
134
|
Offset dates according to a given calendar.
|
@@ -138,15 +139,15 @@ def date_offset_foll(
|
|
138
139
|
The date to offset from
|
139
140
|
months_offset: int, default: 12
|
140
141
|
Number of months as integer
|
141
|
-
adjust: bool, default: False
|
142
|
-
Determines if offset should adjust for business days
|
143
|
-
following: bool, default: True
|
144
|
-
Determines if days should be offset forward (following) or backward
|
145
142
|
countries: CountriesType, default: "SE"
|
146
143
|
(List of) country code(s) according to ISO 3166-1 alpha-2
|
147
144
|
custom_holidays: HolidayType, optional
|
148
145
|
Argument where missing holidays can be added as
|
149
146
|
{"2021-02-12": "Jack's birthday"} or ["2021-02-12"]
|
147
|
+
adjust: bool, default: False
|
148
|
+
Determines if offset should adjust for business days
|
149
|
+
following: bool, default: True
|
150
|
+
Determines if days should be offset forward (following) or backward
|
150
151
|
|
151
152
|
Returns
|
152
153
|
-------
|
openseries/frame.py
CHANGED
@@ -44,6 +44,7 @@ from openseries.risk import (
|
|
44
44
|
from openseries.series import OpenTimeSeries
|
45
45
|
from openseries.types import (
|
46
46
|
CountriesType,
|
47
|
+
DaysInYearType,
|
47
48
|
LiteralBizDayFreq,
|
48
49
|
LiteralCaptureRatio,
|
49
50
|
LiteralCovMethod,
|
@@ -70,7 +71,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
70
71
|
|
71
72
|
Parameters
|
72
73
|
----------
|
73
|
-
constituents: list[
|
74
|
+
constituents: list[OpenTimeSeries]
|
74
75
|
List of objects of Class OpenTimeSeries
|
75
76
|
weights: list[float], optional
|
76
77
|
List of weights in float format.
|
@@ -110,7 +111,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
110
111
|
|
111
112
|
Parameters
|
112
113
|
----------
|
113
|
-
constituents: list[
|
114
|
+
constituents: list[OpenTimeSeries]
|
114
115
|
List of objects of Class OpenTimeSeries
|
115
116
|
weights: list[float], optional
|
116
117
|
List of weights in float format.
|
@@ -254,6 +255,11 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
254
255
|
"""
|
255
256
|
Align the index of .tsdf with local calendar business days.
|
256
257
|
|
258
|
+
Parameters
|
259
|
+
----------
|
260
|
+
countries: CountriesType, default: "SE"
|
261
|
+
(List of) country code(s) according to ISO 3166-1 alpha-2
|
262
|
+
|
257
263
|
Returns
|
258
264
|
-------
|
259
265
|
OpenFrame
|
@@ -307,13 +313,13 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
307
313
|
return list(self.tsdf.columns.get_level_values(0))
|
308
314
|
|
309
315
|
@property
|
310
|
-
def columns_lvl_one(self: OpenFrame) -> list[
|
316
|
+
def columns_lvl_one(self: OpenFrame) -> list[ValueType]:
|
311
317
|
"""
|
312
318
|
Level 1 values of the MultiIndex columns in the .tsdf DataFrame.
|
313
319
|
|
314
320
|
Returns
|
315
321
|
-------
|
316
|
-
list[
|
322
|
+
list[ValueType]
|
317
323
|
Level 1 values of the MultiIndex columns in the .tsdf DataFrame
|
318
324
|
"""
|
319
325
|
return list(self.tsdf.columns.get_level_values(1))
|
@@ -589,7 +595,6 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
589
595
|
----------
|
590
596
|
freq: Union[LiteralBizDayFreq, str], default "BM"
|
591
597
|
The date offset string that sets the resampled frequency
|
592
|
-
Examples are "7D", "B", "M", "BM", "Q", "BQ", "A", "BA"
|
593
598
|
|
594
599
|
Returns
|
595
600
|
-------
|
@@ -624,7 +629,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
624
629
|
|
625
630
|
Parameters
|
626
631
|
----------
|
627
|
-
freq: LiteralBizDayFreq, default BM
|
632
|
+
freq: LiteralBizDayFreq, default "BM"
|
628
633
|
The date offset string that sets the resampled frequency
|
629
634
|
countries: CountriesType, default: "SE"
|
630
635
|
(List of) country code(s) according to ISO 3166-1 alpha-2
|
@@ -694,7 +699,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
694
699
|
months_from_last: Optional[int] = None,
|
695
700
|
from_date: Optional[dt.date] = None,
|
696
701
|
to_date: Optional[dt.date] = None,
|
697
|
-
periods_in_a_year_fixed: Optional[
|
702
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
698
703
|
) -> DataFrame:
|
699
704
|
"""
|
700
705
|
Exponentially Weighted Moving Average Volatilities and Correlation.
|
@@ -721,7 +726,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
721
726
|
Specific from date
|
722
727
|
to_date : datetime.date, optional
|
723
728
|
Specific to date
|
724
|
-
periods_in_a_year_fixed :
|
729
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
725
730
|
Allows locking the periods-in-a-year to simplify test cases and
|
726
731
|
comparisons
|
727
732
|
|
@@ -753,30 +758,30 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
753
758
|
data = self.tsdf.loc[cast(int, earlier) : cast(int, later)].copy()
|
754
759
|
|
755
760
|
for rtn in cols:
|
756
|
-
data[rtn,
|
761
|
+
data[rtn, ValueType.RTRN] = (
|
757
762
|
data.loc[:, (rtn, ValueType.PRICE)] # type: ignore[index]
|
758
763
|
.apply(log)
|
759
764
|
.diff()
|
760
765
|
)
|
761
766
|
|
762
767
|
raw_one = [
|
763
|
-
data.loc[:, (cols[0],
|
768
|
+
data.loc[:, (cols[0], ValueType.RTRN)] # type: ignore[index]
|
764
769
|
.iloc[1:day_chunk]
|
765
770
|
.std(ddof=dlta_degr_freedms)
|
766
771
|
* sqrt(time_factor),
|
767
772
|
]
|
768
773
|
raw_two = [
|
769
|
-
data.loc[:, (cols[1],
|
774
|
+
data.loc[:, (cols[1], ValueType.RTRN)] # type: ignore[index]
|
770
775
|
.iloc[1:day_chunk]
|
771
776
|
.std(ddof=dlta_degr_freedms)
|
772
777
|
* sqrt(time_factor),
|
773
778
|
]
|
774
779
|
raw_cov = [
|
775
780
|
cov(
|
776
|
-
m=data.loc[:, (cols[0],
|
781
|
+
m=data.loc[:, (cols[0], ValueType.RTRN)] # type: ignore[index]
|
777
782
|
.iloc[1:day_chunk]
|
778
783
|
.to_numpy(),
|
779
|
-
y=data.loc[:, (cols[1],
|
784
|
+
y=data.loc[:, (cols[1], ValueType.RTRN)] # type: ignore[index]
|
780
785
|
.iloc[1:day_chunk]
|
781
786
|
.to_numpy(),
|
782
787
|
ddof=dlta_degr_freedms,
|
@@ -786,20 +791,20 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
786
791
|
|
787
792
|
for _, row in data.iloc[1:].iterrows():
|
788
793
|
tmp_raw_one = ewma_calc(
|
789
|
-
reeturn=row.loc[cols[0],
|
794
|
+
reeturn=row.loc[cols[0], ValueType.RTRN],
|
790
795
|
prev_ewma=raw_one[-1],
|
791
796
|
time_factor=time_factor,
|
792
797
|
lmbda=lmbda,
|
793
798
|
)
|
794
799
|
tmp_raw_two = ewma_calc(
|
795
|
-
reeturn=row.loc[cols[1],
|
800
|
+
reeturn=row.loc[cols[1], ValueType.RTRN],
|
796
801
|
prev_ewma=raw_two[-1],
|
797
802
|
time_factor=time_factor,
|
798
803
|
lmbda=lmbda,
|
799
804
|
)
|
800
805
|
tmp_raw_cov = (
|
801
|
-
row.loc[cols[0],
|
802
|
-
* row.loc[cols[1],
|
806
|
+
row.loc[cols[0], ValueType.RTRN]
|
807
|
+
* row.loc[cols[1], ValueType.RTRN]
|
803
808
|
* time_factor
|
804
809
|
* (1 - lmbda)
|
805
810
|
+ raw_cov[-1] * lmbda
|
@@ -941,7 +946,8 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
941
946
|
self: OpenFrame,
|
942
947
|
long_column: int = 0,
|
943
948
|
short_column: int = 1,
|
944
|
-
|
949
|
+
*,
|
950
|
+
base_zero: bool = True,
|
945
951
|
) -> None:
|
946
952
|
"""
|
947
953
|
Calculate cumulative relative return between two series.
|
@@ -979,7 +985,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
979
985
|
months_from_last: Optional[int] = None,
|
980
986
|
from_date: Optional[dt.date] = None,
|
981
987
|
to_date: Optional[dt.date] = None,
|
982
|
-
periods_in_a_year_fixed: Optional[
|
988
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
983
989
|
) -> Series[type[float]]:
|
984
990
|
"""
|
985
991
|
Tracking Error.
|
@@ -999,7 +1005,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
999
1005
|
Specific from date
|
1000
1006
|
to_date : datetime.date, optional
|
1001
1007
|
Specific to date
|
1002
|
-
periods_in_a_year_fixed :
|
1008
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1003
1009
|
Allows locking the periods-in-a-year to simplify test cases and
|
1004
1010
|
comparisons
|
1005
1011
|
|
@@ -1064,7 +1070,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1064
1070
|
months_from_last: Optional[int] = None,
|
1065
1071
|
from_date: Optional[dt.date] = None,
|
1066
1072
|
to_date: Optional[dt.date] = None,
|
1067
|
-
periods_in_a_year_fixed: Optional[
|
1073
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1068
1074
|
) -> Series[type[float]]:
|
1069
1075
|
"""
|
1070
1076
|
Information Ratio.
|
@@ -1085,7 +1091,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1085
1091
|
Specific from date
|
1086
1092
|
to_date : datetime.date, optional
|
1087
1093
|
Specific to date
|
1088
|
-
periods_in_a_year_fixed :
|
1094
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1089
1095
|
Allows locking the periods-in-a-year to simplify test cases and
|
1090
1096
|
comparisons
|
1091
1097
|
|
@@ -1158,7 +1164,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1158
1164
|
months_from_last: Optional[int] = None,
|
1159
1165
|
from_date: Optional[dt.date] = None,
|
1160
1166
|
to_date: Optional[dt.date] = None,
|
1161
|
-
periods_in_a_year_fixed: Optional[
|
1167
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1162
1168
|
) -> Series[type[float]]:
|
1163
1169
|
"""
|
1164
1170
|
Capture Ratio.
|
@@ -1185,7 +1191,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1185
1191
|
Specific from date
|
1186
1192
|
to_date : datetime.date, optional
|
1187
1193
|
Specific to date
|
1188
|
-
periods_in_a_year_fixed :
|
1194
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1189
1195
|
Allows locking the periods-in-a-year to simplify test cases and
|
1190
1196
|
comparisons
|
1191
1197
|
|
@@ -1430,9 +1436,10 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1430
1436
|
self: OpenFrame,
|
1431
1437
|
y_column: Union[tuple[str, ValueType], int],
|
1432
1438
|
x_column: Union[tuple[str, ValueType], int],
|
1433
|
-
fitted_series: bool = True, # noqa: FBT001, FBT002
|
1434
1439
|
method: LiteralOlsFitMethod = "pinv",
|
1435
1440
|
cov_type: LiteralOlsFitCovType = "nonrobust",
|
1441
|
+
*,
|
1442
|
+
fitted_series: bool = True,
|
1436
1443
|
) -> RegressionResults:
|
1437
1444
|
"""
|
1438
1445
|
Ordinary Least Squares fit.
|
@@ -1447,12 +1454,12 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1447
1454
|
The column level values of the dependent variable y
|
1448
1455
|
x_column: Union[tuple[str, ValueType], int]
|
1449
1456
|
The column level values of the exogenous variable x
|
1450
|
-
fitted_series: bool, default: True
|
1451
|
-
If True the fit is added as a new column in the .tsdf Pandas.DataFrame
|
1452
1457
|
method: LiteralOlsFitMethod, default: pinv
|
1453
1458
|
Method to solve least squares problem
|
1454
1459
|
cov_type: LiteralOlsFitCovType, default: nonrobust
|
1455
1460
|
Covariance estimator
|
1461
|
+
fitted_series: bool, default: True
|
1462
|
+
If True the fit is added as a new column in the .tsdf Pandas.DataFrame
|
1456
1463
|
|
1457
1464
|
Returns
|
1458
1465
|
-------
|
@@ -1599,7 +1606,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1599
1606
|
long_column: int = 0,
|
1600
1607
|
short_column: int = 1,
|
1601
1608
|
observations: int = 21,
|
1602
|
-
periods_in_a_year_fixed: Optional[
|
1609
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
1603
1610
|
) -> DataFrame:
|
1604
1611
|
"""
|
1605
1612
|
Calculate rolling Information Ratio.
|
@@ -1616,7 +1623,7 @@ class OpenFrame(CommonModel): # type: ignore[misc]
|
|
1616
1623
|
Column of timeseries that is the denominator in the ratio.
|
1617
1624
|
observations: int, default: 21
|
1618
1625
|
The length of the rolling window to use is set as number of observations.
|
1619
|
-
periods_in_a_year_fixed :
|
1626
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
1620
1627
|
Allows locking the periods-in-a-year to simplify test cases and comparisons
|
1621
1628
|
|
1622
1629
|
Returns
|
openseries/load_plotly.py
CHANGED
openseries/series.py
CHANGED
@@ -43,6 +43,7 @@ from openseries.types import (
|
|
43
43
|
CurrencyStringType,
|
44
44
|
DatabaseIdStringType,
|
45
45
|
DateListType,
|
46
|
+
DaysInYearType,
|
46
47
|
LiteralBizDayFreq,
|
47
48
|
LiteralPandasReindexMethod,
|
48
49
|
LiteralPandasResampleConvention,
|
@@ -163,7 +164,8 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
163
164
|
instrument_id: DatabaseIdStringType = "",
|
164
165
|
isin: Optional[str] = None,
|
165
166
|
baseccy: CurrencyStringType = "SEK",
|
166
|
-
|
167
|
+
*,
|
168
|
+
local_ccy: bool = True,
|
167
169
|
) -> OpenTimeSeries:
|
168
170
|
"""
|
169
171
|
Create series from a Pandas DataFrame or Series.
|
@@ -220,7 +222,8 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
220
222
|
column_nmbr: int = 0,
|
221
223
|
valuetype: ValueType = ValueType.PRICE,
|
222
224
|
baseccy: CurrencyStringType = "SEK",
|
223
|
-
|
225
|
+
*,
|
226
|
+
local_ccy: bool = True,
|
224
227
|
) -> OpenTimeSeries:
|
225
228
|
"""
|
226
229
|
Create series from a Pandas DataFrame or Series.
|
@@ -302,7 +305,8 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
302
305
|
label: str = "Series",
|
303
306
|
valuetype: ValueType = ValueType.PRICE,
|
304
307
|
baseccy: CurrencyStringType = "SEK",
|
305
|
-
|
308
|
+
*,
|
309
|
+
local_ccy: bool = True,
|
306
310
|
) -> OpenTimeSeries:
|
307
311
|
"""
|
308
312
|
Create series from values accruing with a given fixed rate return.
|
@@ -683,7 +687,7 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
683
687
|
months_from_last: Optional[int] = None,
|
684
688
|
from_date: Optional[dt.date] = None,
|
685
689
|
to_date: Optional[dt.date] = None,
|
686
|
-
periods_in_a_year_fixed: Optional[
|
690
|
+
periods_in_a_year_fixed: Optional[DaysInYearType] = None,
|
687
691
|
) -> DataFrame:
|
688
692
|
"""
|
689
693
|
Exponentially Weighted Moving Average Model for Volatility.
|
@@ -705,7 +709,7 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
705
709
|
Specific from date
|
706
710
|
to_date : datetime.date, optional
|
707
711
|
Specific to date
|
708
|
-
periods_in_a_year_fixed :
|
712
|
+
periods_in_a_year_fixed : DaysInYearType, optional
|
709
713
|
Allows locking the periods-in-a-year to simplify test cases and comparisons
|
710
714
|
|
711
715
|
Returns
|
@@ -726,18 +730,18 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
726
730
|
|
727
731
|
data = self.tsdf.loc[cast(int, earlier) : cast(int, later)].copy()
|
728
732
|
|
729
|
-
data[self.label,
|
733
|
+
data[self.label, ValueType.RTRN] = (
|
730
734
|
data.loc[:, self.tsdf.columns.to_numpy()[0]].apply(log).diff()
|
731
735
|
)
|
732
736
|
|
733
737
|
rawdata = [
|
734
|
-
data.loc[:, (self.label,
|
738
|
+
data.loc[:, (self.label, ValueType.RTRN)] # type: ignore[index]
|
735
739
|
.iloc[1:day_chunk]
|
736
740
|
.std(ddof=dlta_degr_freedms)
|
737
741
|
* sqrt(time_factor),
|
738
742
|
]
|
739
743
|
|
740
|
-
for item in data.loc[:, (self.label,
|
744
|
+
for item in data.loc[:, (self.label, ValueType.RTRN)].iloc[ # type: ignore[index]
|
741
745
|
1:
|
742
746
|
]:
|
743
747
|
previous = rawdata[-1]
|
@@ -817,7 +821,8 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
817
821
|
self: OpenTimeSeries,
|
818
822
|
lvl_zero: Optional[str] = None,
|
819
823
|
lvl_one: Optional[ValueType] = None,
|
820
|
-
|
824
|
+
*,
|
825
|
+
delete_lvl_one: bool = False,
|
821
826
|
) -> OpenTimeSeries:
|
822
827
|
"""
|
823
828
|
Set the column labels of the .tsdf Pandas Dataframe.
|
@@ -826,7 +831,7 @@ class OpenTimeSeries(CommonModel): # type: ignore[misc]
|
|
826
831
|
----------
|
827
832
|
lvl_zero: str, optional
|
828
833
|
New level zero label
|
829
|
-
lvl_one:
|
834
|
+
lvl_one: ValueType, optional
|
830
835
|
New level one label
|
831
836
|
delete_lvl_one: bool, default: False
|
832
837
|
If True the level one label is deleted
|
@@ -868,7 +873,7 @@ def timeseries_chain(
|
|
868
873
|
Earlier series to chain with
|
869
874
|
back: TypeOpenTimeSeries
|
870
875
|
Later series to chain with
|
871
|
-
old_fee:
|
876
|
+
old_fee: float, default: 0.0
|
872
877
|
Fee to apply to earlier series
|
873
878
|
|
874
879
|
Returns
|
openseries/simulation.py
CHANGED
@@ -818,8 +818,7 @@ class ReturnSimulation:
|
|
818
818
|
Mean standard deviation
|
819
819
|
seed: int
|
820
820
|
Seed for random process initiation
|
821
|
-
trading_days_in_year: DaysInYearType,
|
822
|
-
default: 252
|
821
|
+
trading_days_in_year: DaysInYearType, default: 252
|
823
822
|
Number of trading days used to annualize
|
824
823
|
|
825
824
|
Returns
|
@@ -889,8 +888,7 @@ class ReturnSimulation:
|
|
889
888
|
This is the rate of mean reversion for volatility in the Heston model
|
890
889
|
seed: int
|
891
890
|
Seed for random process initiation
|
892
|
-
trading_days_in_year: DaysInYearType,
|
893
|
-
default: 252
|
891
|
+
trading_days_in_year: DaysInYearType, default: 252
|
894
892
|
Number of trading days used to annualize
|
895
893
|
|
896
894
|
Returns
|
@@ -962,8 +960,7 @@ class ReturnSimulation:
|
|
962
960
|
This is the rate of mean reversion for volatility in the Heston model
|
963
961
|
seed: int
|
964
962
|
Seed for random process initiation
|
965
|
-
trading_days_in_year: DaysInYearType,
|
966
|
-
default: 252
|
963
|
+
trading_days_in_year: DaysInYearType, default: 252
|
967
964
|
Number of trading days used to annualize
|
968
965
|
|
969
966
|
Returns
|
@@ -1038,8 +1035,7 @@ class ReturnSimulation:
|
|
1038
1035
|
This is the average jump size
|
1039
1036
|
seed: int
|
1040
1037
|
Seed for random process initiation
|
1041
|
-
trading_days_in_year: DaysInYearType,
|
1042
|
-
default: 252
|
1038
|
+
trading_days_in_year: DaysInYearType, default: 252
|
1043
1039
|
Number of trading days used to annualize
|
1044
1040
|
|
1045
1041
|
Returns
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: openseries
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.9
|
4
4
|
Summary: Package for simple financial time series analysis.
|
5
5
|
Home-page: https://github.com/CaptorAB/OpenSeries
|
6
6
|
License: BSD-3-Clause
|
@@ -20,10 +20,10 @@ Classifier: Programming Language :: Python :: 3.10
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
21
21
|
Classifier: Topic :: Office/Business :: Financial :: Investment
|
22
22
|
Requires-Dist: ffn (>=0.3.7,<0.4.0)
|
23
|
-
Requires-Dist: holidays (>=0.
|
24
|
-
Requires-Dist: numpy (>=1.
|
23
|
+
Requires-Dist: holidays (>=0.35,<0.36)
|
24
|
+
Requires-Dist: numpy (>=1.26.1,<2.0.0)
|
25
25
|
Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
|
26
|
-
Requires-Dist: pandas (>=2.
|
26
|
+
Requires-Dist: pandas (>=2.1.1,<3.0.0)
|
27
27
|
Requires-Dist: plotly (>=5.17.0,<6.0.0)
|
28
28
|
Requires-Dist: pydantic (>=2.4.2,<3.0.0)
|
29
29
|
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
openseries/__init__.py,sha256=hA7I5IFk88EnX6eyBbI1KLT_FGcmPIKF49xa5g3T8Yg,41
|
2
|
+
openseries/common_model.py,sha256=de3sFqvpHjxwJ3RSk80nzg98msGVVhqnhzW74QkS6Yk,66399
|
3
|
+
openseries/datefixer.py,sha256=vfZtT0YnfoLX8z9fq-B8SJJL8yq35SS21MiZYa5jthw,15898
|
4
|
+
openseries/frame.py,sha256=M_1ZVKh1AAJ3kWQuhLujnTwpgeddy_BR7Wn4bY5OCd4,62054
|
5
|
+
openseries/load_plotly.py,sha256=UBBjzByrKWjLRBNfwHJXQEs80QXaS_7EzaFu8TnrJxA,1803
|
6
|
+
openseries/plotly_captor_logo.json,sha256=pGMuPVu4cEO3ZsCH1wU03hxqbIQkHFNoJUs1k1WK89Y,178
|
7
|
+
openseries/plotly_layouts.json,sha256=xhrMOqW8LXb4QMtPiNBGdkPX518OHThiIJ68jpQk524,1429
|
8
|
+
openseries/risk.py,sha256=u2BZwmm5Ydbu03HdT-XjwHWkV-vZ0tUY3-Ok58qobVc,6312
|
9
|
+
openseries/series.py,sha256=GRPZpbhzwDSJR4mHY9Su33-K_Qaez-XXNZV9Iqn9UCw,30889
|
10
|
+
openseries/simulation.py,sha256=kPPIC4j0ceCLpvlSS21RCHJrIlC3s1SWWggyti1iMbw,35741
|
11
|
+
openseries/types.py,sha256=oZVcAT2-5-_ZMEU_r7FQZUFPU11REhHyUNOFu4joWk8,7775
|
12
|
+
openseries-1.3.9.dist-info/LICENSE.md,sha256=NJjeq3wyB7EnnHLmsdK1EK6zT00T1eB3FgAmHAPT_vM,1521
|
13
|
+
openseries-1.3.9.dist-info/METADATA,sha256=Q-g0RdwIf8vOOdctp-UonZKZELBauthls_j-a2iZC5Y,47751
|
14
|
+
openseries-1.3.9.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
15
|
+
openseries-1.3.9.dist-info/RECORD,,
|
@@ -1,15 +0,0 @@
|
|
1
|
-
openseries/__init__.py,sha256=hA7I5IFk88EnX6eyBbI1KLT_FGcmPIKF49xa5g3T8Yg,41
|
2
|
-
openseries/common_model.py,sha256=-MpjOIx-ebg6ZTl9kVo4yWFmz_ffkj3y0BGMF5vk7AM,66306
|
3
|
-
openseries/datefixer.py,sha256=HkHXkajI0QhkdAcvecH2yLki8B6Ne4Bk1iir-mKK5pw,15939
|
4
|
-
openseries/frame.py,sha256=vYtX_okdGLSlMzmy07Rl6_aArycv7Jo_KjRra2tQTyA,61810
|
5
|
-
openseries/load_plotly.py,sha256=zuqpHVIeRtZxcM-K5-rjIpn6_Z8UG-ll-02GqpHe9U8,1820
|
6
|
-
openseries/plotly_captor_logo.json,sha256=pGMuPVu4cEO3ZsCH1wU03hxqbIQkHFNoJUs1k1WK89Y,178
|
7
|
-
openseries/plotly_layouts.json,sha256=xhrMOqW8LXb4QMtPiNBGdkPX518OHThiIJ68jpQk524,1429
|
8
|
-
openseries/risk.py,sha256=u2BZwmm5Ydbu03HdT-XjwHWkV-vZ0tUY3-Ok58qobVc,6312
|
9
|
-
openseries/series.py,sha256=03NOUhyacK1Mv6Rypsw3RR65LeJwBXhftMNUGXjlUfA,30879
|
10
|
-
openseries/simulation.py,sha256=LSKHma-uVnUdGJlRvDK0TuPunp2snpby1gF93TYNe34,35789
|
11
|
-
openseries/types.py,sha256=oZVcAT2-5-_ZMEU_r7FQZUFPU11REhHyUNOFu4joWk8,7775
|
12
|
-
openseries-1.3.8.dist-info/LICENSE.md,sha256=NJjeq3wyB7EnnHLmsdK1EK6zT00T1eB3FgAmHAPT_vM,1521
|
13
|
-
openseries-1.3.8.dist-info/METADATA,sha256=P388DlJxU7O0N09TrrbrH5ac-60fl3LCWuBhjk1iJWw,47751
|
14
|
-
openseries-1.3.8.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
15
|
-
openseries-1.3.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|