openseries 1.9.7__py3-none-any.whl → 2.0.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/datefixer.py CHANGED
@@ -1,11 +1,4 @@
1
- """Date related utilities.
2
-
3
- Copyright (c) Captor Fund Management AB. This file is part of the openseries project.
4
-
5
- Licensed under the BSD 3-Clause License. You may obtain a copy of the License at:
6
- https://github.com/CaptorAB/openseries/blob/master/LICENSE.md
7
- SPDX-License-Identifier: BSD-3-Clause
8
- """
1
+ """Date related utilities."""
9
2
 
10
3
  from __future__ import annotations
11
4
 
@@ -70,7 +63,7 @@ def market_holidays(
70
63
  String or list of market codes supported by pandas_market_calendars.
71
64
 
72
65
  Returns:
73
- -------
66
+ --------
74
67
  list[str]
75
68
  list of holiday dates.
76
69
  """
@@ -122,7 +115,7 @@ def holiday_calendar(
122
115
  Argument where missing holidays can be added
123
116
 
124
117
  Returns:
125
- -------
118
+ --------
126
119
  numpy.busdaycalendar
127
120
  Generate a business calendar
128
121
 
@@ -183,7 +176,7 @@ def date_fix(
183
176
  The data item to parse
184
177
 
185
178
  Returns:
186
- -------
179
+ --------
187
180
  datetime.date
188
181
  Parsed date
189
182
 
@@ -232,7 +225,7 @@ def date_offset_foll(
232
225
  Determines if days should be offset forward (following) or backward
233
226
 
234
227
  Returns:
235
- -------
228
+ --------
236
229
  datetime.date
237
230
  Off-set date
238
231
 
@@ -280,7 +273,7 @@ def get_previous_business_day_before_today(
280
273
  Argument where missing holidays can be added
281
274
 
282
275
  Returns:
283
- -------
276
+ --------
284
277
  datetime.date
285
278
  The previous business day
286
279
 
@@ -326,7 +319,7 @@ def offset_business_days(
326
319
  Argument where missing holidays can be added
327
320
 
328
321
  Returns:
329
- -------
322
+ --------
330
323
  datetime.date
331
324
  The new offset business day
332
325
 
@@ -410,7 +403,7 @@ def generate_calendar_date_range(
410
403
  Argument where missing holidays can be added
411
404
 
412
405
  Returns:
413
- -------
406
+ --------
414
407
  list[dt.date]
415
408
  List of business day calendar dates
416
409
 
@@ -491,7 +484,7 @@ def _do_resample_to_business_period_ends(
491
484
  Argument where missing holidays can be added
492
485
 
493
486
  Returns:
494
- -------
487
+ --------
495
488
  Pandas.DatetimeIndex
496
489
  A date range aligned to business period ends
497
490
 
openseries/frame.py CHANGED
@@ -1,11 +1,4 @@
1
- """Defining the OpenFrame class.
2
-
3
- Copyright (c) Captor Fund Management AB. This file is part of the openseries project.
4
-
5
- Licensed under the BSD 3-Clause License. You may obtain a copy of the License at:
6
- https://github.com/CaptorAB/openseries/blob/master/LICENSE.md
7
- SPDX-License-Identifier: BSD-3-Clause
8
- """
1
+ """The OpenFrame class."""
9
2
 
10
3
  from __future__ import annotations
11
4
 
@@ -18,11 +11,14 @@ from numpy import (
18
11
  array,
19
12
  asarray,
20
13
  concatenate,
14
+ corrcoef,
21
15
  cov,
22
16
  diff,
23
17
  divide,
24
18
  float64,
25
19
  isinf,
20
+ isnan,
21
+ linalg,
26
22
  log,
27
23
  nan,
28
24
  sqrt,
@@ -93,7 +89,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
93
89
  List of weights in float format.
94
90
 
95
91
  Returns:
96
- -------
92
+ --------
97
93
  OpenFrame
98
94
  Object of the class OpenFrame
99
95
 
@@ -132,7 +128,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
132
128
  List of weights in float format.
133
129
 
134
130
  Returns:
135
- -------
131
+ --------
136
132
  OpenFrame
137
133
  Object of the class OpenFrame
138
134
 
@@ -164,7 +160,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
164
160
  """Create copy of the OpenFrame object.
165
161
 
166
162
  Returns:
167
- -------
163
+ --------
168
164
  OpenFrame
169
165
  An OpenFrame object
170
166
 
@@ -183,7 +179,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
183
179
  The Pandas merge method.
184
180
 
185
181
  Returns:
186
- -------
182
+ --------
187
183
  OpenFrame
188
184
  An OpenFrame object
189
185
 
@@ -227,7 +223,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
227
223
  The properties to calculate. Defaults to calculating all available.
228
224
 
229
225
  Returns:
230
- -------
226
+ --------
231
227
  pandas.DataFrame
232
228
  Properties of the contituent OpenTimeSeries
233
229
 
@@ -246,7 +242,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
246
242
  """Number of observations of all constituents.
247
243
 
248
244
  Returns:
249
- -------
245
+ --------
250
246
  Pandas.Series[int]
251
247
  Number of observations of all constituents
252
248
 
@@ -262,7 +258,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
262
258
  """Number of constituents.
263
259
 
264
260
  Returns:
265
- -------
261
+ --------
266
262
  int
267
263
  Number of constituents
268
264
 
@@ -274,7 +270,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
274
270
  """Level 0 values of the MultiIndex columns in the .tsdf DataFrame.
275
271
 
276
272
  Returns:
277
- -------
273
+ --------
278
274
  list[str]
279
275
  Level 0 values of the MultiIndex columns in the .tsdf DataFrame
280
276
 
@@ -286,7 +282,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
286
282
  """Level 1 values of the MultiIndex columns in the .tsdf DataFrame.
287
283
 
288
284
  Returns:
289
- -------
285
+ --------
290
286
  list[ValueType]
291
287
  Level 1 values of the MultiIndex columns in the .tsdf DataFrame
292
288
 
@@ -298,7 +294,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
298
294
  """The first dates in the timeseries of all constituents.
299
295
 
300
296
  Returns:
301
- -------
297
+ --------
302
298
  Pandas.Series[dt.date]
303
299
  The first dates in the timeseries of all constituents
304
300
 
@@ -315,7 +311,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
315
311
  """The last dates in the timeseries of all constituents.
316
312
 
317
313
  Returns:
318
- -------
314
+ --------
319
315
  Pandas.Series[dt.date]
320
316
  The last dates in the timeseries of all constituents
321
317
 
@@ -332,7 +328,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
332
328
  """Number of days from the first date to the last for all items in the frame.
333
329
 
334
330
  Returns:
335
- -------
331
+ --------
336
332
  Pandas.Series[int]
337
333
  Number of days from the first date to the last for all
338
334
  items in the frame.
@@ -348,7 +344,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
348
344
  """Convert series of values into series of returns.
349
345
 
350
346
  Returns:
351
- -------
347
+ --------
352
348
  OpenFrame
353
349
  The returns of the values in the series
354
350
 
@@ -374,7 +370,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
374
370
  is calculated
375
371
 
376
372
  Returns:
377
- -------
373
+ --------
378
374
  OpenFrame
379
375
  An OpenFrame object
380
376
 
@@ -393,7 +389,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
393
389
  """Convert series of returns into cumulative series of values.
394
390
 
395
391
  Returns:
396
- -------
392
+ --------
397
393
  OpenFrame
398
394
  An OpenFrame object
399
395
 
@@ -432,7 +428,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
432
428
  The date offset string that sets the resampled frequency
433
429
 
434
430
  Returns:
435
- -------
431
+ --------
436
432
  OpenFrame
437
433
  An OpenFrame object
438
434
 
@@ -481,7 +477,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
481
477
  Controls the method used to align values across columns
482
478
 
483
479
  Returns:
484
- -------
480
+ --------
485
481
  OpenFrame
486
482
  An OpenFrame object
487
483
 
@@ -562,7 +558,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
562
558
  comparisons
563
559
 
564
560
  Returns:
565
- -------
561
+ --------
566
562
  Pandas.DataFrame
567
563
  Series volatilities and correlation
568
564
 
@@ -658,10 +654,13 @@ class OpenFrame(_CommonModel[SeriesFloat]):
658
654
  def correl_matrix(self: Self) -> DataFrame:
659
655
  """Correlation matrix.
660
656
 
657
+ This property returns the correlation matrix of the time series
658
+ in the frame.
659
+
661
660
  Returns:
662
- -------
663
- Pandas.DataFrame
664
- Correlation matrix
661
+ --------
662
+ pandas.DataFrame
663
+ Correlation matrix of the time series in the frame.
665
664
 
666
665
  """
667
666
  corr_matrix = (
@@ -689,7 +688,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
689
688
  The timeseries to add
690
689
 
691
690
  Returns:
692
- -------
691
+ --------
693
692
  OpenFrame
694
693
  An OpenFrame object
695
694
 
@@ -707,7 +706,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
707
706
  The .tsdf column level 0 value of the timeseries to delete
708
707
 
709
708
  Returns:
710
- -------
709
+ --------
711
710
  OpenFrame
712
711
  An OpenFrame object
713
712
 
@@ -746,7 +745,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
746
745
  or end_cut is None.
747
746
 
748
747
  Returns:
749
- -------
748
+ --------
750
749
  OpenFrame
751
750
  An OpenFrame object
752
751
 
@@ -847,7 +846,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
847
846
  comparisons
848
847
 
849
848
  Returns:
850
- -------
849
+ --------
851
850
  Pandas.Series[float]
852
851
  Tracking Errors
853
852
 
@@ -922,7 +921,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
922
921
  comparisons
923
922
 
924
923
  Returns:
925
- -------
924
+ --------
926
925
  Pandas.Series[float]
927
926
  Information Ratios
928
927
 
@@ -1005,7 +1004,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1005
1004
  comparisons
1006
1005
 
1007
1006
  Returns:
1008
- -------
1007
+ --------
1009
1008
  Pandas.Series[float]
1010
1009
  Capture Ratios
1011
1010
 
@@ -1191,7 +1190,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1191
1190
  Variance bias factor taking the value 0 or 1.
1192
1191
 
1193
1192
  Returns:
1194
- -------
1193
+ --------
1195
1194
  float
1196
1195
  Beta as Co-variance of x & y divided by Variance of x
1197
1196
 
@@ -1260,7 +1259,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1260
1259
  If True the fit is added as a new column in the .tsdf Pandas.DataFrame
1261
1260
 
1262
1261
  Returns:
1263
- -------
1262
+ --------
1264
1263
  dict[str, float]
1265
1264
  A dictionary with the coefficient, intercept and rsquared outputs.
1266
1265
 
@@ -1329,7 +1328,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1329
1328
  Variance bias factor taking the value 0 or 1.
1330
1329
 
1331
1330
  Returns:
1332
- -------
1331
+ --------
1333
1332
  float
1334
1333
  Jensen's alpha
1335
1334
 
@@ -1401,7 +1400,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1401
1400
  weight calculation strategies
1402
1401
 
1403
1402
  Returns:
1404
- -------
1403
+ --------
1405
1404
  Pandas.DataFrame
1406
1405
  A basket timeseries
1407
1406
 
@@ -1431,6 +1430,23 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1431
1430
  vol = divide(1.0, std(returns, axis=0, ddof=1))
1432
1431
  vol[isinf(vol)] = nan
1433
1432
  self.weights = list(divide(vol, vol.sum()))
1433
+ elif weight_strat == "max_div":
1434
+ corr_matrix = corrcoef(returns.T)
1435
+ corr_matrix[isinf(corr_matrix)] = nan
1436
+ corr_matrix[isnan(corr_matrix)] = nan
1437
+ try:
1438
+ inv_corr_sum = linalg.inv(corr_matrix).sum(axis=1)
1439
+ self.weights = list(divide(inv_corr_sum, inv_corr_sum.sum()))
1440
+ except linalg.LinAlgError:
1441
+ self.weights = [1.0 / self.item_count] * self.item_count
1442
+ elif weight_strat == "target_risk":
1443
+ vols = std(returns, axis=0, ddof=1)
1444
+ min_vol_idx = vols.argmin()
1445
+ min_vol_weight = 0.6
1446
+ remaining_weight = 0.4
1447
+ weights = [remaining_weight / (self.item_count - 1)] * self.item_count
1448
+ weights[min_vol_idx] = min_vol_weight
1449
+ self.weights = weights
1434
1450
  else:
1435
1451
  raise NotImplementedError(msg)
1436
1452
 
@@ -1466,7 +1482,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1466
1482
  Allows locking the periods-in-a-year to simplify test cases and comparisons
1467
1483
 
1468
1484
  Returns:
1469
- -------
1485
+ --------
1470
1486
  Pandas.DataFrame
1471
1487
  Rolling Information Ratios
1472
1488
 
@@ -1532,7 +1548,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1532
1548
  Variance bias factor taking the value 0 or 1.
1533
1549
 
1534
1550
  Returns:
1535
- -------
1551
+ --------
1536
1552
  Pandas.DataFrame
1537
1553
  Rolling Betas
1538
1554
 
@@ -1592,7 +1608,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1592
1608
  The length of the rolling window to use is set as number of observations
1593
1609
 
1594
1610
  Returns:
1595
- -------
1611
+ --------
1596
1612
  Pandas.DataFrame
1597
1613
  Rolling Correlations
1598
1614
 
@@ -1637,7 +1653,7 @@ class OpenFrame(_CommonModel[SeriesFloat]):
1637
1653
  to use as the dependent variable
1638
1654
 
1639
1655
  Returns:
1640
- -------
1656
+ --------
1641
1657
  tuple[pandas.DataFrame, OpenTimeSeries]
1642
1658
  - A DataFrame with the R-squared, the intercept
1643
1659
  and the regression coefficients
openseries/load_plotly.py CHANGED
@@ -1,11 +1,4 @@
1
- """Function to load plotly layout and configuration from local json file.
2
-
3
- Copyright (c) Captor Fund Management AB. This file is part of the openseries project.
4
-
5
- Licensed under the BSD 3-Clause License. You may obtain a copy of the License at:
6
- https://github.com/CaptorAB/openseries/blob/master/LICENSE.md
7
- SPDX-License-Identifier: BSD-3-Clause
8
- """
1
+ """Function to load plotly layout and configuration from local json file."""
9
2
 
10
3
  from __future__ import annotations
11
4
 
@@ -34,7 +27,7 @@ def _check_remote_file_existence(url: str) -> bool:
34
27
  Path to remote file
35
28
 
36
29
  Returns:
37
- -------
30
+ --------
38
31
  bool
39
32
  True if url is valid and False otherwise
40
33
 
@@ -62,7 +55,7 @@ def load_plotly_dict(
62
55
  Flag whether to load as responsive
63
56
 
64
57
  Returns:
65
- -------
58
+ --------
66
59
  tuple[PlotlyLayoutType, CaptorLogoType]
67
60
  A dictionary with the Plotly config and layout template
68
61
 
openseries/owntypes.py CHANGED
@@ -1,11 +1,4 @@
1
- """Declaring types used throughout the project.
2
-
3
- Copyright (c) Captor Fund Management AB. This file is part of the openseries project.
4
-
5
- Licensed under the BSD 3-Clause License. You may obtain a copy of the License at:
6
- https://github.com/CaptorAB/openseries/blob/master/LICENSE.md
7
- SPDX-License-Identifier: BSD-3-Clause
8
- """
1
+ """Declaring types used throughout the project."""
9
2
 
10
3
  from __future__ import annotations
11
4
 
@@ -142,7 +135,7 @@ LiteralPlotlyHistogramHistNorm = Literal[
142
135
  "density",
143
136
  "probability density",
144
137
  ]
145
- LiteralPortfolioWeightings = Literal["eq_weights", "inv_vol"]
138
+ LiteralPortfolioWeightings = Literal["eq_weights", "inv_vol", "max_div", "target_risk"]
146
139
  LiteralMinimizeMethods = Literal[
147
140
  "SLSQP",
148
141
  "Nelder-Mead",
@@ -1,11 +1,4 @@
1
- """Defining the portfolio tools for the OpenFrame class.
2
-
3
- Copyright (c) Captor Fund Management AB. This file is part of the openseries project.
4
-
5
- Licensed under the BSD 3-Clause License. You may obtain a copy of the License at:
6
- https://github.com/CaptorAB/openseries/blob/master/LICENSE.md
7
- SPDX-License-Identifier: BSD-3-Clause
8
- """
1
+ """Defining the portfolio tools for the OpenFrame class."""
9
2
 
10
3
  from __future__ import annotations
11
4
 
@@ -84,7 +77,7 @@ def simulate_portfolios(
84
77
  The seed for the random process
85
78
 
86
79
  Returns:
87
- -------
80
+ --------
88
81
  pandas.DataFrame
89
82
  The resulting data
90
83
 
@@ -155,7 +148,7 @@ def efficient_frontier(
155
148
  cutting the frontier to exclude multiple points with almost the same risk
156
149
 
157
150
  Returns:
158
- -------
151
+ --------
159
152
  tuple[DataFrame, DataFrame, NDArray[float]]
160
153
  The efficient frontier data, simulation data and optimal portfolio
161
154
 
@@ -342,7 +335,7 @@ def constrain_optimized_portfolios(
342
335
  The method passed into the scipy.minimize function
343
336
 
344
337
  Returns:
345
- -------
338
+ --------
346
339
  tuple[OpenFrame, OpenTimeSeries, OpenFrame, OpenTimeSeries]
347
340
  The constrained optimal portfolio data
348
341
 
@@ -404,7 +397,7 @@ def prepare_plot_data(
404
397
  Data optimized with the efficient_frontier method
405
398
 
406
399
  Returns:
407
- -------
400
+ --------
408
401
  DataFrame
409
402
  The data prepared with mean returns, volatility and weights
410
403
 
@@ -488,7 +481,7 @@ def sharpeplot(
488
481
  Determines whether to open a browser window with the plot
489
482
 
490
483
  Returns:
491
- -------
484
+ --------
492
485
  Figure
493
486
  The scatter plot with simulated and optimized results
494
487
 
openseries/report.py CHANGED
@@ -1,11 +1,4 @@
1
- """Functions related to HTML reports.
2
-
3
- Copyright (c) Captor Fund Management AB. This file is part of the openseries project.
4
-
5
- Licensed under the BSD 3-Clause License. You may obtain a copy of the License at:
6
- https://github.com/CaptorAB/openseries/blob/master/LICENSE.md
7
- SPDX-License-Identifier: BSD-3-Clause
8
- """
1
+ """Functions related to HTML reports."""
9
2
 
10
3
  from __future__ import annotations
11
4
 
@@ -61,7 +54,7 @@ def calendar_period_returns(
61
54
  Whether to set new appropriate labels
62
55
 
63
56
  Returns:
64
- -------
57
+ --------
65
58
  pandas.DataFrame
66
59
  The resulting data
67
60
 
@@ -122,7 +115,7 @@ def report_html(
122
115
  Determines whether to vertically align the legend's labels
123
116
 
124
117
  Returns:
125
- -------
118
+ --------
126
119
  tuple[plotly.go.Figure, str]
127
120
  Plotly Figure and a div section or a html filename with location
128
121