openseries 1.8.1__py3-none-any.whl → 1.8.3__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
@@ -32,7 +32,7 @@ def _cvar_down_calc(
32
32
  level: float, default: 0.95
33
33
  The sought CVaR level
34
34
 
35
- Returns
35
+ Returns:
36
36
  -------
37
37
  float
38
38
  Downside Conditional Value At Risk "CVaR"
@@ -66,7 +66,7 @@ def _var_down_calc(
66
66
  interpolation: LiteralQuantileInterp, default: "lower"
67
67
  type of interpolation in Pandas.DataFrame.quantile() function.
68
68
 
69
- Returns
69
+ Returns:
70
70
  -------
71
71
  float
72
72
  Downside Value At Risk
openseries/datefixer.py CHANGED
@@ -65,7 +65,7 @@ def holiday_calendar(
65
65
  Argument where missing holidays can be added as
66
66
  {"2021-02-12": "Jack's birthday"} or ["2021-02-12"]
67
67
 
68
- Returns
68
+ Returns:
69
69
  -------
70
70
  numpy.busdaycalendar
71
71
  Generate a business calendar
@@ -113,7 +113,7 @@ def date_fix(
113
113
  fixerdate: DateType
114
114
  The data item to parse
115
115
 
116
- Returns
116
+ Returns:
117
117
  -------
118
118
  datetime.date
119
119
  Parsed date
@@ -160,7 +160,7 @@ def date_offset_foll(
160
160
  following: bool, default: True
161
161
  Determines if days should be offset forward (following) or backward
162
162
 
163
- Returns
163
+ Returns:
164
164
  -------
165
165
  datetime.date
166
166
  Off-set date
@@ -185,7 +185,7 @@ def date_offset_foll(
185
185
  while not is_busday(dates=new_date, busdaycal=calendar):
186
186
  new_date += day_delta
187
187
 
188
- return new_date
188
+ return new_date # type: ignore[no-any-return]
189
189
 
190
190
 
191
191
  def get_previous_business_day_before_today(
@@ -205,7 +205,7 @@ def get_previous_business_day_before_today(
205
205
  Argument where missing holidays can be added as
206
206
  {"2021-02-12": "Jack's birthday"} or ["2021-02-12"]
207
207
 
208
- Returns
208
+ Returns:
209
209
  -------
210
210
  datetime.date
211
211
  The previous business day
@@ -248,7 +248,7 @@ def offset_business_days(
248
248
  Argument where missing holidays can be added as
249
249
  {"2021-02-12": "Jack's birthday"} or ["2021-02-12"]
250
250
 
251
- Returns
251
+ Returns:
252
252
  -------
253
253
  datetime.date
254
254
  The new offset business day
@@ -324,7 +324,7 @@ def generate_calendar_date_range(
324
324
  countries: CountriesType, default: "SE"
325
325
  (List of) country code(s) according to ISO 3166-1 alpha-2
326
326
 
327
- Returns
327
+ Returns:
328
328
  -------
329
329
  list[dt.date]
330
330
  List of business day calendar dates
@@ -342,7 +342,7 @@ def generate_calendar_date_range(
342
342
  )
343
343
  calendar = holiday_calendar(
344
344
  startyear=start.year,
345
- endyear=date_fix(tmp_range[-1]).year,
345
+ endyear=date_fix(tmp_range.tolist()[-1]).year,
346
346
  countries=countries,
347
347
  )
348
348
  return [
@@ -357,7 +357,7 @@ def generate_calendar_date_range(
357
357
  if end and not start:
358
358
  tmp_range = date_range(end=end, periods=trading_days * 365 // 252, freq="D")
359
359
  calendar = holiday_calendar(
360
- startyear=date_fix(tmp_range[0]).year,
360
+ startyear=date_fix(tmp_range.tolist()[0]).year,
361
361
  endyear=end.year,
362
362
  countries=countries,
363
363
  )
@@ -396,7 +396,7 @@ def _do_resample_to_business_period_ends(
396
396
  (List of) country code(s) according to ISO 3166-1 alpha-2
397
397
  to create a business day calendar used for date adjustments
398
398
 
399
- Returns
399
+ Returns:
400
400
  -------
401
401
  Pandas.DatetimeIndex
402
402
  A date range aligned to business period ends
openseries/frame.py CHANGED
@@ -11,11 +11,11 @@ from typing import TYPE_CHECKING, cast
11
11
  if TYPE_CHECKING: # pragma: no cover
12
12
  import datetime as dt
13
13
 
14
- from statsmodels.regression.linear_model import ( # type: ignore[import-untyped,unused-ignore]
14
+ from statsmodels.regression.linear_model import ( # type: ignore[import-untyped]
15
15
  OLSResults,
16
16
  )
17
17
 
18
- import statsmodels.api as sm # type: ignore[import-untyped,unused-ignore]
18
+ import statsmodels.api as sm # type: ignore[import-untyped]
19
19
  from numpy import (
20
20
  array,
21
21
  cov,
@@ -31,7 +31,6 @@ from pandas import (
31
31
  DataFrame,
32
32
  DatetimeIndex,
33
33
  Index,
34
- Int64Dtype,
35
34
  MultiIndex,
36
35
  Series,
37
36
  concat,
@@ -82,7 +81,7 @@ class OpenFrame(_CommonModel):
82
81
  weights: list[float], optional
83
82
  List of weights in float format.
84
83
 
85
- Returns
84
+ Returns:
86
85
  -------
87
86
  OpenFrame
88
87
  Object of the class OpenFrame
@@ -94,7 +93,7 @@ class OpenFrame(_CommonModel):
94
93
  weights: list[float] | None = None
95
94
 
96
95
  # noinspection PyMethodParameters
97
- @field_validator("constituents")
96
+ @field_validator("constituents") # type: ignore[misc]
98
97
  def _check_labels_unique( # type: ignore[misc]
99
98
  cls: OpenFrame, # noqa: N805
100
99
  tseries: list[OpenTimeSeries],
@@ -122,7 +121,7 @@ class OpenFrame(_CommonModel):
122
121
  weights: list[float], optional
123
122
  List of weights in float format.
124
123
 
125
- Returns
124
+ Returns:
126
125
  -------
127
126
  OpenFrame
128
127
  Object of the class OpenFrame
@@ -150,7 +149,7 @@ class OpenFrame(_CommonModel):
150
149
  def from_deepcopy(self: Self) -> Self:
151
150
  """Create copy of the OpenFrame object.
152
151
 
153
- Returns
152
+ Returns:
154
153
  -------
155
154
  OpenFrame
156
155
  An OpenFrame object
@@ -169,7 +168,7 @@ class OpenFrame(_CommonModel):
169
168
  how: LiteralHowMerge, default: "outer"
170
169
  The Pandas merge method.
171
170
 
172
- Returns
171
+ Returns:
173
172
  -------
174
173
  OpenFrame
175
174
  An OpenFrame object
@@ -213,7 +212,7 @@ class OpenFrame(_CommonModel):
213
212
  properties: list[LiteralFrameProps], optional
214
213
  The properties to calculate. Defaults to calculating all available.
215
214
 
216
- Returns
215
+ Returns:
217
216
  -------
218
217
  pandas.DataFrame
219
218
  Properties of the contituent OpenTimeSeries
@@ -232,24 +231,23 @@ class OpenFrame(_CommonModel):
232
231
  def lengths_of_items(self: Self) -> Series[int]:
233
232
  """Number of observations of all constituents.
234
233
 
235
- Returns
234
+ Returns:
236
235
  -------
237
236
  Pandas.Series[int]
238
237
  Number of observations of all constituents
239
238
 
240
239
  """
241
240
  return Series(
242
- data=[int(self.tsdf.loc[:, d].count()) for d in self.tsdf],
241
+ data=[self.tsdf.loc[:, d].count() for d in self.tsdf],
243
242
  index=self.tsdf.columns,
244
243
  name="observations",
245
- dtype=Int64Dtype(),
246
- )
244
+ ).astype(int)
247
245
 
248
246
  @property
249
247
  def item_count(self: Self) -> int:
250
248
  """Number of constituents.
251
249
 
252
- Returns
250
+ Returns:
253
251
  -------
254
252
  int
255
253
  Number of constituents
@@ -261,7 +259,7 @@ class OpenFrame(_CommonModel):
261
259
  def columns_lvl_zero(self: Self) -> list[str]:
262
260
  """Level 0 values of the MultiIndex columns in the .tsdf DataFrame.
263
261
 
264
- Returns
262
+ Returns:
265
263
  -------
266
264
  list[str]
267
265
  Level 0 values of the MultiIndex columns in the .tsdf DataFrame
@@ -273,7 +271,7 @@ class OpenFrame(_CommonModel):
273
271
  def columns_lvl_one(self: Self) -> list[ValueType]:
274
272
  """Level 1 values of the MultiIndex columns in the .tsdf DataFrame.
275
273
 
276
- Returns
274
+ Returns:
277
275
  -------
278
276
  list[ValueType]
279
277
  Level 1 values of the MultiIndex columns in the .tsdf DataFrame
@@ -285,7 +283,7 @@ class OpenFrame(_CommonModel):
285
283
  def first_indices(self: Self) -> Series[dt.date]:
286
284
  """The first dates in the timeseries of all constituents.
287
285
 
288
- Returns
286
+ Returns:
289
287
  -------
290
288
  Pandas.Series[dt.date]
291
289
  The first dates in the timeseries of all constituents
@@ -302,7 +300,7 @@ class OpenFrame(_CommonModel):
302
300
  def last_indices(self: Self) -> Series[dt.date]:
303
301
  """The last dates in the timeseries of all constituents.
304
302
 
305
- Returns
303
+ Returns:
306
304
  -------
307
305
  Pandas.Series[dt.date]
308
306
  The last dates in the timeseries of all constituents
@@ -319,7 +317,7 @@ class OpenFrame(_CommonModel):
319
317
  def span_of_days_all(self: Self) -> Series[int]:
320
318
  """Number of days from the first date to the last for all items in the frame.
321
319
 
322
- Returns
320
+ Returns:
323
321
  -------
324
322
  Pandas.Series[int]
325
323
  Number of days from the first date to the last for all
@@ -330,13 +328,12 @@ class OpenFrame(_CommonModel):
330
328
  data=[c.span_of_days for c in self.constituents],
331
329
  index=self.tsdf.columns,
332
330
  name="span of days",
333
- dtype=Int64Dtype(),
334
- )
331
+ ).astype(int)
335
332
 
336
333
  def value_to_ret(self: Self) -> Self:
337
334
  """Convert series of values into series of returns.
338
335
 
339
- Returns
336
+ Returns:
340
337
  -------
341
338
  OpenFrame
342
339
  The returns of the values in the series
@@ -359,7 +356,7 @@ class OpenFrame(_CommonModel):
359
356
  The number of periods between observations over which difference
360
357
  is calculated
361
358
 
362
- Returns
359
+ Returns:
363
360
  -------
364
361
  OpenFrame
365
362
  An OpenFrame object
@@ -375,7 +372,7 @@ class OpenFrame(_CommonModel):
375
372
  def to_cumret(self: Self) -> Self:
376
373
  """Convert series of returns into cumulative series of values.
377
374
 
378
- Returns
375
+ Returns:
379
376
  -------
380
377
  OpenFrame
381
378
  An OpenFrame object
@@ -411,7 +408,7 @@ class OpenFrame(_CommonModel):
411
408
  freq: LiteralBizDayFreq | str, default "BME"
412
409
  The date offset string that sets the resampled frequency
413
410
 
414
- Returns
411
+ Returns:
415
412
  -------
416
413
  OpenFrame
417
414
  An OpenFrame object
@@ -449,7 +446,7 @@ class OpenFrame(_CommonModel):
449
446
  method: LiteralPandasReindexMethod, default: nearest
450
447
  Controls the method used to align values across columns
451
448
 
452
- Returns
449
+ Returns:
453
450
  -------
454
451
  OpenFrame
455
452
  An OpenFrame object
@@ -517,7 +514,7 @@ class OpenFrame(_CommonModel):
517
514
  Allows locking the periods-in-a-year to simplify test cases and
518
515
  comparisons
519
516
 
520
- Returns
517
+ Returns:
521
518
  -------
522
519
  Pandas.DataFrame
523
520
  Series volatilities and correlation
@@ -605,7 +602,7 @@ class OpenFrame(_CommonModel):
605
602
  def correl_matrix(self: Self) -> DataFrame:
606
603
  """Correlation matrix.
607
604
 
608
- Returns
605
+ Returns:
609
606
  -------
610
607
  Pandas.DataFrame
611
608
  Correlation matrix
@@ -635,7 +632,7 @@ class OpenFrame(_CommonModel):
635
632
  new_series: OpenTimeSeries
636
633
  The timeseries to add
637
634
 
638
- Returns
635
+ Returns:
639
636
  -------
640
637
  OpenFrame
641
638
  An OpenFrame object
@@ -653,7 +650,7 @@ class OpenFrame(_CommonModel):
653
650
  lvl_zero_item: str
654
651
  The .tsdf column level 0 value of the timeseries to delete
655
652
 
656
- Returns
653
+ Returns:
657
654
  -------
658
655
  OpenFrame
659
656
  An OpenFrame object
@@ -692,7 +689,7 @@ class OpenFrame(_CommonModel):
692
689
  Determines where dataframe is truncated also when start_cut
693
690
  or end_cut is None.
694
691
 
695
- Returns
692
+ Returns:
696
693
  -------
697
694
  OpenFrame
698
695
  An OpenFrame object
@@ -793,7 +790,7 @@ class OpenFrame(_CommonModel):
793
790
  Allows locking the periods-in-a-year to simplify test cases and
794
791
  comparisons
795
792
 
796
- Returns
793
+ Returns:
797
794
  -------
798
795
  Pandas.Series[float]
799
796
  Tracking Errors
@@ -885,7 +882,7 @@ class OpenFrame(_CommonModel):
885
882
  Allows locking the periods-in-a-year to simplify test cases and
886
883
  comparisons
887
884
 
888
- Returns
885
+ Returns:
889
886
  -------
890
887
  Pandas.Series[float]
891
888
  Information Ratios
@@ -987,7 +984,7 @@ class OpenFrame(_CommonModel):
987
984
  Allows locking the periods-in-a-year to simplify test cases and
988
985
  comparisons
989
986
 
990
- Returns
987
+ Returns:
991
988
  -------
992
989
  Pandas.Series[float]
993
990
  Capture Ratios
@@ -1169,7 +1166,7 @@ class OpenFrame(_CommonModel):
1169
1166
  dlta_degr_freedms: int, default: 1
1170
1167
  Variance bias factor taking the value 0 or 1.
1171
1168
 
1172
- Returns
1169
+ Returns:
1173
1170
  -------
1174
1171
  float
1175
1172
  Beta as Co-variance of x & y divided by Variance of x
@@ -1253,7 +1250,7 @@ class OpenFrame(_CommonModel):
1253
1250
  fitted_series: bool, default: True
1254
1251
  If True the fit is added as a new column in the .tsdf Pandas.DataFrame
1255
1252
 
1256
- Returns
1253
+ Returns:
1257
1254
  -------
1258
1255
  OLSResults
1259
1256
  The Statsmodels regression output
@@ -1318,7 +1315,7 @@ class OpenFrame(_CommonModel):
1318
1315
  dlta_degr_freedms: int, default: 1
1319
1316
  Variance bias factor taking the value 0 or 1.
1320
1317
 
1321
- Returns
1318
+ Returns:
1322
1319
  -------
1323
1320
  float
1324
1321
  Jensen's alpha
@@ -1438,7 +1435,7 @@ class OpenFrame(_CommonModel):
1438
1435
  weight_strat: LiteralPortfolioWeightings, optional
1439
1436
  weight calculation strategies
1440
1437
 
1441
- Returns
1438
+ Returns:
1442
1439
  -------
1443
1440
  Pandas.DataFrame
1444
1441
  A basket timeseries
@@ -1503,7 +1500,7 @@ class OpenFrame(_CommonModel):
1503
1500
  periods_in_a_year_fixed : DaysInYearType, optional
1504
1501
  Allows locking the periods-in-a-year to simplify test cases and comparisons
1505
1502
 
1506
- Returns
1503
+ Returns:
1507
1504
  -------
1508
1505
  Pandas.DataFrame
1509
1506
  Rolling Information Ratios
@@ -1569,7 +1566,7 @@ class OpenFrame(_CommonModel):
1569
1566
  dlta_degr_freedms: int, default: 1
1570
1567
  Variance bias factor taking the value 0 or 1.
1571
1568
 
1572
- Returns
1569
+ Returns:
1573
1570
  -------
1574
1571
  Pandas.DataFrame
1575
1572
  Rolling Betas
@@ -1629,7 +1626,7 @@ class OpenFrame(_CommonModel):
1629
1626
  observations: int, default: 21
1630
1627
  The length of the rolling window to use is set as number of observations
1631
1628
 
1632
- Returns
1629
+ Returns:
1633
1630
  -------
1634
1631
  Pandas.DataFrame
1635
1632
  Rolling Correlations
openseries/load_plotly.py CHANGED
@@ -26,7 +26,7 @@ def _check_remote_file_existence(url: str) -> bool:
26
26
  url: str
27
27
  Path to remote file
28
28
 
29
- Returns
29
+ Returns:
30
30
  -------
31
31
  bool
32
32
  True if url is valid and False otherwise
@@ -54,7 +54,7 @@ def load_plotly_dict(
54
54
  responsive : bool
55
55
  Flag whether to load as responsive
56
56
 
57
- Returns
57
+ Returns:
58
58
  -------
59
59
  tuple[PlotlyLayoutType, CaptorLogoType]
60
60
  A dictionary with the Plotly config and layout template
openseries/owntypes.py CHANGED
@@ -38,7 +38,7 @@ CountryListType = conset(
38
38
  CountriesType = Union[CountryListType, CountryStringType] # type: ignore[valid-type] # noqa: UP007
39
39
 
40
40
 
41
- class Countries(BaseModel):
41
+ class Countries(BaseModel): # type: ignore[misc]
42
42
  """Declare Countries."""
43
43
 
44
44
  countryinput: CountriesType
@@ -57,7 +57,7 @@ CurrencyStringType = Annotated[
57
57
  ]
58
58
 
59
59
 
60
- class Currency(BaseModel):
60
+ class Currency(BaseModel): # type: ignore[misc]
61
61
  """Declare Currency."""
62
62
 
63
63
  ccy: CurrencyStringType
@@ -135,6 +135,15 @@ LiteralCaptureRatio = Literal["up", "down", "both"]
135
135
  LiteralBarPlotMode = Literal["stack", "group", "overlay", "relative"]
136
136
  LiteralPlotlyOutput = Literal["file", "div"]
137
137
  LiteralPlotlyJSlib = Literal[True, False, "cdn"]
138
+ LiteralPlotlyHistogramPlotType = Literal["bars", "lines"]
139
+ LiteralPlotlyHistogramBarMode = Literal["stack", "group", "overlay", "relative"]
140
+ LiteralPlotlyHistogramCurveType = Literal["normal", "kde"]
141
+ LiteralPlotlyHistogramHistNorm = Literal[
142
+ "percent",
143
+ "probability",
144
+ "density",
145
+ "probability density",
146
+ ]
138
147
  LiteralOlsFitMethod = Literal["pinv", "qr"]
139
148
  LiteralPortfolioWeightings = Literal["eq_weights", "inv_vol"]
140
149
  LiteralOlsFitCovType = Literal[
@@ -43,19 +43,19 @@
43
43
  "size": 14
44
44
  },
45
45
  "legend": {
46
- "bgcolor": "rgba(0, 0, 0, 0)",
46
+ "bgcolor": "rgba(0,0,0,0)",
47
47
  "orientation": "h",
48
48
  "x": 0.98,
49
49
  "xanchor": "right",
50
50
  "y": -0.15,
51
51
  "yanchor": "bottom"
52
52
  },
53
- "paper_bgcolor": "rgba(0, 0, 0, 0)",
54
- "plot_bgcolor": "rgba(0, 0, 0, 0)",
53
+ "paper_bgcolor": "rgba(255,255,255,1)",
54
+ "plot_bgcolor": "rgba(255,255,255,1)",
55
55
  "showlegend": true,
56
56
  "title": {
57
57
  "font": {
58
- "size": 24
58
+ "size": 32
59
59
  },
60
60
  "x": 0.5,
61
61
  "xanchor": "center",
@@ -26,10 +26,10 @@ from pandas import (
26
26
  Series,
27
27
  concat,
28
28
  )
29
- from plotly.graph_objs import Figure # type: ignore[import-untyped,unused-ignore]
30
- from plotly.io import to_html # type: ignore[import-untyped,unused-ignore]
31
- from plotly.offline import plot # type: ignore[import-untyped,unused-ignore]
32
- from scipy.optimize import minimize # type: ignore[import-untyped,unused-ignore]
29
+ from plotly.graph_objs import Figure # type: ignore[import-untyped]
30
+ from plotly.io import to_html # type: ignore[import-untyped]
31
+ from plotly.offline import plot # type: ignore[import-untyped]
32
+ from scipy.optimize import minimize # type: ignore[import-untyped]
33
33
 
34
34
  from .load_plotly import load_plotly_dict
35
35
  from .owntypes import (
@@ -47,6 +47,7 @@ from .series import OpenTimeSeries
47
47
  from .simulation import _random_generator
48
48
 
49
49
  if TYPE_CHECKING: # pragma: no cover
50
+ # noinspection PyUnresolvedReferences
50
51
  from collections.abc import Callable
51
52
 
52
53
  from numpy.typing import NDArray
@@ -79,7 +80,7 @@ def simulate_portfolios(
79
80
  seed: int
80
81
  The seed for the random process
81
82
 
82
- Returns
83
+ Returns:
83
84
  -------
84
85
  pandas.DataFrame
85
86
  The resulting data
@@ -160,7 +161,7 @@ def efficient_frontier(
160
161
  tweak: bool, default: True
161
162
  cutting the frontier to exclude multiple points with almost the same risk
162
163
 
163
- Returns
164
+ Returns:
164
165
  -------
165
166
  tuple[DataFrame, DataFrame, NDArray[float]]
166
167
  The efficient frontier data, simulation data and optimal portfolio
@@ -192,8 +193,8 @@ def efficient_frontier(
192
193
 
193
194
  frontier_max = cleaned_arithmetic_means.max()
194
195
 
195
- def _check_sum(weights: NDArray[float64]) -> float64:
196
- return npsum(weights) - 1
196
+ def _check_sum(weights: NDArray[float64]) -> float:
197
+ return cast("float", npsum(weights) - 1)
197
198
 
198
199
  def _get_ret_vol_sr(
199
200
  lg_ret: DataFrame,
@@ -347,7 +348,7 @@ def constrain_optimized_portfolios(
347
348
  minimize_method: LiteralMinimizeMethods, default: SLSQP
348
349
  The method passed into the scipy.minimize function
349
350
 
350
- Returns
351
+ Returns:
351
352
  -------
352
353
  tuple[OpenFrame, OpenTimeSeries, OpenFrame, OpenTimeSeries]
353
354
  The constrained optimal portfolio data
@@ -407,7 +408,7 @@ def prepare_plot_data(
407
408
  optimized: DataFrame
408
409
  Data optimized with the efficient_frontier method
409
410
 
410
- Returns
411
+ Returns:
411
412
  -------
412
413
  DataFrame
413
414
  The data prepared with mean returns, volatility and weights
@@ -492,7 +493,7 @@ def sharpeplot(
492
493
  auto_open: bool, default: True
493
494
  Determines whether to open a browser window with the plot
494
495
 
495
- Returns
496
+ Returns:
496
497
  -------
497
498
  Figure
498
499
  The scatter plot with simulated and optimized results
@@ -559,8 +560,8 @@ def sharpeplot(
559
560
  fig["layout"],
560
561
  ).get("colorway")[: len(point_frame.columns)]
561
562
  for col, clr in zip(point_frame.columns, colorway, strict=True):
562
- returns.extend([point_frame.loc["ret", col]])
563
- risk.extend([point_frame.loc["stdev", col]])
563
+ returns.extend([cast("float", point_frame.loc["ret", col])])
564
+ risk.extend([cast("float", point_frame.loc["stdev", col])])
564
565
  figure.add_scatter(
565
566
  x=[point_frame.loc["stdev", col]],
566
567
  y=[point_frame.loc["ret", col]],