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.
@@ -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
- overwrite: bool = True, # noqa: FBT001, FBT002
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 # type: ignore[union-attr]
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) # type: ignore[union-attr]
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[int] = None,
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 : int, optional
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[int] = None,
829
- ) -> Union[float, Series]: # type: ignore[type-arg]
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 : int, optional
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
- result = self.tsdf.loc[cast(int, earlier) : cast(int, later)]
869
- result = result.ffill()
870
- result = result.pct_change().std() * sqrt(time_factor)
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
- drift_adjust: bool = False, # noqa: FBT001, FBT002
889
- periods_in_a_year_fixed: Optional[int] = None,
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
- drift_adjust: bool, default: False
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
- drift_adjust: bool = False, # noqa: FBT001, FBT002
944
- periods_in_a_year_fixed: Optional[int] = None,
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
- drift_adjust: bool, default: False
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[int] = None,
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 : int, optional
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[int] = None,
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 : int, optional
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[int] = None,
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 : int, optional
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[int] = None,
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 : int, optional
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
- drift_adjust: bool = False, # noqa: FBT001, FBT002
1944
- periods_in_a_year_fixed: Optional[int] = None,
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
- drift_adjust: bool, default: False
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[TypeOpenTimeSeries]
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[TypeOpenTimeSeries]
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[str]:
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[str]
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[int] = None,
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 : int, optional
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, "Returns"] = (
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], "Returns")] # type: ignore[index]
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], "Returns")] # type: ignore[index]
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], "Returns")] # type: ignore[index]
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], "Returns")] # type: ignore[index]
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], "Returns"],
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], "Returns"],
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], "Returns"]
802
- * row.loc[cols[1], "Returns"]
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
- base_zero: bool = True, # noqa: FBT001, FBT002
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[int] = None,
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 : int, optional
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[int] = None,
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 : int, optional
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[int] = None,
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 : int, optional
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[int] = None,
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 : int, optional
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
@@ -36,7 +36,8 @@ def check_remote_file_existence(url: str) -> bool:
36
36
 
37
37
 
38
38
  def load_plotly_dict(
39
- responsive: bool = True, # noqa: FBT001, FBT002
39
+ *,
40
+ responsive: bool = True,
40
41
  ) -> tuple[PlotlyLayoutType, CaptorLogoType]:
41
42
  """
42
43
  Load Plotly defaults.
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
- local_ccy: bool = True, # noqa: FBT001, FBT002
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
- local_ccy: bool = True, # noqa: FBT001, FBT002
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
- local_ccy: bool = True, # noqa: FBT001, FBT002
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[int] = None,
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 : int, optional
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, "Returns"] = (
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, "Returns")] # type: ignore[index]
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, "Returns")].iloc[ # type: ignore[index]
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
- delete_lvl_one: bool = False, # noqa: FBT001, FBT002
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: str, optional
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: bool, default: False
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.8
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.34,<0.35)
24
- Requires-Dist: numpy (>=1.25.2,<2.0.0)
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.0.3,<3.0.0)
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,,