openseries 1.2.2__py3-none-any.whl → 1.2.4__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/series.py CHANGED
@@ -1,11 +1,11 @@
1
- """
2
- Defining the OpenTimeSeries class
3
- """
1
+ """Defining the OpenTimeSeries class."""
4
2
  from __future__ import annotations
5
- from copy import deepcopy
3
+
6
4
  import datetime as dt
5
+ from copy import deepcopy
7
6
  from re import compile as re_compile
8
- from typing import cast, Optional, Type, Union, TypeVar, Any
7
+ from typing import Any, Optional, TypeVar, Union, cast
8
+
9
9
  from numpy import (
10
10
  array,
11
11
  cumprod,
@@ -19,9 +19,9 @@ from numpy.typing import NDArray
19
19
  from pandas import (
20
20
  DataFrame,
21
21
  DatetimeIndex,
22
- date_range,
23
22
  MultiIndex,
24
23
  Series,
24
+ date_range,
25
25
  )
26
26
  from pydantic import BaseModel, ConfigDict, field_validator, model_validator
27
27
  from stdnum import isin as isincode
@@ -29,34 +29,36 @@ from stdnum.exceptions import InvalidChecksum
29
29
 
30
30
  from openseries.common_model import CommonModel
31
31
  from openseries.datefixer import (
32
- date_fix,
33
32
  align_dataframe_to_local_cdays,
33
+ date_fix,
34
34
  do_resample_to_business_period_ends,
35
35
  get_calc_range,
36
36
  )
37
+ from openseries.risk import (
38
+ drawdown_details,
39
+ ewma_calc,
40
+ )
37
41
  from openseries.types import (
38
42
  CountriesType,
39
43
  CurrencyStringType,
40
44
  DatabaseIdStringType,
41
45
  DateListType,
42
- ValueListType,
43
46
  LiteralBizDayFreq,
44
- LiteralPandasResampleConvention,
45
47
  LiteralPandasReindexMethod,
48
+ LiteralPandasResampleConvention,
46
49
  LiteralSeriesProps,
47
50
  OpenTimeSeriesPropertiesList,
51
+ ValueListType,
48
52
  ValueType,
49
53
  )
50
- from openseries.risk import (
51
- drawdown_details,
52
- ewma_calc,
53
- )
54
54
 
55
55
  TypeOpenTimeSeries = TypeVar("TypeOpenTimeSeries", bound="OpenTimeSeries")
56
56
 
57
57
 
58
- class OpenTimeSeries(BaseModel, CommonModel):
59
- """Object of the class OpenTimeSeries.
58
+ class OpenTimeSeries(BaseModel, CommonModel): # type: ignore[misc]
59
+
60
+ """
61
+ Object of the class OpenTimeSeries.
60
62
 
61
63
  Parameters
62
64
  ----------
@@ -90,8 +92,8 @@ class OpenTimeSeries(BaseModel, CommonModel):
90
92
  Placeholder for a name of the timeseries
91
93
  """
92
94
 
93
- timeseriesId: DatabaseIdStringType
94
- instrumentId: DatabaseIdStringType
95
+ timeseriesId: DatabaseIdStringType # noqa: N815
96
+ instrumentId: DatabaseIdStringType # noqa: N815
95
97
  name: str
96
98
  valuetype: ValueType
97
99
  dates: DateListType
@@ -111,23 +113,21 @@ class OpenTimeSeries(BaseModel, CommonModel):
111
113
  extra="allow",
112
114
  )
113
115
 
114
- @field_validator("isin")
115
- def check_isincode( # pylint: disable=no-self-argument
116
- cls: TypeOpenTimeSeries, isin_code: str
117
- ) -> str:
118
- """Pydantic validator to ensure that the ISIN code is valid if provided"""
116
+ @field_validator("isin") # type: ignore[misc]
117
+ def check_isincode(cls: TypeOpenTimeSeries, isin_code: str) -> str: # noqa: N805
118
+ """Pydantic validator to ensure that the ISIN code is valid if provided."""
119
119
  if isin_code:
120
120
  try:
121
121
  isincode.validate(isin_code)
122
122
  except InvalidChecksum as exc:
123
123
  raise ValueError(
124
- "The ISIN code's checksum or check digit is invalid."
124
+ "The ISIN code's checksum or check digit is invalid.",
125
125
  ) from exc
126
126
  return isin_code
127
127
 
128
- @model_validator(mode="after")
129
- def check_dates_unique(self) -> OpenTimeSeries:
130
- """Pydantic validator to ensure that the dates are unique"""
128
+ @model_validator(mode="after") # type: ignore[misc]
129
+ def check_dates_unique(self: TypeOpenTimeSeries) -> OpenTimeSeries:
130
+ """Pydantic validator to ensure that the dates are unique."""
131
131
  dates_list_length = len(self.dates)
132
132
  dates_set_length = len(set(self.dates))
133
133
  if dates_list_length != dates_set_length:
@@ -136,17 +136,18 @@ class OpenTimeSeries(BaseModel, CommonModel):
136
136
 
137
137
  @classmethod
138
138
  def setup_class(
139
- cls: Type[TypeOpenTimeSeries],
139
+ cls: type[TypeOpenTimeSeries],
140
140
  domestic_ccy: CurrencyStringType = "SEK",
141
141
  countries: CountriesType = "SE",
142
142
  ) -> None:
143
- """Sets the domestic currency and calendar of the user.
143
+ """
144
+ Set the domestic currency and calendar of the user.
144
145
 
145
146
  Parameters
146
147
  ----------
147
- domestic_ccy : str, default: "SEK"
148
+ domestic_ccy : CurrencyStringType, default: "SEK"
148
149
  Currency code according to ISO 4217
149
- countries: list[str] | str, default: "SE"
150
+ countries: CountriesType, default: "SE"
150
151
  (List of) country code(s) according to ISO 3166-1 alpha-2
151
152
  """
152
153
  ccy_pattern = re_compile(r"^[A-Z]{3}$")
@@ -155,7 +156,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
155
156
  ccy_ok = ccy_pattern.match(domestic_ccy)
156
157
  except TypeError as exc:
157
158
  raise ValueError(
158
- "domestic currency must be a code according to ISO 4217"
159
+ "domestic currency must be a code according to ISO 4217",
159
160
  ) from exc
160
161
  if not ccy_ok:
161
162
  raise ValueError("domestic currency must be a code according to ISO 4217")
@@ -163,7 +164,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
163
164
  if not ctry_pattern.match(countries):
164
165
  raise ValueError(
165
166
  "countries must be a country code according to "
166
- "ISO 3166-1 alpha-2"
167
+ "ISO 3166-1 alpha-2",
167
168
  )
168
169
  elif isinstance(countries, list):
169
170
  try:
@@ -171,17 +172,17 @@ class OpenTimeSeries(BaseModel, CommonModel):
171
172
  except TypeError as exc:
172
173
  raise ValueError(
173
174
  "countries must be a list of country codes "
174
- "according to ISO 3166-1 alpha-2"
175
+ "according to ISO 3166-1 alpha-2",
175
176
  ) from exc
176
177
  if not all_ctries:
177
178
  raise ValueError(
178
179
  "countries must be a list of country codes "
179
- "according to ISO 3166-1 alpha-2"
180
+ "according to ISO 3166-1 alpha-2",
180
181
  )
181
182
  else:
182
183
  raise ValueError(
183
184
  "countries must be a (list of) country code(s) "
184
- "according to ISO 3166-1 alpha-2"
185
+ "according to ISO 3166-1 alpha-2",
185
186
  )
186
187
 
187
188
  cls.domestic = domestic_ccy
@@ -189,7 +190,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
189
190
 
190
191
  @classmethod
191
192
  def from_arrays(
192
- cls: Type[TypeOpenTimeSeries],
193
+ cls: type[TypeOpenTimeSeries],
193
194
  name: str,
194
195
  dates: DateListType,
195
196
  values: ValueListType,
@@ -200,7 +201,8 @@ class OpenTimeSeries(BaseModel, CommonModel):
200
201
  baseccy: CurrencyStringType = "SEK",
201
202
  local_ccy: bool = True,
202
203
  ) -> TypeOpenTimeSeries:
203
- """Creates a timeseries from a Pandas DataFrame or Series
204
+ """
205
+ Create series from a Pandas DataFrame or Series.
204
206
 
205
207
  Parameters
206
208
  ----------
@@ -228,7 +230,6 @@ class OpenTimeSeries(BaseModel, CommonModel):
228
230
  OpenTimeSeries
229
231
  An OpenTimeSeries object
230
232
  """
231
-
232
233
  return cls(
233
234
  name=name,
234
235
  label=name,
@@ -250,14 +251,15 @@ class OpenTimeSeries(BaseModel, CommonModel):
250
251
 
251
252
  @classmethod
252
253
  def from_df(
253
- cls: Type[TypeOpenTimeSeries],
254
+ cls: type[TypeOpenTimeSeries],
254
255
  dframe: Union[DataFrame, Series],
255
256
  column_nmbr: int = 0,
256
257
  valuetype: ValueType = ValueType.PRICE,
257
258
  baseccy: CurrencyStringType = "SEK",
258
259
  local_ccy: bool = True,
259
260
  ) -> TypeOpenTimeSeries:
260
- """Creates a timeseries from a Pandas DataFrame or Series
261
+ """
262
+ Create series from a Pandas DataFrame or Series.
261
263
 
262
264
  Parameters
263
265
  ----------
@@ -277,38 +279,39 @@ class OpenTimeSeries(BaseModel, CommonModel):
277
279
  OpenTimeSeries
278
280
  An OpenTimeSeries object
279
281
  """
280
-
281
282
  if isinstance(dframe, Series):
282
283
  if isinstance(dframe.name, tuple):
283
284
  label, _ = dframe.name
284
285
  else:
285
286
  label = dframe.name
286
- values = dframe.values.tolist()
287
+ values = dframe.to_numpy().tolist()
287
288
  else:
288
289
  values = dframe.iloc[:, column_nmbr].tolist()
289
290
  if isinstance(dframe.columns, MultiIndex):
290
291
  if check_if_none(
291
- dframe.columns.get_level_values(0).values[column_nmbr]
292
+ dframe.columns.get_level_values(0).to_numpy()[column_nmbr],
292
293
  ):
293
294
  print(
294
295
  "checked item",
295
- dframe.columns.get_level_values(0).values[column_nmbr],
296
+ dframe.columns.get_level_values(0).to_numpy()[column_nmbr],
296
297
  )
297
298
  label = "Series"
298
299
  print(f"label missing. Adding '{label}' as label")
299
300
  else:
300
- label = dframe.columns.get_level_values(0).values[column_nmbr]
301
+ label = dframe.columns.get_level_values(0).to_numpy()[column_nmbr]
301
302
  if check_if_none(
302
- dframe.columns.get_level_values(1).values[column_nmbr]
303
+ dframe.columns.get_level_values(1).to_numpy()[column_nmbr],
303
304
  ):
304
305
  valuetype = ValueType.PRICE
305
306
  print(
306
- f"valuetype missing. Adding '{valuetype.value}' as valuetype"
307
+ f"valuetype missing. Adding '{valuetype.value}' as valuetype",
307
308
  )
308
309
  else:
309
- valuetype = dframe.columns.get_level_values(1).values[column_nmbr]
310
+ valuetype = dframe.columns.get_level_values(1).to_numpy()[
311
+ column_nmbr
312
+ ]
310
313
  else:
311
- label = dframe.columns.values[column_nmbr]
314
+ label = dframe.columns.to_numpy()[column_nmbr]
312
315
  dates = [date_fix(d).strftime("%Y-%m-%d") for d in dframe.index]
313
316
 
314
317
  return cls(
@@ -331,7 +334,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
331
334
 
332
335
  @classmethod
333
336
  def from_fixed_rate(
334
- cls: Type[TypeOpenTimeSeries],
337
+ cls: type[TypeOpenTimeSeries],
335
338
  rate: float,
336
339
  d_range: Optional[DatetimeIndex] = None,
337
340
  days: Optional[int] = None,
@@ -341,7 +344,8 @@ class OpenTimeSeries(BaseModel, CommonModel):
341
344
  baseccy: CurrencyStringType = "SEK",
342
345
  local_ccy: bool = True,
343
346
  ) -> TypeOpenTimeSeries:
344
- """Creates a timeseries from values accruing with a given fixed rate return
347
+ """
348
+ Create series from values accruing with a given fixed rate return.
345
349
 
346
350
  Providing a date_range of type Pandas DatetimeIndex takes priority over
347
351
  providing a combination of days and an end date.
@@ -374,11 +378,11 @@ class OpenTimeSeries(BaseModel, CommonModel):
374
378
  """
375
379
  if not isinstance(d_range, DatetimeIndex) and all([days, end_dt]):
376
380
  d_range = DatetimeIndex(
377
- [d.date() for d in date_range(periods=days, end=end_dt, freq="D")]
381
+ [d.date() for d in date_range(periods=days, end=end_dt, freq="D")],
378
382
  )
379
383
  elif not isinstance(d_range, DatetimeIndex) and not all([days, end_dt]):
380
384
  raise ValueError(
381
- "If d_range is not provided both days and end_dt must be."
385
+ "If d_range is not provided both days and end_dt must be.",
382
386
  )
383
387
 
384
388
  deltas = array(
@@ -386,7 +390,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
386
390
  i.days
387
391
  for i in cast(DatetimeIndex, d_range)[1:]
388
392
  - cast(DatetimeIndex, d_range)[:-1]
389
- ]
393
+ ],
390
394
  )
391
395
  arr = list(cumprod(insert(1 + deltas * rate / 365, 0, 1.0)))
392
396
  d_range = [d.strftime("%Y-%m-%d") for d in cast(DatetimeIndex, d_range)]
@@ -410,19 +414,19 @@ class OpenTimeSeries(BaseModel, CommonModel):
410
414
  )
411
415
 
412
416
  def from_deepcopy(self: TypeOpenTimeSeries) -> TypeOpenTimeSeries:
413
- """Creates a copy of an OpenTimeSeries object
417
+ """
418
+ Create copy of OpenTimeSeries object.
414
419
 
415
420
  Returns
416
421
  -------
417
422
  OpenTimeSeries
418
423
  An OpenTimeSeries object
419
424
  """
420
-
421
425
  return deepcopy(self)
422
426
 
423
427
  def pandas_df(self: TypeOpenTimeSeries) -> TypeOpenTimeSeries:
424
- """Sets the .tsdf parameter as a Pandas DataFrame from the .dates and
425
- .values lists
428
+ """
429
+ Populate .tsdf Pandas DataFrame from the .dates and .values lists.
426
430
 
427
431
  Returns
428
432
  -------
@@ -437,7 +441,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
437
441
  )
438
442
  dframe.index = [d.date() for d in DatetimeIndex(dframe.index)]
439
443
 
440
- dframe.sort_index(inplace=True)
444
+ dframe = dframe.sort_index()
441
445
  self.tsdf = dframe
442
446
 
443
447
  return self
@@ -448,7 +452,8 @@ class OpenTimeSeries(BaseModel, CommonModel):
448
452
  from_dt: Optional[dt.date] = None,
449
453
  to_dt: Optional[dt.date] = None,
450
454
  ) -> tuple[dt.date, dt.date]:
451
- """Creates user defined date range
455
+ """
456
+ Create user defined date range.
452
457
 
453
458
  Parameters
454
459
  ----------
@@ -466,12 +471,15 @@ class OpenTimeSeries(BaseModel, CommonModel):
466
471
  Start and end date of the chosen date range
467
472
  """
468
473
  return get_calc_range(
469
- data=self.tsdf, months_offset=months_offset, from_dt=from_dt, to_dt=to_dt
474
+ data=self.tsdf,
475
+ months_offset=months_offset,
476
+ from_dt=from_dt,
477
+ to_dt=to_dt,
470
478
  )
471
479
 
472
480
  def align_index_to_local_cdays(self: TypeOpenTimeSeries) -> TypeOpenTimeSeries:
473
- """Changes the index of the associated Pandas DataFrame .tsdf to align with
474
- local calendar business days
481
+ """
482
+ Align the index .tsdf with local calendar business days.
475
483
 
476
484
  Returns
477
485
  -------
@@ -479,14 +487,17 @@ class OpenTimeSeries(BaseModel, CommonModel):
479
487
  An OpenTimeSeries object
480
488
  """
481
489
  self.tsdf = align_dataframe_to_local_cdays(
482
- data=self.tsdf, countries=self.countries
490
+ data=self.tsdf,
491
+ countries=self.countries,
483
492
  )
484
493
  return self
485
494
 
486
495
  def all_properties(
487
- self: TypeOpenTimeSeries, properties: Optional[list[LiteralSeriesProps]] = None
496
+ self: TypeOpenTimeSeries,
497
+ properties: Optional[list[LiteralSeriesProps]] = None,
488
498
  ) -> DataFrame:
489
- """Calculates the chosen timeseries properties
499
+ """
500
+ Calculate chosen properties.
490
501
 
491
502
  Parameters
492
503
  ----------
@@ -498,10 +509,10 @@ class OpenTimeSeries(BaseModel, CommonModel):
498
509
  pandas.DataFrame
499
510
  Properties of the OpenTimeSeries
500
511
  """
501
-
502
512
  if not properties:
503
513
  properties = cast(
504
- list[LiteralSeriesProps], OpenTimeSeriesPropertiesList.allowed_strings
514
+ list[LiteralSeriesProps],
515
+ OpenTimeSeriesPropertiesList.allowed_strings,
505
516
  )
506
517
 
507
518
  props = OpenTimeSeriesPropertiesList(*properties)
@@ -512,24 +523,26 @@ class OpenTimeSeries(BaseModel, CommonModel):
512
523
  @property
513
524
  def worst_month(self: TypeOpenTimeSeries) -> float:
514
525
  """
526
+ Most negative month.
527
+
515
528
  Returns
516
529
  -------
517
530
  float
518
531
  Most negative month
519
532
  """
520
-
521
533
  resdf = self.tsdf.copy()
522
534
  resdf.index = DatetimeIndex(resdf.index)
523
535
  return float((resdf.resample("BM").last().pct_change().min()).iloc[0])
524
536
 
525
537
  def value_to_ret(self: TypeOpenTimeSeries) -> TypeOpenTimeSeries:
526
538
  """
539
+ Convert series of values into series of returns.
540
+
527
541
  Returns
528
542
  -------
529
543
  OpenTimeSeries
530
544
  The returns of the values in the series
531
545
  """
532
-
533
546
  self.tsdf = self.tsdf.pct_change()
534
547
  self.tsdf.iloc[0] = 0
535
548
  self.valuetype = ValueType.RTRN
@@ -537,9 +550,11 @@ class OpenTimeSeries(BaseModel, CommonModel):
537
550
  return self
538
551
 
539
552
  def value_to_diff(
540
- self: TypeOpenTimeSeries, periods: int = 1
553
+ self: TypeOpenTimeSeries,
554
+ periods: int = 1,
541
555
  ) -> TypeOpenTimeSeries:
542
- """Converts a valueseries to a series of its period differences
556
+ """
557
+ Convert series of values to series of their period differences.
543
558
 
544
559
  Parameters
545
560
  ----------
@@ -552,7 +567,6 @@ class OpenTimeSeries(BaseModel, CommonModel):
552
567
  OpenTimeSeries
553
568
  An OpenTimeSeries object
554
569
  """
555
-
556
570
  self.tsdf = self.tsdf.diff(periods=periods)
557
571
  self.tsdf.iloc[0] = 0
558
572
  self.valuetype = ValueType.RTRN
@@ -560,7 +574,8 @@ class OpenTimeSeries(BaseModel, CommonModel):
560
574
  return self
561
575
 
562
576
  def to_cumret(self: TypeOpenTimeSeries) -> TypeOpenTimeSeries:
563
- """Converts a returnseries into a cumulative valueseries
577
+ """
578
+ Convert series of returns into cumulative series of values.
564
579
 
565
580
  Returns
566
581
  -------
@@ -569,7 +584,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
569
584
  """
570
585
  if not any(
571
586
  x == ValueType.RTRN
572
- for x in cast(MultiIndex, self.tsdf.columns).get_level_values(1).values
587
+ for x in cast(MultiIndex, self.tsdf.columns).get_level_values(1).to_numpy()
573
588
  ):
574
589
  self.value_to_ret()
575
590
 
@@ -580,9 +595,12 @@ class OpenTimeSeries(BaseModel, CommonModel):
580
595
  return self
581
596
 
582
597
  def from_1d_rate_to_cumret(
583
- self: TypeOpenTimeSeries, days_in_year: int = 365, divider: float = 1.0
598
+ self: TypeOpenTimeSeries,
599
+ days_in_year: int = 365,
600
+ divider: float = 1.0,
584
601
  ) -> TypeOpenTimeSeries:
585
- """Converts a series of 1-day rates into a cumulative valueseries
602
+ """
603
+ Convert series of 1-day rates into series of cumulative values.
586
604
 
587
605
  Parameters
588
606
  ----------
@@ -596,7 +614,6 @@ class OpenTimeSeries(BaseModel, CommonModel):
596
614
  OpenTimeSeries
597
615
  An OpenTimeSeries object
598
616
  """
599
-
600
617
  arr = array(self.values) / divider
601
618
 
602
619
  deltas = array([i.days for i in self.tsdf.index[1:] - self.tsdf.index[:-1]])
@@ -610,9 +627,11 @@ class OpenTimeSeries(BaseModel, CommonModel):
610
627
  return self
611
628
 
612
629
  def resample(
613
- self: TypeOpenTimeSeries, freq: Union[LiteralBizDayFreq, str] = "BM"
630
+ self: TypeOpenTimeSeries,
631
+ freq: Union[LiteralBizDayFreq, str] = "BM",
614
632
  ) -> TypeOpenTimeSeries:
615
- """Resamples the timeseries frequency
633
+ """
634
+ Resamples the timeseries frequency.
616
635
 
617
636
  Parameters
618
637
  ----------
@@ -625,7 +644,6 @@ class OpenTimeSeries(BaseModel, CommonModel):
625
644
  OpenTimeSeries
626
645
  An OpenTimeSeries object
627
646
  """
628
-
629
647
  self.tsdf.index = DatetimeIndex(self.tsdf.index)
630
648
  self.tsdf = self.tsdf.resample(freq).last()
631
649
  self.tsdf.index = [d.date() for d in DatetimeIndex(self.tsdf.index)]
@@ -637,9 +655,10 @@ class OpenTimeSeries(BaseModel, CommonModel):
637
655
  convention: LiteralPandasResampleConvention = "end",
638
656
  method: LiteralPandasReindexMethod = "nearest",
639
657
  ) -> TypeOpenTimeSeries:
640
- """Resamples timeseries frequency to the business calendar
641
- month end dates of each period while leaving any stubs
642
- in place
658
+ """
659
+ Resamples timeseries frequency to the business calendar month end dates.
660
+
661
+ Stubs left in place. Stubs will be aligned to the shortest stub.
643
662
 
644
663
  Parameters
645
664
  ----------
@@ -655,7 +674,6 @@ class OpenTimeSeries(BaseModel, CommonModel):
655
674
  OpenTimeSeries
656
675
  An OpenTimeSeries object
657
676
  """
658
-
659
677
  head = self.tsdf.iloc[0].copy()
660
678
  tail = self.tsdf.iloc[-1].copy()
661
679
  dates = do_resample_to_business_period_ends(
@@ -671,13 +689,14 @@ class OpenTimeSeries(BaseModel, CommonModel):
671
689
 
672
690
  def drawdown_details(self: TypeOpenTimeSeries) -> DataFrame:
673
691
  """
692
+ Details of the maximum drawdown.
693
+
674
694
  Returns
675
695
  -------
676
696
  Pandas.DataFrame
677
697
  Calculates 'Max Drawdown', 'Start of drawdown', 'Date of bottom',
678
698
  'Days from start to bottom', & 'Average fall per day'
679
699
  """
680
-
681
700
  dddf = self.tsdf.copy()
682
701
  dddf.index = DatetimeIndex(dddf.index)
683
702
  return drawdown_details(dddf).to_frame()
@@ -692,8 +711,10 @@ class OpenTimeSeries(BaseModel, CommonModel):
692
711
  to_date: Optional[dt.date] = None,
693
712
  periods_in_a_year_fixed: Optional[int] = None,
694
713
  ) -> Series:
695
- """Exponentially Weighted Moving Average Model for Volatility.
696
- https://www.investopedia.com/articles/07/ewma.asp
714
+ """
715
+ Exponentially Weighted Moving Average Model for Volatility.
716
+
717
+ https://www.investopedia.com/articles/07/ewma.asp.
697
718
 
698
719
  Parameters
699
720
  ----------
@@ -718,13 +739,13 @@ class OpenTimeSeries(BaseModel, CommonModel):
718
739
  Pandas.DataFrame
719
740
  Series EWMA volatility
720
741
  """
721
-
722
742
  earlier, later = self.calc_range(months_from_last, from_date, to_date)
723
743
  if periods_in_a_year_fixed:
724
744
  time_factor = float(periods_in_a_year_fixed)
725
745
  else:
726
746
  how_many = self.tsdf.loc[
727
- cast(int, earlier) : cast(int, later), self.tsdf.columns.values[0]
747
+ cast(int, earlier) : cast(int, later),
748
+ self.tsdf.columns.to_numpy()[0],
728
749
  ].count()
729
750
  fraction = (later - earlier).days / 365.25
730
751
  time_factor = how_many / fraction
@@ -732,14 +753,14 @@ class OpenTimeSeries(BaseModel, CommonModel):
732
753
  data = self.tsdf.loc[cast(int, earlier) : cast(int, later)].copy()
733
754
 
734
755
  data[self.label, "Returns"] = (
735
- data.loc[:, self.tsdf.columns.values[0]].apply(log).diff()
756
+ data.loc[:, self.tsdf.columns.to_numpy()[0]].apply(log).diff()
736
757
  )
737
758
 
738
759
  rawdata = [
739
760
  data.loc[:, (self.label, "Returns")]
740
761
  .iloc[1:day_chunk]
741
762
  .std(ddof=dlta_degr_freedms)
742
- * sqrt(time_factor)
763
+ * sqrt(time_factor),
743
764
  ]
744
765
 
745
766
  for item in data.loc[:, (self.label, "Returns")].iloc[1:]:
@@ -750,7 +771,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
750
771
  prev_ewma=previous,
751
772
  time_factor=time_factor,
752
773
  lmbda=lmbda,
753
- )
774
+ ),
754
775
  )
755
776
 
756
777
  data.loc[:, (self.label, ValueType.EWMA)] = rawdata
@@ -758,9 +779,12 @@ class OpenTimeSeries(BaseModel, CommonModel):
758
779
  return data.loc[:, (self.label, ValueType.EWMA)]
759
780
 
760
781
  def running_adjustment(
761
- self: TypeOpenTimeSeries, adjustment: float, days_in_year: int = 365
782
+ self: TypeOpenTimeSeries,
783
+ adjustment: float,
784
+ days_in_year: int = 365,
762
785
  ) -> TypeOpenTimeSeries:
763
- """Adds (+) or subtracts (-) a fee from the timeseries return
786
+ """
787
+ Add (+) or subtract (-) a fee from the timeseries return.
764
788
 
765
789
  Parameters
766
790
  ----------
@@ -778,7 +802,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
778
802
  values: list[float]
779
803
  if any(
780
804
  x == ValueType.RTRN
781
- for x in cast(MultiIndex, self.tsdf.columns).get_level_values(1).values
805
+ for x in cast(MultiIndex, self.tsdf.columns).get_level_values(1).to_numpy()
782
806
  ):
783
807
  ra_df = self.tsdf.copy()
784
808
  values = [1.0]
@@ -787,7 +811,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
787
811
  values = [self.tsdf.iloc[0, 0]]
788
812
  ra_df = self.tsdf.pct_change().copy()
789
813
  returns_input = False
790
- ra_df.dropna(inplace=True)
814
+ ra_df = ra_df.dropna()
791
815
 
792
816
  prev = self.first_idx
793
817
  idx: dt.date
@@ -797,7 +821,7 @@ class OpenTimeSeries(BaseModel, CommonModel):
797
821
  dates.append(idx)
798
822
  values.append(
799
823
  values[-1]
800
- * (1 + row.iloc[0] + adjustment * (idx - prev).days / days_in_year)
824
+ * (1 + row.iloc[0] + adjustment * (idx - prev).days / days_in_year),
801
825
  )
802
826
  prev = idx
803
827
  self.tsdf = DataFrame(data=values, index=dates)
@@ -814,8 +838,8 @@ class OpenTimeSeries(BaseModel, CommonModel):
814
838
  lvl_one: Optional[ValueType] = None,
815
839
  delete_lvl_one: bool = False,
816
840
  ) -> TypeOpenTimeSeries:
817
- """Sets the column labels of the .tsdf Pandas Dataframe associated
818
- with the timeseries
841
+ """
842
+ Set the column labels of the .tsdf Pandas Dataframe.
819
843
 
820
844
  Parameters
821
845
  ----------
@@ -831,10 +855,9 @@ class OpenTimeSeries(BaseModel, CommonModel):
831
855
  OpenTimeSeries
832
856
  An OpenTimeSeries object
833
857
  """
834
-
835
858
  if lvl_zero is None and lvl_one is None:
836
859
  self.tsdf.columns = MultiIndex.from_arrays(
837
- [[self.label], [self.valuetype]]
860
+ [[self.label], [self.valuetype]],
838
861
  )
839
862
  elif lvl_zero is not None and lvl_one is None:
840
863
  self.tsdf.columns = MultiIndex.from_arrays([[lvl_zero], [self.valuetype]])
@@ -855,7 +878,8 @@ def timeseries_chain(
855
878
  back: TypeOpenTimeSeries,
856
879
  old_fee: float = 0.0,
857
880
  ) -> Union[TypeOpenTimeSeries, OpenTimeSeries]:
858
- """Chain two timeseries together
881
+ """
882
+ Chain two timeseries together.
859
883
 
860
884
  Parameters
861
885
  ----------
@@ -868,7 +892,7 @@ def timeseries_chain(
868
892
 
869
893
  Returns
870
894
  -------
871
- TypeOpenTimeSeries
895
+ Union[TypeOpenTimeSeries, OpenTimeSeries]
872
896
  An OpenTimeSeries object or a subclass thereof
873
897
  """
874
898
  old = front.from_deepcopy()
@@ -889,17 +913,17 @@ def timeseries_chain(
889
913
  raise ValueError("Failed to find a matching date between series")
890
914
 
891
915
  dates: list[str] = [x.strftime("%Y-%m-%d") for x in olddf.index if x < first]
892
- values = array([x[0] for x in old.tsdf.values][: len(dates)])
916
+ values = array([x[0] for x in old.tsdf.to_numpy()][: len(dates)])
893
917
  values = cast(
894
918
  NDArray[float64],
895
919
  list(values * new.tsdf.iloc[:, 0].loc[first] / olddf.iloc[:, 0].loc[first]),
896
920
  )
897
921
 
898
922
  dates.extend([x.strftime("%Y-%m-%d") for x in new.tsdf.index])
899
- values += [x[0] for x in new.tsdf.values]
923
+ values += [x[0] for x in new.tsdf.to_numpy()]
900
924
 
901
- if back.__class__.__subclasscheck__( # pylint: disable=unnecessary-dunder-call
902
- OpenTimeSeries
925
+ if back.__class__.__subclasscheck__(
926
+ OpenTimeSeries,
903
927
  ):
904
928
  return OpenTimeSeries(
905
929
  timeseriesId=new.timeseriesId,
@@ -937,8 +961,9 @@ def timeseries_chain(
937
961
  )
938
962
 
939
963
 
940
- def check_if_none(item: Any) -> bool:
941
- """Function to check if a variable is None or equivalent
964
+ def check_if_none(item: Any) -> bool: # noqa: ANN401
965
+ """
966
+ Check if a variable is None or equivalent.
942
967
 
943
968
  Parameters
944
969
  ----------