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/load_plotly.py CHANGED
@@ -5,18 +5,19 @@ from __future__ import annotations
5
5
  from json import load
6
6
  from logging import warning
7
7
  from pathlib import Path
8
+ from typing import TYPE_CHECKING
8
9
 
9
10
  import requests
10
11
  from requests.exceptions import ConnectionError
11
12
 
12
- from openseries.types import CaptorLogoType, PlotlyLayoutType
13
+ if TYPE_CHECKING:
14
+ from .types import CaptorLogoType, PlotlyLayoutType # pragma: no cover
13
15
 
14
16
  __all__ = ["load_plotly_dict"]
15
17
 
16
18
 
17
19
  def _check_remote_file_existence(url: str) -> bool:
18
- """
19
- Check if remote file exists.
20
+ """Check if remote file exists.
20
21
 
21
22
  Parameters
22
23
  ----------
@@ -44,8 +45,7 @@ def load_plotly_dict(
44
45
  *,
45
46
  responsive: bool = True,
46
47
  ) -> tuple[PlotlyLayoutType, CaptorLogoType]:
47
- """
48
- Load Plotly defaults.
48
+ """Load Plotly defaults.
49
49
 
50
50
  Parameters
51
51
  ----------
@@ -58,13 +58,13 @@ def load_plotly_dict(
58
58
  A dictionary with the Plotly config and layout template
59
59
 
60
60
  """
61
- project_root = Path(__file__).resolve().parent.parent
61
+ project_root = Path(__file__).parent.parent
62
62
  layoutfile = project_root.joinpath("openseries").joinpath("plotly_layouts.json")
63
63
  logofile = project_root.joinpath("openseries").joinpath("plotly_captor_logo.json")
64
64
 
65
- with Path.open(layoutfile, mode="r", encoding="utf-8") as layout_file:
65
+ with layoutfile.open(mode="r", encoding="utf-8") as layout_file:
66
66
  fig = load(layout_file)
67
- with Path.open(logofile, mode="r", encoding="utf-8") as logo_file:
67
+ with logofile.open(mode="r", encoding="utf-8") as logo_file:
68
68
  logo = load(logo_file)
69
69
 
70
70
  if _check_remote_file_existence(url=logo["source"]) is False:
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
 
6
6
  from inspect import stack
7
7
  from pathlib import Path
8
- from typing import Callable, Optional, Union, cast
8
+ from typing import TYPE_CHECKING, Callable, cast
9
9
 
10
10
  from numpy import (
11
11
  append,
@@ -30,15 +30,14 @@ from pandas import (
30
30
  from plotly.graph_objs import Figure # type: ignore[import-untyped,unused-ignore]
31
31
  from plotly.io import to_html # type: ignore[import-untyped,unused-ignore]
32
32
  from plotly.offline import plot # type: ignore[import-untyped,unused-ignore]
33
- from pydantic import DirectoryPath
34
33
  from scipy.optimize import minimize # type: ignore[import-untyped,unused-ignore]
35
34
 
35
+ from .load_plotly import load_plotly_dict
36
+ from .series import OpenTimeSeries
37
+
36
38
  # noinspection PyProtectedMember
37
- from openseries.frame import OpenFrame
38
- from openseries.load_plotly import load_plotly_dict
39
- from openseries.series import OpenTimeSeries
40
- from openseries.simulation import _random_generator
41
- from openseries.types import (
39
+ from .simulation import _random_generator
40
+ from .types import (
42
41
  LiteralLinePlotMode,
43
42
  LiteralMinimizeMethods,
44
43
  LiteralPlotlyJSlib,
@@ -46,6 +45,11 @@ from openseries.types import (
46
45
  ValueType,
47
46
  )
48
47
 
48
+ if TYPE_CHECKING: # pragma: no cover
49
+ from pydantic import DirectoryPath
50
+
51
+ from .frame import OpenFrame
52
+
49
53
  __all__ = [
50
54
  "constrain_optimized_portfolios",
51
55
  "efficient_frontier",
@@ -60,8 +64,7 @@ def simulate_portfolios(
60
64
  num_ports: int,
61
65
  seed: int,
62
66
  ) -> DataFrame:
63
- """
64
- Generate random weights for simulated portfolios.
67
+ """Generate random weights for simulated portfolios.
65
68
 
66
69
  Parameters
67
70
  ----------
@@ -130,14 +133,13 @@ def efficient_frontier( # noqa: C901
130
133
  eframe: OpenFrame,
131
134
  num_ports: int = 5000,
132
135
  seed: int = 71,
133
- bounds: Optional[tuple[tuple[float]]] = None,
136
+ bounds: tuple[tuple[float]] | None = None,
134
137
  frontier_points: int = 200,
135
138
  minimize_method: LiteralMinimizeMethods = "SLSQP",
136
139
  *,
137
140
  tweak: bool = True,
138
141
  ) -> tuple[DataFrame, DataFrame, NDArray[float64]]:
139
- """
140
- Identify an efficient frontier.
142
+ """Identify an efficient frontier.
141
143
 
142
144
  Parameters
143
145
  ----------
@@ -258,7 +260,7 @@ def efficient_frontier( # noqa: C901
258
260
 
259
261
  for possible_return in frontier_y:
260
262
  cons = cast(
261
- dict[str, Union[str, Callable[[float, NDArray[float64]], float64]]],
263
+ dict[str, str | Callable[[float, NDArray[float64]], float64]],
262
264
  (
263
265
  {"type": "eq", "fun": _check_sum},
264
266
  {
@@ -319,11 +321,10 @@ def constrain_optimized_portfolios(
319
321
  portfolioname: str = "Current Portfolio",
320
322
  simulations: int = 10000,
321
323
  curve_points: int = 200,
322
- bounds: Optional[tuple[tuple[float]]] = None,
324
+ bounds: tuple[tuple[float]] | None = None,
323
325
  minimize_method: LiteralMinimizeMethods = "SLSQP",
324
326
  ) -> tuple[OpenFrame, OpenTimeSeries, OpenFrame, OpenTimeSeries]:
325
- """
326
- Constrain optimized portfolios to those that improve on the current one.
327
+ """Constrain optimized portfolios to those that improve on the current one.
327
328
 
328
329
  Parameters
329
330
  ----------
@@ -391,8 +392,7 @@ def prepare_plot_data(
391
392
  current: OpenTimeSeries,
392
393
  optimized: NDArray[float64],
393
394
  ) -> DataFrame:
394
- """
395
- Prepare date to be used as point_frame in the sharpeplot function.
395
+ """Prepare date to be used as point_frame in the sharpeplot function.
396
396
 
397
397
  Parameters
398
398
  ----------
@@ -443,13 +443,13 @@ def prepare_plot_data(
443
443
 
444
444
 
445
445
  def sharpeplot( # noqa: C901
446
- sim_frame: Optional[DataFrame] = None,
447
- line_frame: Optional[DataFrame] = None,
448
- point_frame: Optional[DataFrame] = None,
446
+ sim_frame: DataFrame | None = None,
447
+ line_frame: DataFrame | None = None,
448
+ point_frame: DataFrame | None = None,
449
449
  point_frame_mode: LiteralLinePlotMode = "markers",
450
- filename: Optional[str] = None,
451
- directory: Optional[DirectoryPath] = None,
452
- titletext: Optional[str] = None,
450
+ filename: str | None = None,
451
+ directory: DirectoryPath | None = None,
452
+ titletext: str | None = None,
453
453
  output_type: LiteralPlotlyOutput = "file",
454
454
  include_plotlyjs: LiteralPlotlyJSlib = "cdn",
455
455
  *,
@@ -457,8 +457,7 @@ def sharpeplot( # noqa: C901
457
457
  add_logo: bool = True,
458
458
  auto_open: bool = True,
459
459
  ) -> tuple[Figure, str]:
460
- """
461
- Create scatter plot coloured by Sharpe Ratio.
460
+ """Create scatter plot coloured by Sharpe Ratio.
462
461
 
463
462
  Parameters
464
463
  ----------
openseries/series.py CHANGED
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import datetime as dt
6
6
  from copy import deepcopy
7
7
  from logging import warning
8
- from typing import Any, Optional, TypeVar, Union, cast
8
+ from typing import Any, TypeVar, cast
9
9
 
10
10
  from numpy import (
11
11
  append,
@@ -28,9 +28,9 @@ from pandas import (
28
28
  from pydantic import model_validator
29
29
  from typing_extensions import Self
30
30
 
31
- from openseries._common_model import _CommonModel
32
- from openseries.datefixer import date_fix, do_resample_to_business_period_ends
33
- from openseries.types import (
31
+ from ._common_model import _CommonModel
32
+ from .datefixer import date_fix, do_resample_to_business_period_ends
33
+ from .types import (
34
34
  Countries,
35
35
  CountriesType,
36
36
  Currency,
@@ -53,9 +53,7 @@ TypeOpenTimeSeries = TypeVar("TypeOpenTimeSeries", bound="OpenTimeSeries")
53
53
 
54
54
  # noinspection PyUnresolvedReferences
55
55
  class OpenTimeSeries(_CommonModel):
56
-
57
- """
58
- OpenTimeSeries objects are at the core of the openseries package.
56
+ """OpenTimeSeries objects are at the core of the openseries package.
59
57
 
60
58
  The intended use is to allow analyses of financial timeseries.
61
59
  It is only intended for daily or less frequent data samples.
@@ -104,8 +102,8 @@ class OpenTimeSeries(_CommonModel):
104
102
  currency: CurrencyStringType
105
103
  domestic: CurrencyStringType = "SEK"
106
104
  countries: CountriesType = "SE"
107
- isin: Optional[str] = None
108
- label: Optional[str] = None
105
+ isin: str | None = None
106
+ label: str | None = None
109
107
 
110
108
  @model_validator(mode="after") # type: ignore[misc,unused-ignore]
111
109
  def dates_and_values_validate(self: Self) -> Self:
@@ -134,8 +132,7 @@ class OpenTimeSeries(_CommonModel):
134
132
  domestic_ccy: CurrencyStringType = "SEK",
135
133
  countries: CountriesType = "SE",
136
134
  ) -> None:
137
- """
138
- Set the domestic currency and calendar of the user.
135
+ """Set the domestic currency and calendar of the user.
139
136
 
140
137
  Parameters
141
138
  ----------
@@ -160,13 +157,12 @@ class OpenTimeSeries(_CommonModel):
160
157
  valuetype: ValueType = ValueType.PRICE,
161
158
  timeseries_id: DatabaseIdStringType = "",
162
159
  instrument_id: DatabaseIdStringType = "",
163
- isin: Optional[str] = None,
160
+ isin: str | None = None,
164
161
  baseccy: CurrencyStringType = "SEK",
165
162
  *,
166
163
  local_ccy: bool = True,
167
164
  ) -> OpenTimeSeries:
168
- """
169
- Create series from a Pandas DataFrame or Series.
165
+ """Create series from a Pandas DataFrame or Series.
170
166
 
171
167
  Parameters
172
168
  ----------
@@ -217,19 +213,18 @@ class OpenTimeSeries(_CommonModel):
217
213
  @classmethod
218
214
  def from_df(
219
215
  cls: type[OpenTimeSeries],
220
- dframe: Union[DataFrame, Series[float]],
216
+ dframe: DataFrame | Series[float],
221
217
  column_nmbr: int = 0,
222
218
  valuetype: ValueType = ValueType.PRICE,
223
219
  baseccy: CurrencyStringType = "SEK",
224
220
  *,
225
221
  local_ccy: bool = True,
226
222
  ) -> OpenTimeSeries:
227
- """
228
- Create series from a Pandas DataFrame or Series.
223
+ """Create series from a Pandas DataFrame or Series.
229
224
 
230
225
  Parameters
231
226
  ----------
232
- dframe: Union[DataFrame, Series[float]]
227
+ dframe: DataFrame | Series[float]
233
228
  Pandas DataFrame or Series
234
229
  column_nmbr : int, default: 0
235
230
  Using iloc[:, column_nmbr] to pick column
@@ -299,17 +294,16 @@ class OpenTimeSeries(_CommonModel):
299
294
  def from_fixed_rate(
300
295
  cls: type[OpenTimeSeries],
301
296
  rate: float,
302
- d_range: Optional[DatetimeIndex] = None,
303
- days: Optional[int] = None,
304
- end_dt: Optional[dt.date] = None,
297
+ d_range: DatetimeIndex | None = None,
298
+ days: int | None = None,
299
+ end_dt: dt.date | None = None,
305
300
  label: str = "Series",
306
301
  valuetype: ValueType = ValueType.PRICE,
307
302
  baseccy: CurrencyStringType = "SEK",
308
303
  *,
309
304
  local_ccy: bool = True,
310
305
  ) -> OpenTimeSeries:
311
- """
312
- Create series from values accruing with a given fixed rate return.
306
+ """Create series from values accruing with a given fixed rate return.
313
307
 
314
308
  Providing a date_range of type Pandas DatetimeIndex takes priority over
315
309
  providing a combination of days and an end date.
@@ -380,8 +374,7 @@ class OpenTimeSeries(_CommonModel):
380
374
  )
381
375
 
382
376
  def from_deepcopy(self: Self) -> Self:
383
- """
384
- Create copy of OpenTimeSeries object.
377
+ """Create copy of OpenTimeSeries object.
385
378
 
386
379
  Returns
387
380
  -------
@@ -392,8 +385,7 @@ class OpenTimeSeries(_CommonModel):
392
385
  return deepcopy(self)
393
386
 
394
387
  def pandas_df(self: Self) -> Self:
395
- """
396
- Populate .tsdf Pandas DataFrame from the .dates and .values lists.
388
+ """Populate .tsdf Pandas DataFrame from the .dates and .values lists.
397
389
 
398
390
  Returns
399
391
  -------
@@ -413,10 +405,9 @@ class OpenTimeSeries(_CommonModel):
413
405
 
414
406
  def all_properties(
415
407
  self: Self,
416
- properties: Optional[list[LiteralSeriesProps]] = None,
408
+ properties: list[LiteralSeriesProps] | None = None,
417
409
  ) -> DataFrame:
418
- """
419
- Calculate chosen properties.
410
+ """Calculate chosen properties.
420
411
 
421
412
  Parameters
422
413
  ----------
@@ -441,8 +432,7 @@ class OpenTimeSeries(_CommonModel):
441
432
  return pdf
442
433
 
443
434
  def value_to_ret(self: Self) -> Self:
444
- """
445
- Convert series of values into series of returns.
435
+ """Convert series of values into series of returns.
446
436
 
447
437
  Returns
448
438
  -------
@@ -450,7 +440,7 @@ class OpenTimeSeries(_CommonModel):
450
440
  The returns of the values in the series
451
441
 
452
442
  """
453
- self.tsdf = self.tsdf.pct_change(fill_method=cast(str, None))
443
+ self.tsdf = self.tsdf.pct_change(fill_method=None) # type: ignore[arg-type]
454
444
  self.tsdf.iloc[0] = 0
455
445
  self.valuetype = ValueType.RTRN
456
446
  self.tsdf.columns = MultiIndex.from_arrays(
@@ -462,8 +452,7 @@ class OpenTimeSeries(_CommonModel):
462
452
  return self
463
453
 
464
454
  def value_to_diff(self: Self, periods: int = 1) -> Self:
465
- """
466
- Convert series of values to series of their period differences.
455
+ """Convert series of values to series of their period differences.
467
456
 
468
457
  Parameters
469
458
  ----------
@@ -489,8 +478,7 @@ class OpenTimeSeries(_CommonModel):
489
478
  return self
490
479
 
491
480
  def to_cumret(self: Self) -> Self:
492
- """
493
- Convert series of returns into cumulative series of values.
481
+ """Convert series of returns into cumulative series of values.
494
482
 
495
483
  Returns
496
484
  -------
@@ -520,8 +508,7 @@ class OpenTimeSeries(_CommonModel):
520
508
  days_in_year: int = 365,
521
509
  divider: float = 1.0,
522
510
  ) -> Self:
523
- """
524
- Convert series of 1-day rates into series of cumulative values.
511
+ """Convert series of 1-day rates into series of cumulative values.
525
512
 
526
513
  Parameters
527
514
  ----------
@@ -555,14 +542,13 @@ class OpenTimeSeries(_CommonModel):
555
542
 
556
543
  def resample(
557
544
  self: Self,
558
- freq: Union[LiteralBizDayFreq, str] = "BME",
545
+ freq: LiteralBizDayFreq | str = "BME",
559
546
  ) -> Self:
560
- """
561
- Resamples the timeseries frequency.
547
+ """Resamples the timeseries frequency.
562
548
 
563
549
  Parameters
564
550
  ----------
565
- freq: Union[LiteralBizDayFreq, str], default "BME"
551
+ freq: LiteralBizDayFreq | str, default "BME"
566
552
  The date offset string that sets the resampled frequency
567
553
 
568
554
  Returns
@@ -581,8 +567,7 @@ class OpenTimeSeries(_CommonModel):
581
567
  freq: LiteralBizDayFreq = "BME",
582
568
  method: LiteralPandasReindexMethod = "nearest",
583
569
  ) -> Self:
584
- """
585
- Resamples timeseries frequency to the business calendar month end dates.
570
+ """Resamples timeseries frequency to the business calendar month end dates.
586
571
 
587
572
  Stubs left in place. Stubs will be aligned to the shortest stub.
588
573
 
@@ -616,13 +601,12 @@ class OpenTimeSeries(_CommonModel):
616
601
  lmbda: float = 0.94,
617
602
  day_chunk: int = 11,
618
603
  dlta_degr_freedms: int = 0,
619
- months_from_last: Optional[int] = None,
620
- from_date: Optional[dt.date] = None,
621
- to_date: Optional[dt.date] = None,
622
- periods_in_a_year_fixed: Optional[DaysInYearType] = None,
604
+ months_from_last: int | None = None,
605
+ from_date: dt.date | None = None,
606
+ to_date: dt.date | None = None,
607
+ periods_in_a_year_fixed: DaysInYearType | None = None,
623
608
  ) -> Series[float]:
624
- """
625
- Exponentially Weighted Moving Average Model for Volatility.
609
+ """Exponentially Weighted Moving Average Model for Volatility.
626
610
 
627
611
  https://www.investopedia.com/articles/07/ewma.asp.
628
612
 
@@ -694,8 +678,7 @@ class OpenTimeSeries(_CommonModel):
694
678
  adjustment: float,
695
679
  days_in_year: int = 365,
696
680
  ) -> Self:
697
- """
698
- Add or subtract a fee from the timeseries return.
681
+ """Add or subtract a fee from the timeseries return.
699
682
 
700
683
  Parameters
701
684
  ----------
@@ -721,7 +704,7 @@ class OpenTimeSeries(_CommonModel):
721
704
  returns_input = True
722
705
  else:
723
706
  values = [cast(float, self.tsdf.iloc[0, 0])]
724
- ra_df = self.tsdf.pct_change(fill_method=cast(str, None))
707
+ ra_df = self.tsdf.pct_change(fill_method=None) # type: ignore[arg-type]
725
708
  returns_input = False
726
709
  ra_df = ra_df.dropna()
727
710
 
@@ -754,13 +737,12 @@ class OpenTimeSeries(_CommonModel):
754
737
 
755
738
  def set_new_label(
756
739
  self: Self,
757
- lvl_zero: Optional[str] = None,
758
- lvl_one: Optional[ValueType] = None,
740
+ lvl_zero: str | None = None,
741
+ lvl_one: ValueType | None = None,
759
742
  *,
760
743
  delete_lvl_one: bool = False,
761
744
  ) -> Self:
762
- """
763
- Set the column labels of the .tsdf Pandas Dataframe.
745
+ """Set the column labels of the .tsdf Pandas Dataframe.
764
746
 
765
747
  Parameters
766
748
  ----------
@@ -799,9 +781,8 @@ def timeseries_chain(
799
781
  front: TypeOpenTimeSeries,
800
782
  back: TypeOpenTimeSeries,
801
783
  old_fee: float = 0.0,
802
- ) -> Union[TypeOpenTimeSeries, OpenTimeSeries]:
803
- """
804
- Chain two timeseries together.
784
+ ) -> TypeOpenTimeSeries | OpenTimeSeries:
785
+ """Chain two timeseries together.
805
786
 
806
787
  The function assumes that the two series have at least one date in common.
807
788
 
@@ -816,7 +797,7 @@ def timeseries_chain(
816
797
 
817
798
  Returns
818
799
  -------
819
- Union[TypeOpenTimeSeries, OpenTimeSeries]
800
+ TypeOpenTimeSeries | OpenTimeSeries
820
801
  An OpenTimeSeries object or a subclass thereof
821
802
 
822
803
  """
@@ -887,8 +868,7 @@ def timeseries_chain(
887
868
 
888
869
 
889
870
  def _check_if_none(item: Any) -> bool: # noqa: ANN401
890
- """
891
- Check if a variable is None or equivalent.
871
+ """Check if a variable is None or equivalent.
892
872
 
893
873
  Parameters
894
874
  ----------
openseries/simulation.py CHANGED
@@ -2,8 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import datetime as dt
6
- from typing import Optional, cast
5
+ from typing import TYPE_CHECKING, cast
6
+
7
+ if TYPE_CHECKING:
8
+ import datetime as dt # pragma: no cover
7
9
 
8
10
  from numpy import multiply, sqrt
9
11
  from numpy.random import PCG64, Generator, SeedSequence
@@ -22,8 +24,8 @@ from pydantic import (
22
24
  )
23
25
  from typing_extensions import Self
24
26
 
25
- from openseries.datefixer import generate_calendar_date_range
26
- from openseries.types import (
27
+ from .datefixer import generate_calendar_date_range
28
+ from .types import (
27
29
  CountriesType,
28
30
  DaysInYearType,
29
31
  ValueType,
@@ -32,9 +34,8 @@ from openseries.types import (
32
34
  __all__ = ["ReturnSimulation"]
33
35
 
34
36
 
35
- def _random_generator(seed: Optional[int]) -> Generator:
36
- """
37
- Make a Numpy Random Generator object.
37
+ def _random_generator(seed: int | None) -> Generator:
38
+ """Make a Numpy Random Generator object.
38
39
 
39
40
  Parameters
40
41
  ----------
@@ -48,14 +49,12 @@ def _random_generator(seed: Optional[int]) -> Generator:
48
49
 
49
50
  """
50
51
  ss = SeedSequence(entropy=seed)
51
- bg = PCG64(seed=cast(Optional[int], ss))
52
+ bg = PCG64(seed=cast(int | None, ss))
52
53
  return Generator(bit_generator=bg)
53
54
 
54
55
 
55
56
  class ReturnSimulation(BaseModel):
56
-
57
- """
58
- The class ReturnSimulation allows for simulating financial timeseries.
57
+ """The class ReturnSimulation allows for simulating financial timeseries.
59
58
 
60
59
  Parameters
61
60
  ----------
@@ -91,7 +90,7 @@ class ReturnSimulation(BaseModel):
91
90
  jumps_lamda: NonNegativeFloat = 0.0
92
91
  jumps_sigma: NonNegativeFloat = 0.0
93
92
  jumps_mu: float = 0.0
94
- seed: Optional[int] = None
93
+ seed: int | None = None
95
94
 
96
95
  model_config = ConfigDict(
97
96
  arbitrary_types_allowed=True,
@@ -101,8 +100,7 @@ class ReturnSimulation(BaseModel):
101
100
 
102
101
  @property
103
102
  def results(self: Self) -> DataFrame:
104
- """
105
- Simulation data.
103
+ """Simulation data.
106
104
 
107
105
  Returns
108
106
  -------
@@ -114,8 +112,7 @@ class ReturnSimulation(BaseModel):
114
112
 
115
113
  @property
116
114
  def realized_mean_return(self: Self) -> float:
117
- """
118
- Annualized arithmetic mean of returns.
115
+ """Annualized arithmetic mean of returns.
119
116
 
120
117
  Returns
121
118
  -------
@@ -133,8 +130,7 @@ class ReturnSimulation(BaseModel):
133
130
 
134
131
  @property
135
132
  def realized_vol(self: Self) -> float:
136
- """
137
- Annualized volatility.
133
+ """Annualized volatility.
138
134
 
139
135
  Returns
140
136
  -------
@@ -159,10 +155,9 @@ class ReturnSimulation(BaseModel):
159
155
  trading_days: PositiveInt,
160
156
  seed: int,
161
157
  trading_days_in_year: DaysInYearType = 252,
162
- randomizer: Optional[Generator] = None,
158
+ randomizer: Generator | None = None,
163
159
  ) -> ReturnSimulation:
164
- """
165
- Create a Normal distribution simulation.
160
+ """Create a Normal distribution simulation.
166
161
 
167
162
  Parameters
168
163
  ----------
@@ -216,10 +211,9 @@ class ReturnSimulation(BaseModel):
216
211
  trading_days: PositiveInt,
217
212
  seed: int,
218
213
  trading_days_in_year: DaysInYearType = 252,
219
- randomizer: Optional[Generator] = None,
214
+ randomizer: Generator | None = None,
220
215
  ) -> ReturnSimulation:
221
- """
222
- Create a Lognormal distribution simulation.
216
+ """Create a Lognormal distribution simulation.
223
217
 
224
218
  Parameters
225
219
  ----------
@@ -276,10 +270,9 @@ class ReturnSimulation(BaseModel):
276
270
  trading_days: PositiveInt,
277
271
  seed: int,
278
272
  trading_days_in_year: DaysInYearType = 252,
279
- randomizer: Optional[Generator] = None,
273
+ randomizer: Generator | None = None,
280
274
  ) -> ReturnSimulation:
281
- """
282
- Create a Geometric Brownian Motion simulation.
275
+ """Create a Geometric Brownian Motion simulation.
283
276
 
284
277
  Parameters
285
278
  ----------
@@ -342,10 +335,9 @@ class ReturnSimulation(BaseModel):
342
335
  jumps_sigma: NonNegativeFloat = 0.0,
343
336
  jumps_mu: float = 0.0,
344
337
  trading_days_in_year: DaysInYearType = 252,
345
- randomizer: Optional[Generator] = None,
338
+ randomizer: Generator | None = None,
346
339
  ) -> ReturnSimulation:
347
- """
348
- Create a Merton Jump-Diffusion model simulation.
340
+ """Create a Merton Jump-Diffusion model simulation.
349
341
 
350
342
  Parameters
351
343
  ----------
@@ -424,12 +416,11 @@ class ReturnSimulation(BaseModel):
424
416
  def to_dataframe(
425
417
  self: Self,
426
418
  name: str,
427
- start: Optional[dt.date] = None,
428
- end: Optional[dt.date] = None,
419
+ start: dt.date | None = None,
420
+ end: dt.date | None = None,
429
421
  countries: CountriesType = "SE",
430
422
  ) -> DataFrame:
431
- """
432
- Create a pandas.DataFrame from simulation(s).
423
+ """Create a pandas.DataFrame from simulation(s).
433
424
 
434
425
  Parameters
435
426
  ----------