openseries 1.5.7__py3-none-any.whl → 1.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
openseries/_risk.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from math import ceil
6
- from typing import Union, cast
6
+ from typing import TYPE_CHECKING, cast
7
7
 
8
8
  from numpy import (
9
9
  mean,
@@ -13,21 +13,21 @@ from numpy import (
13
13
  )
14
14
  from pandas import DataFrame, Series
15
15
 
16
- from openseries.types import LiteralQuantileInterp
16
+ if TYPE_CHECKING:
17
+ from .types import LiteralQuantileInterp # pragma: no cover
17
18
 
18
19
 
19
20
  def _cvar_down_calc(
20
- data: Union[DataFrame, Series[float], list[float]],
21
+ data: DataFrame | Series[float] | list[float],
21
22
  level: float = 0.95,
22
23
  ) -> float:
23
- """
24
- Calculate downside Conditional Value at Risk (CVaR).
24
+ """Calculate downside Conditional Value at Risk (CVaR).
25
25
 
26
26
  https://www.investopedia.com/terms/c/conditional_value_at_risk.asp.
27
27
 
28
28
  Parameters
29
29
  ----------
30
- data: Union[DataFrame, Series[float], list[float]]
30
+ data: DataFrame | Series[float] | list[float]
31
31
  The data to perform the calculation over
32
32
  level: float, default: 0.95
33
33
  The sought CVaR level
@@ -48,19 +48,18 @@ def _cvar_down_calc(
48
48
 
49
49
 
50
50
  def _var_down_calc(
51
- data: Union[DataFrame, Series[float], list[float]],
51
+ data: DataFrame | Series[float] | list[float],
52
52
  level: float = 0.95,
53
53
  interpolation: LiteralQuantileInterp = "lower",
54
54
  ) -> float:
55
- """
56
- Calculate downside Value At Risk (VaR).
55
+ """Calculate downside Value At Risk (VaR).
57
56
 
58
57
  The equivalent of percentile.inc([...], 1-level) over returns in MS Excel
59
58
  https://www.investopedia.com/terms/v/var.asp.
60
59
 
61
60
  Parameters
62
61
  ----------
63
- data: Union[DataFrame, Series[float], list[float]]
62
+ data: DataFrame | Series[float] | list[float]
64
63
  The data to perform the calculation over
65
64
  level: float, default: 0.95
66
65
  The sought VaR level
openseries/datefixer.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import datetime as dt
6
- from typing import Optional, Union, cast
6
+ from typing import TYPE_CHECKING, cast
7
7
 
8
8
  from dateutil.relativedelta import relativedelta
9
9
  from holidays import (
@@ -21,24 +21,33 @@ from pandas import (
21
21
  date_range,
22
22
  )
23
23
  from pandas.tseries.offsets import CustomBusinessDay
24
- from pydantic import PositiveInt
25
24
 
26
- from openseries.types import (
27
- CountriesType,
28
- DateType,
29
- HolidayType,
30
- LiteralBizDayFreq,
31
- )
25
+ if TYPE_CHECKING: # pragma: no cover
26
+ from .types import (
27
+ CountriesType,
28
+ DateType,
29
+ HolidayType,
30
+ LiteralBizDayFreq,
31
+ )
32
+
33
+ __all__ = [
34
+ "date_fix",
35
+ "date_offset_foll",
36
+ "do_resample_to_business_period_ends",
37
+ "generate_calendar_date_range",
38
+ "get_previous_business_day_before_today",
39
+ "holiday_calendar",
40
+ "offset_business_days",
41
+ ]
32
42
 
33
43
 
34
44
  def holiday_calendar(
35
45
  startyear: int,
36
46
  endyear: int,
37
47
  countries: CountriesType = "SE",
38
- custom_holidays: Optional[HolidayType] = None,
48
+ custom_holidays: HolidayType | None = None,
39
49
  ) -> busdaycalendar:
40
- """
41
- Generate a business calendar.
50
+ """Generate a business calendar.
42
51
 
43
52
  Parameters
44
53
  ----------
@@ -73,7 +82,7 @@ def holiday_calendar(
73
82
  country in list_supported_countries() for country in countries
74
83
  ):
75
84
  country: str
76
- countryholidays: list[Union[dt.date, str]] = []
85
+ countryholidays: list[dt.date | str] = []
77
86
  for i, country in enumerate(countries):
78
87
  staging = country_holidays(country=country, years=years)
79
88
  if i == 0 and custom_holidays is not None:
@@ -95,8 +104,7 @@ def holiday_calendar(
95
104
  def date_fix(
96
105
  fixerdate: DateType,
97
106
  ) -> dt.date:
98
- """
99
- Parse different date formats into datetime.date.
107
+ """Parse different date formats into datetime.date.
100
108
 
101
109
  Parameters
102
110
  ----------
@@ -115,9 +123,7 @@ def date_fix(
115
123
  return fixerdate
116
124
  if isinstance(fixerdate, datetime64):
117
125
  return (
118
- dt.datetime.strptime(str(fixerdate)[:10], "%Y-%m-%d")
119
- .astimezone()
120
- .date()
126
+ dt.datetime.strptime(str(fixerdate)[:10], "%Y-%m-%d").astimezone().date()
121
127
  )
122
128
  if isinstance(fixerdate, str):
123
129
  return dt.datetime.strptime(fixerdate, "%Y-%m-%d").astimezone().date()
@@ -131,13 +137,12 @@ def date_offset_foll(
131
137
  raw_date: DateType,
132
138
  months_offset: int = 12,
133
139
  countries: CountriesType = "SE",
134
- custom_holidays: Optional[HolidayType] = None,
140
+ custom_holidays: HolidayType | None = None,
135
141
  *,
136
142
  adjust: bool = False,
137
143
  following: bool = True,
138
144
  ) -> dt.date:
139
- """
140
- Offset dates according to a given calendar.
145
+ """Offset dates according to a given calendar.
141
146
 
142
147
  Parameters
143
148
  ----------
@@ -184,12 +189,11 @@ def date_offset_foll(
184
189
 
185
190
 
186
191
  def get_previous_business_day_before_today(
187
- today: Optional[dt.date] = None,
192
+ today: dt.date | None = None,
188
193
  countries: CountriesType = "SE",
189
- custom_holidays: Optional[HolidayType] = None,
194
+ custom_holidays: HolidayType | None = None,
190
195
  ) -> dt.date:
191
- """
192
- Bump date backwards to find the previous business day.
196
+ """Bump date backwards to find the previous business day.
193
197
 
194
198
  Parameters
195
199
  ----------
@@ -224,10 +228,9 @@ def offset_business_days(
224
228
  ddate: dt.date,
225
229
  days: int,
226
230
  countries: CountriesType = "SE",
227
- custom_holidays: Optional[HolidayType] = None,
231
+ custom_holidays: HolidayType | None = None,
228
232
  ) -> dt.date:
229
- """
230
- Bump date by business days.
233
+ """Bump date by business days.
231
234
 
232
235
  It first adjusts to a valid business day and then bumps with given
233
236
  number of business days from there.
@@ -303,18 +306,17 @@ def offset_business_days(
303
306
 
304
307
 
305
308
  def generate_calendar_date_range(
306
- trading_days: PositiveInt,
307
- start: Optional[dt.date] = None,
308
- end: Optional[dt.date] = None,
309
+ trading_days: int,
310
+ start: dt.date | None = None,
311
+ end: dt.date | None = None,
309
312
  countries: CountriesType = "SE",
310
313
  ) -> list[dt.date]:
311
- """
312
- Generate a list of business day calendar dates.
314
+ """Generate a list of business day calendar dates.
313
315
 
314
316
  Parameters
315
317
  ----------
316
- trading_days: PositiveInt
317
- Number of days to generate
318
+ trading_days: int
319
+ Number of days to generate. Must be greater than zero
318
320
  start: datetime.date, optional
319
321
  Date when the range starts
320
322
  end: datetime.date, optional
@@ -328,6 +330,10 @@ def generate_calendar_date_range(
328
330
  List of business day calendar dates
329
331
 
330
332
  """
333
+ if trading_days < 1:
334
+ msg = "Argument trading_days must be greater than zero."
335
+ raise ValueError(msg)
336
+
331
337
  if start and not end:
332
338
  tmp_range = date_range(
333
339
  start=start,
@@ -380,8 +386,7 @@ def do_resample_to_business_period_ends(
380
386
  freq: LiteralBizDayFreq,
381
387
  countries: CountriesType,
382
388
  ) -> DatetimeIndex:
383
- """
384
- Resample timeseries frequency to business calendar month end dates.
389
+ """Resample timeseries frequency to business calendar month end dates.
385
390
 
386
391
  Stubs left in place. Stubs will be aligned to the shortest stub.
387
392