openseries 1.5.6__py3-none-any.whl → 1.6.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 CHANGED
@@ -1 +1,44 @@
1
1
  """openseries.openseries.__init__.py."""
2
+
3
+ from .datefixer import (
4
+ date_fix,
5
+ date_offset_foll,
6
+ do_resample_to_business_period_ends,
7
+ generate_calendar_date_range,
8
+ get_previous_business_day_before_today,
9
+ holiday_calendar,
10
+ offset_business_days,
11
+ )
12
+ from .frame import OpenFrame
13
+ from .load_plotly import load_plotly_dict
14
+ from .portfoliotools import (
15
+ constrain_optimized_portfolios,
16
+ efficient_frontier,
17
+ prepare_plot_data,
18
+ sharpeplot,
19
+ simulate_portfolios,
20
+ )
21
+ from .series import OpenTimeSeries, timeseries_chain
22
+ from .simulation import ReturnSimulation
23
+ from .types import ValueType
24
+
25
+ __all__ = [
26
+ "OpenFrame",
27
+ "constrain_optimized_portfolios",
28
+ "efficient_frontier",
29
+ "prepare_plot_data",
30
+ "sharpeplot",
31
+ "simulate_portfolios",
32
+ "date_fix",
33
+ "date_offset_foll",
34
+ "do_resample_to_business_period_ends",
35
+ "generate_calendar_date_range",
36
+ "get_previous_business_day_before_today",
37
+ "holiday_calendar",
38
+ "offset_business_days",
39
+ "load_plotly_dict",
40
+ "OpenTimeSeries",
41
+ "timeseries_chain",
42
+ "ReturnSimulation",
43
+ "ValueType",
44
+ ]
@@ -9,9 +9,10 @@ from math import ceil
9
9
  from pathlib import Path
10
10
  from secrets import choice
11
11
  from string import ascii_letters
12
- from typing import Any, Optional, Union, cast
12
+ from typing import Any, Optional, SupportsFloat, Union, cast
13
13
 
14
14
  from numpy import float64, inf, isnan, log, maximum, sqrt
15
+ from numpy.typing import NDArray
15
16
  from openpyxl.utils.dataframe import dataframe_to_rows
16
17
  from openpyxl.workbook.workbook import Workbook
17
18
  from openpyxl.worksheet.worksheet import Worksheet
@@ -1132,7 +1133,7 @@ class _CommonModel(BaseModel):
1132
1133
  )
1133
1134
 
1134
1135
  if self.tsdf.shape[1] == 1:
1135
- return float(result.iloc[0])
1136
+ return float(cast(SupportsFloat, result.iloc[0]))
1136
1137
  return Series(
1137
1138
  data=result,
1138
1139
  index=self.tsdf.columns,
@@ -1361,7 +1362,7 @@ class _CommonModel(BaseModel):
1361
1362
  label = f"Imp vol from VaR {level:.0%}"
1362
1363
 
1363
1364
  if self.tsdf.shape[1] == 1:
1364
- return float(result.iloc[0])
1365
+ return float(cast(SupportsFloat, result.iloc[0]))
1365
1366
  return Series(
1366
1367
  data=result,
1367
1368
  index=self.tsdf.columns,
@@ -1593,7 +1594,7 @@ class _CommonModel(BaseModel):
1593
1594
  from_dt=from_date,
1594
1595
  to_dt=to_date,
1595
1596
  )
1596
- result = skew(
1597
+ result: NDArray[float64] = skew(
1597
1598
  a=self.tsdf.loc[cast(int, earlier) : cast(int, later)]
1598
1599
  .pct_change(fill_method=cast(str, None))
1599
1600
  .to_numpy(),
@@ -1642,7 +1643,7 @@ class _CommonModel(BaseModel):
1642
1643
  from_dt=from_date,
1643
1644
  to_dt=to_date,
1644
1645
  )
1645
- result = kurtosis(
1646
+ result: NDArray[float64] = kurtosis(
1646
1647
  self.tsdf.loc[cast(int, earlier) : cast(int, later)].pct_change(
1647
1648
  fill_method=cast(str, None),
1648
1649
  ),
openseries/_risk.py CHANGED
@@ -6,19 +6,11 @@ from math import ceil
6
6
  from typing import Union, cast
7
7
 
8
8
  from numpy import (
9
- divide,
10
- float64,
11
- isinf,
12
9
  mean,
13
- nan,
14
10
  nan_to_num,
15
11
  quantile,
16
12
  sort,
17
- sqrt,
18
- square,
19
- std,
20
13
  )
21
- from numpy.typing import NDArray
22
14
  from pandas import DataFrame, Series
23
15
 
24
16
  from openseries.types import LiteralQuantileInterp
@@ -87,56 +79,3 @@ def _var_down_calc(
87
79
  clean = nan_to_num(data)
88
80
  ret = clean[1:] / clean[:-1] - 1
89
81
  return cast(float, quantile(ret, 1 - level, method=interpolation))
90
-
91
-
92
- def _ewma_calc(
93
- reeturn: float,
94
- prev_ewma: float,
95
- time_factor: float,
96
- lmbda: float = 0.94,
97
- ) -> float:
98
- """
99
- Calculate Exponentially Weighted Moving Average volatility.
100
-
101
- Parameters
102
- ----------
103
- reeturn : float
104
- Return value
105
- prev_ewma : float
106
- Previous EWMA volatility value
107
- time_factor : float
108
- Scaling factor to annualize
109
- lmbda: float, default: 0.94
110
- Scaling factor to determine weighting.
111
-
112
- Returns
113
- -------
114
- float
115
- EWMA volatility value
116
-
117
- """
118
- return cast(
119
- float,
120
- sqrt(square(reeturn) * time_factor * (1 - lmbda) + square(prev_ewma) * lmbda),
121
- )
122
-
123
-
124
- def _calc_inv_vol_weights(returns: DataFrame) -> NDArray[float64]:
125
- """
126
- Calculate weights proportional to inverse volatility.
127
-
128
- Parameters
129
- ----------
130
- returns: pandas.DataFrame
131
- returns data
132
-
133
- Returns
134
- -------
135
- NDArray[float64]
136
- Calculated weights
137
-
138
- """
139
- vol = divide(1.0, std(returns, axis=0, ddof=1))
140
- vol[isinf(vol)] = nan
141
- volsum = vol.sum()
142
- return cast(NDArray[float64], divide(vol, volsum))
openseries/datefixer.py CHANGED
@@ -30,6 +30,16 @@ from openseries.types import (
30
30
  LiteralBizDayFreq,
31
31
  )
32
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
+ ]
42
+
33
43
 
34
44
  def holiday_calendar(
35
45
  startyear: int,
@@ -62,7 +72,7 @@ def holiday_calendar(
62
72
  endyear += 1
63
73
  if startyear == endyear:
64
74
  endyear += 1
65
- years = list(range(int(startyear), int(endyear)))
75
+ years = list(range(startyear, endyear))
66
76
 
67
77
  if isinstance(countries, str) and countries in list_supported_countries():
68
78
  staging = country_holidays(country=countries, years=years)
@@ -116,15 +126,11 @@ def date_fix(
116
126
  if isinstance(fixerdate, datetime64):
117
127
  return (
118
128
  dt.datetime.strptime(str(fixerdate)[:10], "%Y-%m-%d")
119
- .replace(tzinfo=dt.timezone.utc)
129
+ .astimezone()
120
130
  .date()
121
131
  )
122
132
  if isinstance(fixerdate, str):
123
- return (
124
- dt.datetime.strptime(fixerdate, "%Y-%m-%d")
125
- .replace(tzinfo=dt.timezone.utc)
126
- .date()
127
- )
133
+ return dt.datetime.strptime(fixerdate, "%Y-%m-%d").astimezone().date()
128
134
  msg = f"Unknown date format {fixerdate!s} of type {type(fixerdate)!s} encountered"
129
135
  raise TypeError(
130
136
  msg,
@@ -212,7 +218,7 @@ def get_previous_business_day_before_today(
212
218
 
213
219
  """
214
220
  if today is None:
215
- today = dt.datetime.now(tz=dt.timezone.utc).date()
221
+ today = dt.datetime.now().astimezone().date()
216
222
 
217
223
  return date_offset_foll(
218
224
  today - dt.timedelta(days=1),
@@ -241,8 +247,8 @@ def offset_business_days(
241
247
  ddate: datetime.date
242
248
  A starting date that does not have to be a business day
243
249
  days: int
244
- The number of business days to offset from the business day that is
245
- the closest preceding the day given
250
+ The number of business days to offset from the business day that is given
251
+ If days is set as anything other than an integer its value is set to zero
246
252
  countries: CountriesType, default: "SE"
247
253
  (List of) country code(s) according to ISO 3166-1 alpha-2
248
254
  custom_holidays: HolidayType, optional
@@ -255,6 +261,11 @@ def offset_business_days(
255
261
  The new offset business day
256
262
 
257
263
  """
264
+ try:
265
+ days = int(days)
266
+ except TypeError:
267
+ days = 0
268
+
258
269
  if days <= 0:
259
270
  scaledtoyeardays = int((days * 372 / 250) // 1) - 365
260
271
  ndate = ddate + dt.timedelta(days=scaledtoyeardays)