openseries 1.6.0__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,14 +21,14 @@ 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
32
 
33
33
  __all__ = [
34
34
  "date_fix",
@@ -45,10 +45,9 @@ def holiday_calendar(
45
45
  startyear: int,
46
46
  endyear: int,
47
47
  countries: CountriesType = "SE",
48
- custom_holidays: Optional[HolidayType] = None,
48
+ custom_holidays: HolidayType | None = None,
49
49
  ) -> busdaycalendar:
50
- """
51
- Generate a business calendar.
50
+ """Generate a business calendar.
52
51
 
53
52
  Parameters
54
53
  ----------
@@ -83,7 +82,7 @@ def holiday_calendar(
83
82
  country in list_supported_countries() for country in countries
84
83
  ):
85
84
  country: str
86
- countryholidays: list[Union[dt.date, str]] = []
85
+ countryholidays: list[dt.date | str] = []
87
86
  for i, country in enumerate(countries):
88
87
  staging = country_holidays(country=country, years=years)
89
88
  if i == 0 and custom_holidays is not None:
@@ -105,8 +104,7 @@ def holiday_calendar(
105
104
  def date_fix(
106
105
  fixerdate: DateType,
107
106
  ) -> dt.date:
108
- """
109
- Parse different date formats into datetime.date.
107
+ """Parse different date formats into datetime.date.
110
108
 
111
109
  Parameters
112
110
  ----------
@@ -125,9 +123,7 @@ def date_fix(
125
123
  return fixerdate
126
124
  if isinstance(fixerdate, datetime64):
127
125
  return (
128
- dt.datetime.strptime(str(fixerdate)[:10], "%Y-%m-%d")
129
- .astimezone()
130
- .date()
126
+ dt.datetime.strptime(str(fixerdate)[:10], "%Y-%m-%d").astimezone().date()
131
127
  )
132
128
  if isinstance(fixerdate, str):
133
129
  return dt.datetime.strptime(fixerdate, "%Y-%m-%d").astimezone().date()
@@ -141,13 +137,12 @@ def date_offset_foll(
141
137
  raw_date: DateType,
142
138
  months_offset: int = 12,
143
139
  countries: CountriesType = "SE",
144
- custom_holidays: Optional[HolidayType] = None,
140
+ custom_holidays: HolidayType | None = None,
145
141
  *,
146
142
  adjust: bool = False,
147
143
  following: bool = True,
148
144
  ) -> dt.date:
149
- """
150
- Offset dates according to a given calendar.
145
+ """Offset dates according to a given calendar.
151
146
 
152
147
  Parameters
153
148
  ----------
@@ -194,12 +189,11 @@ def date_offset_foll(
194
189
 
195
190
 
196
191
  def get_previous_business_day_before_today(
197
- today: Optional[dt.date] = None,
192
+ today: dt.date | None = None,
198
193
  countries: CountriesType = "SE",
199
- custom_holidays: Optional[HolidayType] = None,
194
+ custom_holidays: HolidayType | None = None,
200
195
  ) -> dt.date:
201
- """
202
- Bump date backwards to find the previous business day.
196
+ """Bump date backwards to find the previous business day.
203
197
 
204
198
  Parameters
205
199
  ----------
@@ -234,10 +228,9 @@ def offset_business_days(
234
228
  ddate: dt.date,
235
229
  days: int,
236
230
  countries: CountriesType = "SE",
237
- custom_holidays: Optional[HolidayType] = None,
231
+ custom_holidays: HolidayType | None = None,
238
232
  ) -> dt.date:
239
- """
240
- Bump date by business days.
233
+ """Bump date by business days.
241
234
 
242
235
  It first adjusts to a valid business day and then bumps with given
243
236
  number of business days from there.
@@ -313,18 +306,17 @@ def offset_business_days(
313
306
 
314
307
 
315
308
  def generate_calendar_date_range(
316
- trading_days: PositiveInt,
317
- start: Optional[dt.date] = None,
318
- end: Optional[dt.date] = None,
309
+ trading_days: int,
310
+ start: dt.date | None = None,
311
+ end: dt.date | None = None,
319
312
  countries: CountriesType = "SE",
320
313
  ) -> list[dt.date]:
321
- """
322
- Generate a list of business day calendar dates.
314
+ """Generate a list of business day calendar dates.
323
315
 
324
316
  Parameters
325
317
  ----------
326
- trading_days: PositiveInt
327
- Number of days to generate
318
+ trading_days: int
319
+ Number of days to generate. Must be greater than zero
328
320
  start: datetime.date, optional
329
321
  Date when the range starts
330
322
  end: datetime.date, optional
@@ -338,6 +330,10 @@ def generate_calendar_date_range(
338
330
  List of business day calendar dates
339
331
 
340
332
  """
333
+ if trading_days < 1:
334
+ msg = "Argument trading_days must be greater than zero."
335
+ raise ValueError(msg)
336
+
341
337
  if start and not end:
342
338
  tmp_range = date_range(
343
339
  start=start,
@@ -390,8 +386,7 @@ def do_resample_to_business_period_ends(
390
386
  freq: LiteralBizDayFreq,
391
387
  countries: CountriesType,
392
388
  ) -> DatetimeIndex:
393
- """
394
- Resample timeseries frequency to business calendar month end dates.
389
+ """Resample timeseries frequency to business calendar month end dates.
395
390
 
396
391
  Stubs left in place. Stubs will be aligned to the shortest stub.
397
392