PYield 0.23.2__tar.gz → 0.23.4__tar.gz

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.
Files changed (34) hide show
  1. pyield-0.23.4/.gitignore +45 -0
  2. {pyield-0.23.2 → pyield-0.23.4}/PKG-INFO +29 -32
  3. pyield-0.23.4/pyield/__about__.py +1 -0
  4. {pyield-0.23.2 → pyield-0.23.4}/pyield/b3_futures/intraday.py +2 -12
  5. {pyield-0.23.2 → pyield-0.23.4}/pyield/bday.py +5 -5
  6. {pyield-0.23.2 → pyield-0.23.4}/pyield/bonds/ntnb.py +47 -14
  7. {pyield-0.23.2 → pyield-0.23.4}/pyield/date_converter.py +2 -2
  8. {pyield-0.23.2 → pyield-0.23.4}/pyield/di.py +7 -9
  9. {pyield-0.23.2 → pyield-0.23.4}/pyield/indicators.py +36 -18
  10. {pyield-0.23.2 → pyield-0.23.4}/pyield/interpolator.py +9 -8
  11. {pyield-0.23.2 → pyield-0.23.4}/pyproject.toml +33 -47
  12. pyield-0.23.2/pyield/__about__.py +0 -1
  13. {pyield-0.23.2 → pyield-0.23.4}/LICENSE +0 -0
  14. {pyield-0.23.2 → pyield-0.23.4}/README.md +0 -0
  15. {pyield-0.23.2 → pyield-0.23.4}/pyield/__init__.py +0 -0
  16. {pyield-0.23.2 → pyield-0.23.4}/pyield/anbima.py +0 -0
  17. {pyield-0.23.2 → pyield-0.23.4}/pyield/b3_futures/__init__.py +0 -0
  18. {pyield-0.23.2 → pyield-0.23.4}/pyield/b3_futures/common.py +0 -0
  19. {pyield-0.23.2 → pyield-0.23.4}/pyield/b3_futures/historical.py +0 -0
  20. {pyield-0.23.2 → pyield-0.23.4}/pyield/b3_futures/xml.py +0 -0
  21. {pyield-0.23.2 → pyield-0.23.4}/pyield/bonds/__init__.py +0 -0
  22. {pyield-0.23.2 → pyield-0.23.4}/pyield/bonds/bond_tools.py +0 -0
  23. {pyield-0.23.2 → pyield-0.23.4}/pyield/bonds/lft.py +0 -0
  24. {pyield-0.23.2 → pyield-0.23.4}/pyield/bonds/ltn.py +0 -0
  25. {pyield-0.23.2 → pyield-0.23.4}/pyield/bonds/ntnf.py +0 -0
  26. {pyield-0.23.2 → pyield-0.23.4}/pyield/conftest.py +0 -0
  27. {pyield-0.23.2 → pyield-0.23.4}/pyield/data_cache.py +0 -0
  28. {pyield-0.23.2 → pyield-0.23.4}/pyield/holidays/__init__.py +0 -0
  29. {pyield-0.23.2 → pyield-0.23.4}/pyield/holidays/br_holidays_new.txt +0 -0
  30. {pyield-0.23.2 → pyield-0.23.4}/pyield/holidays/br_holidays_old.txt +0 -0
  31. {pyield-0.23.2 → pyield-0.23.4}/pyield/holidays/brholidays.py +0 -0
  32. {pyield-0.23.2 → pyield-0.23.4}/pyield/projections.py +0 -0
  33. {pyield-0.23.2 → pyield-0.23.4}/pyield/py.typed +0 -0
  34. {pyield-0.23.2 → pyield-0.23.4}/pyield/tools.py +0 -0
@@ -0,0 +1,45 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+
4
+ # Distribution / packaging
5
+ .Python
6
+ build/
7
+ develop-eggs/
8
+ dist/
9
+ downloads/
10
+ eggs/
11
+ .eggs/
12
+ lib/
13
+ lib64/
14
+ parts/
15
+ sdist/
16
+ var/
17
+ wheels/
18
+ share/python-wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # pdm
25
+ pdm.lock
26
+ .pdm-python
27
+
28
+ # uv
29
+ uv.lock
30
+
31
+ # Environments
32
+ .env
33
+ .venv
34
+ env/
35
+ venv/
36
+ ENV/
37
+ env.bak/
38
+ venv.bak/
39
+
40
+ # Jupiter Notebook
41
+ .ipynb_checkpoints
42
+ *.ipynb
43
+
44
+ # Dev folder
45
+ dev/
@@ -1,45 +1,42 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: PYield
3
- Version: 0.23.2
3
+ Version: 0.23.4
4
4
  Summary: A Python library for analysis of fixed income instruments in Brazil
5
- Keywords: fixed-income, brazil, finance, analysis, bonds
6
- Author-Email: Carlos Carvalho <cr.cj@outlook.com>
5
+ Project-URL: Source, https://github.com/crdcj/PYield
6
+ Author-email: Carlos Carvalho <cr.cj@outlook.com>
7
7
  License: MIT License
8
-
9
- Copyright (c) 2023 Carlos Carvalho
10
-
11
- Permission is hereby granted, free of charge, to any person obtaining a copy
12
- of this software and associated documentation files (the "Software"), to deal
13
- in the Software without restriction, including without limitation the rights
14
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
- copies of the Software, and to permit persons to whom the Software is
16
- furnished to do so, subject to the following conditions:
17
-
18
- The above copyright notice and this permission notice shall be included in all
19
- copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
- SOFTWARE.
28
-
29
- Classifier: Programming Language :: Python :: 3
8
+
9
+ Copyright (c) 2023 Carlos Carvalho
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+ License-File: LICENSE
29
+ Keywords: fixed-income, brazil, finance, analysis, bonds
30
+ Classifier: Intended Audience :: Financial and Insurance Industry
30
31
  Classifier: License :: OSI Approved :: MIT License
31
32
  Classifier: Operating System :: OS Independent
32
- Classifier: Intended Audience :: Financial and Insurance Industry
33
+ Classifier: Programming Language :: Python :: 3
33
34
  Classifier: Topic :: Office/Business :: Financial :: Investment
34
- Project-URL: Source, https://github.com/crdcj/PYield
35
35
  Requires-Python: >=3.12
36
+ Requires-Dist: numpy>=2.0.0
36
37
  Requires-Dist: pandas[html,parquet]>=2.0.0
37
- Requires-Dist: numpy
38
38
  Requires-Dist: python-calamine>=0.2.0
39
39
  Requires-Dist: requests>=2.31.0
40
- Requires-Dist: pandas-stubs
41
- Requires-Dist: lxml-stubs
42
- Requires-Dist: types-requests
43
40
  Description-Content-Type: text/markdown
44
41
 
45
42
  [![PyPI version](https://img.shields.io/pypi/v/pyield.svg)](https://pypi.python.org/pypi/pyield)
@@ -0,0 +1 @@
1
+ __version__ = "0.23.4"
@@ -1,19 +1,9 @@
1
- from io import StringIO
2
-
3
1
  import pandas as pd
4
2
  import requests
5
3
 
6
4
  from pyield import bday
7
5
 
8
6
 
9
- # Função para salvar DataFrame em CSV e ler com read_csv
10
- def _convert_with_read_csv(df):
11
- buffer = StringIO()
12
- df.to_csv(buffer, index=False)
13
- buffer.seek(0) # Reposiciona o cursor no início do buffer
14
- return pd.read_csv(buffer, dtype_backend="numpy_nullable")
15
-
16
-
17
7
  def _fetch_b3_df(future_code: str) -> pd.DataFrame:
18
8
  """
19
9
  Fetch the latest data for a given future code from B3 derivatives quotation API.
@@ -47,8 +37,8 @@ def _fetch_b3_df(future_code: str) -> pd.DataFrame:
47
37
  # Normalize JSON response into a flat table
48
38
  df = pd.json_normalize(r.json()["Scty"])
49
39
 
50
- # Convert DataFrame to use nullable data types for better type consistency
51
- return _convert_with_read_csv(df)
40
+ # Convert columns to the most appropriate data type
41
+ return df.convert_dtypes()
52
42
 
53
43
 
54
44
  def _rename_columns(df: pd.DataFrame) -> pd.DataFrame:
@@ -3,15 +3,15 @@ from typing import Literal, overload
3
3
  import numpy as np
4
4
  import pandas as pd
5
5
 
6
- from pyield import date_converter as dc
6
+ import pyield.date_converter as dc
7
+ import pyield.holidays as hl
7
8
  from pyield.date_converter import ArrayDateTypes, ScalarDateTypes
8
- from pyield.holidays import BrHolidays
9
9
 
10
- type ArrayIntTypes = np.ndarray | pd.Series | list | tuple
11
- type ScalarIntTypes = int | np.integer
10
+ ArrayIntTypes = np.ndarray | pd.Series | list | tuple
11
+ ScalarIntTypes = int | np.integer
12
12
 
13
13
  # Initialize Brazilian holidays data
14
- br_holidays = BrHolidays()
14
+ br_holidays = hl.BrHolidays()
15
15
  OLD_HOLIDAYS_ARRAY = br_holidays.get_holiday_array(holiday_option="old")
16
16
  NEW_HOLIDAYS_ARRAY = br_holidays.get_holiday_array(holiday_option="new")
17
17
 
@@ -457,34 +457,67 @@ def bei_rates(
457
457
  ) -> pd.DataFrame:
458
458
  """
459
459
  Calculate the Breakeven Inflation (BEI) for NTN-B bonds based on nominal and real
460
- interest rates.
460
+ interest rates. The BEI represents the inflation rate that equalizes the real and
461
+ nominal yields. The calculation is based on the spot rates for NTN-B bonds.
461
462
 
462
463
  Args:
463
- settlement (str or pd.Timestamp): The settlement date for the bonds.
464
- ntnb_maturities (pd.Series): Series of maturity dates for the inflation-indexed
465
- bonds (NTN-B).
466
- ntnb_rates (pd.Series): Series of real interest rates (Yield to Maturity - YTM)
467
- corresponding to the inflation-indexed bonds' maturity dates.
468
- nominal_maturities (pd.Series): Series of maturity dates corresponding to the
464
+ settlement (str or pd.Timestamp): The settlement date of the operation.
465
+ ntnb_maturities (pd.Series): The maturity dates for the NTN-B bonds.
466
+ ntnb_rates (pd.Series): The real interest rates (Yield to Maturity - YTM)
467
+ corresponding to the given NTN-B maturities.
468
+ nominal_maturities (pd.Series): The maturity dates to be used as reference for
469
469
  nominal reates.
470
- nominal_rates (pd.Series): Series of nominal interest rates
471
- (e.g., DI or prefixed bonds) used as reference for the calculation.
470
+ nominal_rates (pd.Series): The nominal interest rates (e.g. DI Futures or
471
+ zero prefixed bonds rates) used as reference for the calculation.
472
472
 
473
473
  Returns:
474
474
  pd.DataFrame: DataFrame containing the calculated breakeven inflation rates.
475
475
 
476
476
  Returned columns:
477
477
  - MaturityDate: The maturity date of the bonds.
478
- - BDays: Number of business days from the settlement date to the maturity date.
479
- - RIR: The calculated Real Interest Rate based on the spot rates.
480
- - NIR: Nominal Interest Rate interpolated for the corresponding maturity date.
481
- - BEI: The calculated Breakeven Inflation Rate, which represents the inflation
482
- rate that equalizes the real and nominal yields.
478
+ - RIR: The calculated Real Interest Rates based on the spot rates.
479
+ - NIR: The Nominal Interest Rates interpolated for the maturity date.
480
+ - BEI: The calculated Breakeven Inflation Rates.
483
481
 
484
482
  Notes:
485
483
  The BEI is calculated by comparing the nominal and real interest rates,
486
484
  indicating the market's inflation expectations over the period from the
487
485
  settlement date to the bond's maturity.
486
+
487
+ Examples:
488
+ Get the NTN-B rates for a specific reference date.
489
+ These are YTM rates and the spot rates are calculated based on them
490
+ >>> df_ntnb = yd.ntnb.rates("05-09-2024")
491
+
492
+ Get the DI Futures settlement rates for the same reference date to be used as
493
+ reference for the nominal rates:
494
+ >>> di = yd.DIFutures("05-09-2024")
495
+ >>> df_di = di.data
496
+
497
+ Calculate the BEI rates considering the settlement at the reference date:
498
+ >>> yd.ntnb.bei_rates(
499
+ ... settlement="05-09-2024",
500
+ ... ntnb_maturities=df_ntnb["MaturityDate"],
501
+ ... ntnb_rates=df_ntnb["IndicativeRate"],
502
+ ... nominal_maturities=df_di["ExpirationDate"],
503
+ ... nominal_rates=df_di["SettlementRate"],
504
+ ... )
505
+ MaturityDate RIR NIR BEI
506
+ 0 2025-05-15 0.061749 0.113836 0.049058
507
+ 1 2026-08-15 0.066133 0.117126 0.04783
508
+ 2 2027-05-15 0.063816 0.117169 0.050152
509
+ 3 2028-08-15 0.063635 0.11828 0.051376
510
+ 4 2029-05-15 0.062532 0.11838 0.052561
511
+ 5 2030-08-15 0.061809 0.118499 0.05339
512
+ 6 2032-08-15 0.062135 0.118084 0.052676
513
+ 7 2033-05-15 0.061897 0.11787 0.05271
514
+ 8 2035-05-15 0.061711 0.117713 0.052747
515
+ 9 2040-08-15 0.060468 0.11759 0.053865
516
+ 10 2045-05-15 0.0625 0.11759 0.05185
517
+ 11 2050-08-15 0.063016 0.11759 0.051339
518
+ 12 2055-05-15 0.062252 0.11759 0.052095
519
+ 13 2060-08-15 0.063001 0.11759 0.051354
520
+
488
521
  """
489
522
  # Normalize input dates
490
523
  settlement = dc.convert_input_dates(settlement)
@@ -4,8 +4,8 @@ from typing import overload
4
4
  import numpy as np
5
5
  import pandas as pd
6
6
 
7
- type ScalarDateTypes = str | np.datetime64 | pd.Timestamp | dt.datetime | dt.date
8
- type ArrayDateTypes = pd.Series | pd.DatetimeIndex | np.ndarray | list | tuple
7
+ ScalarDateTypes = str | np.datetime64 | pd.Timestamp | dt.datetime | dt.date
8
+ ArrayDateTypes = pd.Series | pd.DatetimeIndex | np.ndarray | list | tuple
9
9
 
10
10
 
11
11
  def validate_date_format(date_str):
@@ -15,9 +15,15 @@ class DIFutures:
15
15
  includes options to adjust expiration dates and apply filters based on LTN and
16
16
  NTN-F bond maturities.
17
17
 
18
+ Args:
19
+ trade_date (str | pd.Timestamp): The date to retrieve the contract data.
20
+ adj_expirations (bool): If True, adjusts the expiration dates to the start
21
+ of the month.
22
+ prefixed_filter (bool): If True, filters the DI contracts to match only
23
+ expirations with existing LTN and NTN-F bond maturities.
24
+
18
25
  Examples:
19
26
  To create a `DIFutures` instance and retrieve data:
20
-
21
27
  >>> di = yd.DIFutures(trade_date="16-10-2024", adj_expirations=True)
22
28
  >>> df = di.data # Retrieve DI contract dataframe for the specified date
23
29
  >>> df.iloc[:5, :5] # Show the first five rows and columns
@@ -29,7 +35,6 @@ class DIFutures:
29
35
  4 DI1H25 2025-03-01 94 344056 221
30
36
 
31
37
  You can also retrieve forward rates for the DI contracts:
32
-
33
38
  >>> di.forwards.iloc[:5] # Show the first five rows
34
39
  ExpirationDate SettlementRate ForwardRate
35
40
  0 2024-11-01 0.10653 0.10653
@@ -59,13 +64,6 @@ class DIFutures:
59
64
  ):
60
65
  """
61
66
  Initialize the DIFutures instance with a specific trade date.
62
-
63
- Args:
64
- trade_date (str | pd.Timestamp): The date to retrieve the contract data.
65
- adj_expirations (bool): If True, adjusts the expiration dates to the start
66
- of the month.
67
- prefixed_filter (bool): If True, filters the DI contracts to match LTN and
68
- NTN-F bond maturities.
69
67
  """
70
68
  self._trade_date = dc.convert_input_dates(trade_date)
71
69
  self._adj_expirations = adj_expirations
@@ -44,6 +44,7 @@ def indicator(
44
44
 
45
45
  Raises:
46
46
  ValueError: If an invalid `indicator_code` is provided.
47
+ ValueError: After all retries, if the indicator value cannot be fetched.
47
48
 
48
49
  Examples:
49
50
  >>> yd.indicator("IPCA_MR", "01-04-2024")
@@ -102,7 +103,7 @@ def ipca_monthly_rate(reference_date: pd.Timestamp) -> float:
102
103
  data = response.json()
103
104
 
104
105
  if not data:
105
- return float("nan")
106
+ raise ValueError("No data available for the specified date")
106
107
  # Extract and return the IPCA monthly growth rate if data is available
107
108
  ipca_str = data[0]["resultados"][0]["series"][0]["serie"][ipca_date]
108
109
  return round(float(ipca_str) / 100, 4)
@@ -146,8 +147,8 @@ def _selic_target(reference_date: pd.Timestamp) -> float:
146
147
  attempt += 1
147
148
  time.sleep(1.5**attempt) # Exponential backoff: 1.5, 2.3, 3.9, 5.1, 7.6 seconds
148
149
 
149
- # After all retries, return NaN
150
- return float("nan")
150
+ # After all retries, raise an error
151
+ raise ValueError("Failed to fetch SELIC Target rate after maximum attempts")
151
152
 
152
153
 
153
154
  def _selic_over(reference_date: pd.Timestamp) -> float:
@@ -191,8 +192,8 @@ def _selic_over(reference_date: pd.Timestamp) -> float:
191
192
  attempt += 1
192
193
  time.sleep(1.5**attempt) # Exponential backoff: 1.5, 2.3, 3.9, 5.1, 7.6 seconds
193
194
 
194
- # After all retries, return NaN
195
- return float("nan")
195
+ # After all retries, raise an error
196
+ raise ValueError("Failed to fetch SELIC Over rate after maximum attempts")
196
197
 
197
198
 
198
199
  def _di(reference_date: pd.Timestamp) -> float:
@@ -210,22 +211,13 @@ def _di(reference_date: pd.Timestamp) -> float:
210
211
  return round((1 + value) ** 252 - 1, 4)
211
212
 
212
213
 
213
- def _vna_lft(reference_date: pd.Timestamp) -> float:
214
- # url example: https://www3.bcb.gov.br/novoselic/rest/arquivosDiarios/pub/download/3/20240418APC238
215
- url_base = "https://www3.bcb.gov.br/novoselic/rest/arquivosDiarios/pub/download/3/"
216
- url_file = f"{reference_date.strftime('%Y%m%d')}APC238"
217
- url_vna = url_base + url_file
218
-
219
- response = requests.get(url_vna, timeout=TIMEOUT)
220
- response.raise_for_status()
221
- file_text = response.text
222
-
214
+ def _extract_vna_value(text: str) -> float:
223
215
  # Finding the part that contains the table
224
- start_of_table = file_text.find("EMISSAO")
225
- end_of_table = file_text.find("99999999*")
216
+ start_of_table = text.find("EMISSAO")
217
+ end_of_table = text.find("99999999*")
226
218
 
227
219
  # Extracting the table
228
- table_text = file_text[start_of_table:end_of_table].strip()
220
+ table_text = text[start_of_table:end_of_table].strip()
229
221
  table_lines = table_text.splitlines()
230
222
 
231
223
  # Remove empty lines
@@ -246,3 +238,29 @@ def _vna_lft(reference_date: pd.Timestamp) -> float:
246
238
  raise ValueError(f"VNA values are not the same. Please check data at {bcb_url}")
247
239
 
248
240
  return vna_value
241
+
242
+
243
+ def _vna_lft(reference_date: pd.Timestamp) -> float:
244
+ # url example: https://www3.bcb.gov.br/novoselic/rest/arquivosDiarios/pub/download/3/20240418APC238
245
+ url_base = "https://www3.bcb.gov.br/novoselic/rest/arquivosDiarios/pub/download/3/"
246
+ url_file = f"{reference_date.strftime('%Y%m%d')}APC238"
247
+ url_vna = url_base + url_file
248
+ session = requests.Session()
249
+
250
+ attempt = 0
251
+ while attempt < MAX_ATTEMPTS:
252
+ try:
253
+ response = session.get(url_vna, timeout=TIMEOUT)
254
+ response.raise_for_status()
255
+ return _extract_vna_value(response.text)
256
+
257
+ except (RequestException, KeyError, IndexError, ValueError) as e:
258
+ msg = f"Error fetching SELIC Over rate (attempt {attempt + 1}): {e}"
259
+ logging.error(msg)
260
+
261
+ # Increment attempt count and add backoff delay
262
+ attempt += 1
263
+ time.sleep(1.5**attempt) # Exponential backoff: 1.5, 2.3, 3.9, 5.1, 7.6 seconds
264
+
265
+ # After all retries, raise an error
266
+ raise ValueError("Failed to fetch VNA LFT value after maximum attempts")
@@ -11,17 +11,16 @@ class Interpolator:
11
11
 
12
12
  Args:
13
13
  method (Literal["flat_forward", "linear"]): The interpolation method to use.
14
- known_bdays (pd.Series | pd.Index | list): Series of known business days.
15
- known_rates (pd.Series | pd.Index | list): Series of known interest rates.
16
- extrapolate (bool, optional): Whether to extrapolate beyond known business days.
14
+ known_bdays (pd.Series | list[int]): The known business days sequence.
15
+ known_rates (pd.Series | list[float]): The known interest rates sequence.
16
+ extrapolate (bool, optional): If True, extrapolates beyond known business days
17
+ using the last available rate. Defaults to False, returning NaN for
18
+ out-of-range values.
17
19
 
18
20
  Raises:
19
21
  ValueError: If known_bdays and known_rates do not have the same length.
20
22
  ValueError: If the interpolation method is not recognized
21
23
 
22
- Returns:
23
- Interpolator: An instance of the Interpolator
24
-
25
24
  Note:
26
25
  This class uses a 252 business days per year convention.
27
26
 
@@ -30,10 +29,12 @@ class Interpolator:
30
29
  >>> known_bdays = [30, 60, 90]
31
30
  >>> known_rates = [0.045, 0.05, 0.055]
32
31
 
32
+ Linear interpolation example:
33
33
  >>> lin_interp = Interpolator("linear", known_bdays, known_rates)
34
34
  >>> lin_interp(45)
35
35
  0.0475
36
36
 
37
+ Flat forward interpolation example:
37
38
  >>> ffo_interp = Interpolator("flat_forward", known_bdays, known_rates)
38
39
  >>> ffo_interp(45)
39
40
  0.04833068080970859
@@ -42,8 +43,8 @@ class Interpolator:
42
43
  def __init__(
43
44
  self,
44
45
  method: Literal["flat_forward", "linear"],
45
- known_bdays: pd.Series | list,
46
- known_rates: pd.Series | list,
46
+ known_bdays: pd.Series | list[int],
47
+ known_rates: pd.Series | list[float],
47
48
  extrapolate: bool = False,
48
49
  ):
49
50
  self.method = method
@@ -1,20 +1,11 @@
1
- [build-system]
2
- requires = [
3
- "pdm-backend",
4
- ]
5
- build-backend = "pdm.backend"
6
-
7
1
  [project]
8
2
  name = "PYield"
9
- authors = [
10
- { name = "Carlos Carvalho", email = "cr.cj@outlook.com" },
11
- ]
3
+ authors = [{ name = "Carlos Carvalho", email = "cr.cj@outlook.com" }]
12
4
  description = "A Python library for analysis of fixed income instruments in Brazil"
13
5
  readme = "README.md"
14
6
  requires-python = ">=3.12"
15
- keywords = [
16
- "fixed-income, brazil, finance, analysis, bonds",
17
- ]
7
+ keywords = ["fixed-income, brazil, finance, analysis, bonds"]
8
+ license = { file = "LICENSE" }
18
9
  classifiers = [
19
10
  "Programming Language :: Python :: 3",
20
11
  "License :: OSI Approved :: MIT License",
@@ -24,36 +15,16 @@ classifiers = [
24
15
  ]
25
16
  dependencies = [
26
17
  "pandas[html,parquet]>=2.0.0",
27
- "numpy",
28
- "python-calamine>=0.2.0",
18
+ "numpy>=2.0.0",
19
+ "python-calamine>=0.2.0",
29
20
  "requests>=2.31.0",
30
- "pandas-stubs",
31
- "lxml-stubs",
32
- "types-requests",
33
21
  ]
34
- dynamic = []
35
- version = "0.23.2"
36
-
37
- [project.license]
38
- file = "LICENSE"
22
+ dynamic = ["version"]
39
23
 
40
24
  [project.urls]
41
25
  Source = "https://github.com/crdcj/PYield"
42
26
 
43
- [tool.pdm]
44
- distribution = true
45
-
46
- [tool.pdm.version]
47
- source = "file"
48
- path = "pyield/__about__.py"
49
-
50
- [tool.pdm.build]
51
- excludes = [
52
- "tests",
53
- "docs",
54
- ]
55
-
56
- [tool.pdm.dev-dependencies]
27
+ [dependency-groups]
57
28
  dev = [
58
29
  "ipykernel",
59
30
  "pytest",
@@ -62,27 +33,42 @@ dev = [
62
33
  "mkdocs-material",
63
34
  "mkdocstrings[python]",
64
35
  "mkdocs-autorefs",
36
+ "pandas-stubs",
37
+ "lxml-stubs",
38
+ "types-requests",
65
39
  ]
66
40
 
41
+ [build-system]
42
+ requires = ["hatchling"]
43
+ build-backend = "hatchling.build"
44
+
45
+ [tool.hatch.version]
46
+ path = "pyield/__about__.py"
47
+
48
+ [tool.hatch.build.targets.sdist]
49
+ only-include = ["pyield"]
50
+
51
+ [tool.pdm]
52
+ version = { source = "file", path = "pyield/__about__.py" }
53
+ distribution = true
54
+
55
+ [tool.pdm.build]
56
+ excludes = ["tests", "docs"]
57
+
58
+ [tool.uv]
59
+ package = true
60
+
67
61
  [tool.ruff]
68
62
  line-length = 88
69
63
  indent-width = 4
70
64
  target-version = "py312"
71
- extend-include = [
72
- "*.ipynb",
73
- ]
65
+ extend-include = ["*.ipynb"]
74
66
 
75
67
  [tool.ruff.lint]
76
68
  preview = true
77
- select = [
78
- "I",
79
- "F",
80
- "E",
81
- "W",
82
- "PL",
83
- "PT",
84
- ]
69
+ select = ["I", "F", "E", "W", "PL", "PT"]
85
70
 
86
71
  [tool.ruff.format]
87
72
  docstring-code-format = true
88
73
  docstring-code-line-length = 88
74
+
@@ -1 +0,0 @@
1
- __version__ = "0.23.2"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes