openseries 1.6.0__py3-none-any.whl → 1.7.1__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/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
  -------
@@ -157,12 +153,11 @@ class ReturnSimulation(BaseModel):
157
153
  mean_annual_return: float,
158
154
  mean_annual_vol: PositiveFloat,
159
155
  trading_days: PositiveInt,
160
- seed: int,
161
156
  trading_days_in_year: DaysInYearType = 252,
162
- randomizer: Optional[Generator] = None,
157
+ seed: int | None = 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
  ----------
@@ -174,11 +169,10 @@ class ReturnSimulation(BaseModel):
174
169
  Mean return
175
170
  mean_annual_vol: PositiveFloat
176
171
  Mean standard deviation
177
- seed: int
178
- Seed for random process initiation
179
- trading_days_in_year: DaysInYearType,
180
- default: 252
172
+ trading_days_in_year: DaysInYearType, default: 252
181
173
  Number of trading days used to annualize
174
+ seed: int, optional
175
+ Seed for random process initiation
182
176
  randomizer: numpy.random.Generator, optional
183
177
  Random process generator
184
178
 
@@ -214,12 +208,11 @@ class ReturnSimulation(BaseModel):
214
208
  mean_annual_return: float,
215
209
  mean_annual_vol: PositiveFloat,
216
210
  trading_days: PositiveInt,
217
- seed: int,
218
211
  trading_days_in_year: DaysInYearType = 252,
219
- randomizer: Optional[Generator] = None,
212
+ seed: int | None = None,
213
+ randomizer: Generator | None = None,
220
214
  ) -> ReturnSimulation:
221
- """
222
- Create a Lognormal distribution simulation.
215
+ """Create a Lognormal distribution simulation.
223
216
 
224
217
  Parameters
225
218
  ----------
@@ -231,11 +224,10 @@ class ReturnSimulation(BaseModel):
231
224
  Mean return
232
225
  mean_annual_vol: PositiveFloat
233
226
  Mean standard deviation
234
- seed: int
235
- Seed for random process initiation
236
- trading_days_in_year: DaysInYearType,
237
- default: 252
227
+ trading_days_in_year: DaysInYearType, default: 252
238
228
  Number of trading days used to annualize
229
+ seed: int, optional
230
+ Seed for random process initiation
239
231
  randomizer: numpy.random.Generator, optional
240
232
  Random process generator
241
233
 
@@ -274,12 +266,11 @@ class ReturnSimulation(BaseModel):
274
266
  mean_annual_return: float,
275
267
  mean_annual_vol: PositiveFloat,
276
268
  trading_days: PositiveInt,
277
- seed: int,
278
269
  trading_days_in_year: DaysInYearType = 252,
279
- randomizer: Optional[Generator] = None,
270
+ seed: int | None = None,
271
+ randomizer: Generator | None = None,
280
272
  ) -> ReturnSimulation:
281
- """
282
- Create a Geometric Brownian Motion simulation.
273
+ """Create a Geometric Brownian Motion simulation.
283
274
 
284
275
  Parameters
285
276
  ----------
@@ -291,10 +282,10 @@ class ReturnSimulation(BaseModel):
291
282
  Mean return
292
283
  mean_annual_vol: PositiveFloat
293
284
  Mean standard deviation
294
- seed: int
295
- Seed for random process initiation
296
285
  trading_days_in_year: DaysInYearType, default: 252
297
286
  Number of trading days used to annualize
287
+ seed: int, optional
288
+ Seed for random process initiation
298
289
  randomizer: numpy.random.Generator, optional
299
290
  Random process generator
300
291
 
@@ -337,15 +328,14 @@ class ReturnSimulation(BaseModel):
337
328
  trading_days: PositiveInt,
338
329
  mean_annual_return: float,
339
330
  mean_annual_vol: PositiveFloat,
340
- seed: int,
341
331
  jumps_lamda: NonNegativeFloat,
342
332
  jumps_sigma: NonNegativeFloat = 0.0,
343
333
  jumps_mu: float = 0.0,
344
334
  trading_days_in_year: DaysInYearType = 252,
345
- randomizer: Optional[Generator] = None,
335
+ seed: int | None = None,
336
+ randomizer: Generator | None = None,
346
337
  ) -> ReturnSimulation:
347
- """
348
- Create a Merton Jump-Diffusion model simulation.
338
+ """Create a Merton Jump-Diffusion model simulation.
349
339
 
350
340
  Parameters
351
341
  ----------
@@ -357,8 +347,6 @@ class ReturnSimulation(BaseModel):
357
347
  Mean return
358
348
  mean_annual_vol: PositiveFloat
359
349
  Mean standard deviation
360
- seed: int
361
- Seed for random process initiation
362
350
  jumps_lamda: NonNegativeFloat
363
351
  This is the probability of a jump happening at each point in time
364
352
  jumps_sigma: NonNegativeFloat, default: 0.0
@@ -367,6 +355,8 @@ class ReturnSimulation(BaseModel):
367
355
  This is the average jump size
368
356
  trading_days_in_year: DaysInYearType, default: 252
369
357
  Number of trading days used to annualize
358
+ seed: int, optional
359
+ Seed for random process initiation
370
360
  randomizer: numpy.random.Generator, optional
371
361
  Random process generator
372
362
 
@@ -424,12 +414,11 @@ class ReturnSimulation(BaseModel):
424
414
  def to_dataframe(
425
415
  self: Self,
426
416
  name: str,
427
- start: Optional[dt.date] = None,
428
- end: Optional[dt.date] = None,
417
+ start: dt.date | None = None,
418
+ end: dt.date | None = None,
429
419
  countries: CountriesType = "SE",
430
420
  ) -> DataFrame:
431
- """
432
- Create a pandas.DataFrame from simulation(s).
421
+ """Create a pandas.DataFrame from simulation(s).
433
422
 
434
423
  Parameters
435
424
  ----------
openseries/types.py CHANGED
@@ -33,7 +33,6 @@ CountriesType = Union[CountryListType, CountryStringType] # type: ignore[valid-
33
33
 
34
34
 
35
35
  class Countries(BaseModel):
36
-
37
36
  """Declare Countries."""
38
37
 
39
38
  countryinput: CountriesType
@@ -53,7 +52,6 @@ CurrencyStringType = Annotated[
53
52
 
54
53
 
55
54
  class Currency(BaseModel):
56
-
57
55
  """Declare Currency."""
58
56
 
59
57
  ccy: CurrencyStringType
@@ -90,31 +88,29 @@ DatabaseIdStringType = Annotated[
90
88
 
91
89
  DaysInYearType = Annotated[int, Field(strict=True, ge=1, le=366)]
92
90
 
93
- DateType = Union[str, dt.date, dt.datetime, datetime64, Timestamp]
91
+ DateType = str | dt.date | dt.datetime | datetime64 | Timestamp
94
92
 
95
- HolidayType = Union[
96
- dict[Union[dt.date, dt.datetime, str, float, int], str],
97
- list[Union[dt.date, dt.datetime, str, float, int]],
98
- dt.date,
99
- dt.datetime,
100
- str,
101
- float,
102
- int,
103
- ]
93
+ HolidayType = (
94
+ dict[dt.date | dt.datetime | str | float | int, str]
95
+ | list[dt.date | dt.datetime | str | float | int]
96
+ | dt.date
97
+ | dt.datetime
98
+ | str
99
+ | float
100
+ | int
101
+ )
104
102
 
105
103
  PlotlyLayoutType = dict[
106
104
  str,
107
- Union[
108
- str,
109
- int,
110
- float,
111
- bool,
112
- list[str],
113
- dict[str, Union[str, int, float, bool, list[str]]],
114
- ],
105
+ str
106
+ | int
107
+ | float
108
+ | bool
109
+ | list[str]
110
+ | dict[str, str | int | float | bool | list[str]],
115
111
  ]
116
112
 
117
- CaptorLogoType = dict[str, Union[str, float]]
113
+ CaptorLogoType = dict[str, str | float]
118
114
 
119
115
  LiteralJsonOutput = Literal["values", "tsdf"]
120
116
  LiteralTrunc = Literal["before", "after", "both"]
@@ -230,7 +226,6 @@ LiteralFrameProps = Literal[
230
226
 
231
227
 
232
228
  class OpenTimeSeriesPropertiesList(list[str]):
233
-
234
229
  """Allowed property arguments for the OpenTimeSeries class."""
235
230
 
236
231
  allowed_strings: ClassVar[set[str]] = {
@@ -287,7 +282,6 @@ class OpenTimeSeriesPropertiesList(list[str]):
287
282
 
288
283
 
289
284
  class OpenFramePropertiesList(list[str]):
290
-
291
285
  """Allowed property arguments for the OpenFrame class."""
292
286
 
293
287
  allowed_strings: ClassVar[set[str]] = {
@@ -339,7 +333,6 @@ class OpenFramePropertiesList(list[str]):
339
333
 
340
334
 
341
335
  class ValueType(str, Enum):
342
-
343
336
  """Enum types of OpenTimeSeries to identify the output."""
344
337
 
345
338
  EWMA = "EWMA"
@@ -1,6 +1,6 @@
1
1
  # BSD 3-Clause License
2
2
 
3
- ## Copyright (c) 2024, Captor Fund Management AB
3
+ ## Copyright (c) Captor Fund Management AB
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without modification, are
6
6
  permitted provided that the following conditions are met:
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openseries
3
- Version: 1.6.0
3
+ Version: 1.7.1
4
4
  Summary: Tools for analyzing financial timeseries.
5
5
  Home-page: https://github.com/CaptorAB/openseries
6
6
  License: BSD-3-Clause
7
7
  Keywords: python,finance,fintech,data-science,timeseries,timeseries-data,timeseries-analysis,investment,investment-analysis,investing
8
8
  Author: Martin Karrin
9
9
  Author-email: martin.karrin@captor.se
10
- Requires-Python: >=3.9,<3.13
10
+ Requires-Python: >=3.10,<3.13
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Framework :: Pydantic
13
13
  Classifier: Intended Audience :: Financial and Insurance Industry
@@ -15,7 +15,6 @@ Classifier: License :: OSI Approved :: BSD License
15
15
  Classifier: Natural Language :: English
16
16
  Classifier: Operating System :: OS Independent
17
17
  Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.9
19
18
  Classifier: Programming Language :: Python :: 3.10
20
19
  Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
@@ -25,7 +24,7 @@ Requires-Dist: numpy (>=1.23.2,<=3.0.0)
25
24
  Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
26
25
  Requires-Dist: pandas (>=2.1.2,<3.0.0)
27
26
  Requires-Dist: plotly (>=5.18.0,<6.0.0)
28
- Requires-Dist: pyarrow (>=14.0.2,<17.0.0)
27
+ Requires-Dist: pyarrow (>=14.0.2,<18.0.0)
29
28
  Requires-Dist: pydantic (>=2.5.2,<3.0.0)
30
29
  Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
31
30
  Requires-Dist: requests (>=2.20.0,<3.0.0)
@@ -80,7 +79,7 @@ The code snippet can be pasted into a Python console to run it.
80
79
  Install openseries and yfinance first.
81
80
 
82
81
  ```python
83
- from openseries.series import OpenTimeSeries
82
+ from openseries import OpenTimeSeries
84
83
  import yfinance as yf
85
84
 
86
85
  msft=yf.Ticker("MSFT")
@@ -0,0 +1,16 @@
1
+ openseries/__init__.py,sha256=gD2dMKRTJ9HMXLca_5sR67xGiU5sWExwaNUi-9N_RGQ,1032
2
+ openseries/_common_model.py,sha256=qa0MejnuLcLszaeF9IGbrRycv94O3Xf1rBnAjASI-M4,73805
3
+ openseries/_risk.py,sha256=PReIfkzhInvIgJkzI4k1wYvhmLZ4cCurYKuQAvlHLlE,2082
4
+ openseries/datefixer.py,sha256=Gj9r8xXGm0jcWiDlC0IR0mN64vceaZAnXrei-sXcuqE,12345
5
+ openseries/frame.py,sha256=rl0MNUWrQMffS1beNQWzyLHwuLO9AL_9DI_chUoQweA,55466
6
+ openseries/load_plotly.py,sha256=Uuk_-iIY4_C6Z5U3rAneOh8ZlGYWbkuis9s4Amxzko4,1921
7
+ openseries/plotly_captor_logo.json,sha256=F5nhMzEyxKywtjvQqMTKgKRCJQYMDIiBgDSxdte8Clo,178
8
+ openseries/plotly_layouts.json,sha256=ahx8-dL4_RPzvHtBOX0SiL0AH7xQJzNRSDhGrSmU-Og,1429
9
+ openseries/portfoliotools.py,sha256=0H3IKq3kA2nol-NJcbytIflC3cVMde7xWWzh4ebQkyM,18961
10
+ openseries/series.py,sha256=Jn_2NEYGUGrdWhP-Nm3LBA041FzFClqTvmWg6eHhG7E,27882
11
+ openseries/simulation.py,sha256=P5nkX7o3O_3pOL22MAZTqL_i4TB2IUmPGCodegsAM04,13932
12
+ openseries/types.py,sha256=KoqDGI-DOJGP3zPzhx0an7IGIttWG0zYw-VJqolc1xA,7908
13
+ openseries-1.7.1.dist-info/LICENSE.md,sha256=IQ8_IMXgHxyv4M48G14fJsjcrkiSASdalASTXWCOsj4,1515
14
+ openseries-1.7.1.dist-info/METADATA,sha256=sDuycWQUg_jmcAv9LY4uTuZp97rnSIjgfg0gz9Epnis,44166
15
+ openseries-1.7.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
16
+ openseries-1.7.1.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- openseries/__init__.py,sha256=k2r-yXfmxqBT7_voQ-4HL5dBxfkQIItsm-o77ot3aDQ,1116
2
- openseries/_common_model.py,sha256=qDrEjLLz7FmXbfMl07eocz7i892JdighGpigWCFBpmo,75623
3
- openseries/_risk.py,sha256=etureOLszoEgD48NEOZkx24gaK8I-PfjRXV4Ymjkh7w,2072
4
- openseries/datefixer.py,sha256=rNHH5yT8gV9iHgd_TCiVuwTMNB5TcxeqSsvIAq36dXU,12717
5
- openseries/frame.py,sha256=w6eZgfPx9gRnmUj_i0--KdurBoy5p18B7k0kpGwSoTM,56440
6
- openseries/load_plotly.py,sha256=GLsYrbRYEC3HcKHb7vwZIrlRl3ZjnRhSXoMGJsO8weA,1888
7
- openseries/plotly_captor_logo.json,sha256=F5nhMzEyxKywtjvQqMTKgKRCJQYMDIiBgDSxdte8Clo,178
8
- openseries/plotly_layouts.json,sha256=ahx8-dL4_RPzvHtBOX0SiL0AH7xQJzNRSDhGrSmU-Og,1429
9
- openseries/portfoliotools.py,sha256=r6Y1ZRuTV4nsRL4s7WEJfv1u6__6kkc3d5Rb-MhQn2k,18807
10
- openseries/series.py,sha256=gZCASMtN6Drw7CcmRTNtKBT66YCsnP7Ei7Jhdytp-oE,28236
11
- openseries/simulation.py,sha256=LlssueX0tXHvnEZqiubkfsluOkdd9oQE57RbHZDD7_k,13942
12
- openseries/types.py,sha256=hIEPm-5BFs_ZIXoMw2DWnbJWe2xFmWDYkSQsEYlLEEA,7968
13
- openseries-1.6.0.dist-info/LICENSE.md,sha256=cPUabMxJ6-ziqzqS6aLGkR-ilIOKe_s3Qtyp0ioTmo0,1521
14
- openseries-1.6.0.dist-info/METADATA,sha256=wD4JNrn68QfVpJtZRm7y8BgN7c6jykxMWUmOhHJVH1M,44222
15
- openseries-1.6.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
16
- openseries-1.6.0.dist-info/RECORD,,