PYield 0.5.0__tar.gz → 0.6.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PYield
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: A Python library for analysis of fixed income instruments in Brazil
5
5
  Keywords: fixed-income, brazil, finance, analysis, bonds
6
6
  Author-Email: Carlos Carvalho <cr.cj@outlook.com>
@@ -44,17 +44,18 @@ Description-Content-Type: text/markdown
44
44
  [![Made with Python](https://img.shields.io/badge/Python->=3.11-blue?logo=python&logoColor=white)](https://python.org "Go to Python homepage")
45
45
  [![License](https://img.shields.io/badge/License-MIT-blue)](#license)
46
46
 
47
- # PYield: Brazilian Fixed Income Analysis Library
47
+ # PYield: Fixed Income Toolbox for Brazilian Markets
48
48
 
49
49
  ## Introduction
50
50
 
51
- Welcome to PYield, a Python library designed for the analysis of fixed income instruments in Brazil. This library is tailored for financial analysts, researchers, and enthusiasts interested in the Brazilian fixed income market. Leveraging the power of popular Python libraries like Pandas and Requests, PYield simplifies the process of obtaining and processing data from key sources such as Tesouro Nacional (TN), Banco Central (BC), ANBIMA, and B3.
51
+ Welcome to PYield, a Python library designed for the analysis of fixed income instruments in Brazil. This library is tailored for financial analysts, researchers, and enthusiasts interested in the Brazilian fixed income market. Leveraging the power of popular Python libraries like Pandas and Requests, PYield simplifies the process of obtaining and processing data from key sources such as ANBIMA and B3.
52
+
52
53
  ## Features
53
54
 
54
- - **Data Collection**: Automated fetching of data from BC, ANBIMA and B3.
55
+ - **Data Collection**: Automated fetching of data from ANBIMA and B3.
55
56
  - **Data Processing**: Efficient processing and normalization of fixed income data.
56
57
  - **Analysis Tools**: Built-in functions for common analysis tasks in fixed income markets.
57
- - **Easy Integration**: Seamless integration with Python data analysis workflows.
58
+ - **Easy Integration**: Seamless integration with pandas data analysis workflows.
58
59
  - **Type Hints**: Full support for static type checking, enhancing development experience and code quality.
59
60
 
60
61
  ## Installation
@@ -63,30 +64,64 @@ You can install PYield using pip:
63
64
  ```sh
64
65
  pip install pyield
65
66
  ```
67
+
66
68
  ## How to use PYield
67
- ### Getting DI Futures Data
69
+
70
+ ### Futures Data
68
71
  ```python
69
72
  import pyield as yd
70
73
 
71
- # Get a pandas dataframe with the DI processed data from B3 (default)
72
- >>> yd.get_di(trade_date='2024-03-08')
73
- TradeDate ExpirationCode ExpirationDate BDToExpiration ... LastRate LastAskRate LastBidRate SettlementRate
74
- 2024-03-08 J24 2024-04-01 15 ... 10.952 10.952 10.956 10.956
75
- 2024-03-08 K24 2024-05-02 37 ... 10.776 10.774 10.780 10.777
76
- 2024-03-08 M24 2024-06-03 58 ... 10.604 10.602 10.604 10.608
77
- ... ... ... ... ... ... ... ... ...
78
- 2024-03-08 F37 2037-01-02 3213 ... <NA> <NA> <NA> 10.859
79
- 2024-03-08 F38 2038-01-04 3462 ... <NA> <NA> <NA> 10.859
80
- 2024-03-08 F39 2039-01-03 3713 ... <NA> <NA> <NA> 10.85
74
+ # Get a DataFrame with the DI Futures data from B3
75
+ >>> yd.get_data(asset_code="DI1", reference_date='2024-03-08')
76
+
77
+ TradeDate ExpirationCode ExpirationDate BDToExpiration ... LastRate LastAskRate LastBidRate SettlementRate
78
+ 2024-03-08 J24 2024-04-01 15 ... 10.952 10.952 10.956 10.956
79
+ 2024-03-08 K24 2024-05-02 37 ... 10.776 10.774 10.780 10.777
80
+ 2024-03-08 M24 2024-06-03 58 ... 10.604 10.602 10.604 10.608
81
+ ... ... ... ... ... ... ... ... ...
82
+ 2024-03-08 F37 2037-01-02 3213 ... <NA> <NA> <NA> 10.859
83
+ 2024-03-08 F38 2038-01-04 3462 ... <NA> <NA> <NA> 10.859
84
+ 2024-03-08 F39 2039-01-03 3713 ... <NA> <NA> <NA> 10.85
85
+ ```
86
+
87
+ ### Treasury Bonds Data
88
+ ```python
89
+ # Get a DataFrame with the NTN-B data from ANBIMA
90
+ # Anbima data is available for the last 5 working days
91
+ # Obs: Anbima members have access to the full history
92
+ >>> yd.get_data(asset_code="NTN-B", reference_date='2024-04-12')
93
+
94
+ BondType ReferenceDate MaturityDate BidRate AskRate IndicativeRate Price
95
+ NTN-B 2024-04-12 2024-08-15 0.07540 0.07504 0.07523 4,271.43565
96
+ NTN-B 2024-04-12 2025-05-15 0.05945 0.05913 0.05930 4,361.34391
97
+ NTN-B 2024-04-12 2026-08-15 0.05927 0.05897 0.05910 4,301.40082
98
+ ... ... ... ... ... ... ...
99
+ NTN-B 2024-04-12 2050-08-15 0.06039 0.06006 0.06023 4,299.28233
100
+ NTN-B 2024-04-12 2055-05-15 0.06035 0.05998 0.06017 4,367.13360
101
+ NTN-B 2024-04-12 2060-08-15 0.06057 0.06016 0.06036 4,292.26323
102
+ ```
103
+
104
+ ### Spreads Calculation
105
+ ```python
106
+ # Calculate the spread between two DI Futures contracts and the pre-fix bonds
107
+ >>> yd.calculate_spreads(spread_type="di_vs_pre", reference_date="2024-4-11")
108
+
109
+ BondType ReferenceDate MaturityDate DISpread
110
+ LTN 2024-04-11 2024-07-01 -20.28000
111
+ LTN 2024-04-11 2024-10-01 -10.19000
112
+ LTN 2024-04-11 2025-01-01 -15.05000
113
+ ... ... ... ...
114
+ NTN-F 2024-04-11 2031-01-01 -0.66000
115
+ NTN-F 2024-04-11 2033-01-01 -5.69000
116
+ NTN-F 2024-04-11 2035-01-01 -1.27000
81
117
  ```
118
+
82
119
  ### Business Days Tools (Brazilian holidays are automatically considered)
83
120
  ```python
84
- # Generate a pandas series with the business days between two dates
85
- >>> yd.generate_bdays(start='2023-12-29', end='2024-01-03')
86
- 0 2023-12-29
87
- 1 2024-01-02
88
- 2 2024-01-03
89
- dtype: datetime64[ns]
121
+ # Count the number of business days between two dates
122
+ # Start date is included, end date is excluded
123
+ >>> yd.count_bdays(start='2023-12-29', end='2024-01-02')
124
+ 1
90
125
 
91
126
  # Get the next business day after a given date (offset=1)
92
127
  >>> yd.offset_bdays(dates="2023-12-29", offset=1)
@@ -100,21 +135,10 @@ Timestamp('2024-01-02 00:00:00')
100
135
  >>> yd.offset_bdays(dates="2023-12-29", offset=0)
101
136
  Timestamp('2023-12-29 00:00:00')
102
137
 
103
- # Count the number of business days between two dates
104
- # Start date is included, end date is excluded
105
- >>> yd.count_bdays(start='2023-12-29', end='2024-01-02')
106
- 1
138
+ # Generate a pandas series with the business days between two dates
139
+ >>> yd.generate_bdays(start='2023-12-29', end='2024-01-03')
140
+ 0 2023-12-29
141
+ 1 2024-01-02
142
+ 2 2024-01-03
143
+ dtype: datetime64[ns]
107
144
  ```
108
-
109
- ## Documentation
110
-
111
- For detailed documentation on all features and functionalities, please visit PYield Documentation.
112
- Contributing
113
-
114
- Contributions to PYield are welcome! Please read our Contributing Guidelines for details on how to submit pull requests, report issues, or suggest enhancements.
115
- License
116
-
117
- PYield is licensed under the MIT License.
118
- Acknowledgments
119
-
120
- PYield was developed with the support of the Python community and financial analysts in Brazil. Special thanks to the maintainers of Pandas and Requests for their invaluable libraries.
pyield-0.6.0/README.md ADDED
@@ -0,0 +1,102 @@
1
+ [![PyPI version](https://img.shields.io/pypi/v/pyield.svg)](https://pypi.python.org/pypi/pyield)
2
+ [![Made with Python](https://img.shields.io/badge/Python->=3.11-blue?logo=python&logoColor=white)](https://python.org "Go to Python homepage")
3
+ [![License](https://img.shields.io/badge/License-MIT-blue)](#license)
4
+
5
+ # PYield: Fixed Income Toolbox for Brazilian Markets
6
+
7
+ ## Introduction
8
+
9
+ Welcome to PYield, a Python library designed for the analysis of fixed income instruments in Brazil. This library is tailored for financial analysts, researchers, and enthusiasts interested in the Brazilian fixed income market. Leveraging the power of popular Python libraries like Pandas and Requests, PYield simplifies the process of obtaining and processing data from key sources such as ANBIMA and B3.
10
+
11
+ ## Features
12
+
13
+ - **Data Collection**: Automated fetching of data from ANBIMA and B3.
14
+ - **Data Processing**: Efficient processing and normalization of fixed income data.
15
+ - **Analysis Tools**: Built-in functions for common analysis tasks in fixed income markets.
16
+ - **Easy Integration**: Seamless integration with pandas data analysis workflows.
17
+ - **Type Hints**: Full support for static type checking, enhancing development experience and code quality.
18
+
19
+ ## Installation
20
+
21
+ You can install PYield using pip:
22
+ ```sh
23
+ pip install pyield
24
+ ```
25
+
26
+ ## How to use PYield
27
+
28
+ ### Futures Data
29
+ ```python
30
+ import pyield as yd
31
+
32
+ # Get a DataFrame with the DI Futures data from B3
33
+ >>> yd.get_data(asset_code="DI1", reference_date='2024-03-08')
34
+
35
+ TradeDate ExpirationCode ExpirationDate BDToExpiration ... LastRate LastAskRate LastBidRate SettlementRate
36
+ 2024-03-08 J24 2024-04-01 15 ... 10.952 10.952 10.956 10.956
37
+ 2024-03-08 K24 2024-05-02 37 ... 10.776 10.774 10.780 10.777
38
+ 2024-03-08 M24 2024-06-03 58 ... 10.604 10.602 10.604 10.608
39
+ ... ... ... ... ... ... ... ... ...
40
+ 2024-03-08 F37 2037-01-02 3213 ... <NA> <NA> <NA> 10.859
41
+ 2024-03-08 F38 2038-01-04 3462 ... <NA> <NA> <NA> 10.859
42
+ 2024-03-08 F39 2039-01-03 3713 ... <NA> <NA> <NA> 10.85
43
+ ```
44
+
45
+ ### Treasury Bonds Data
46
+ ```python
47
+ # Get a DataFrame with the NTN-B data from ANBIMA
48
+ # Anbima data is available for the last 5 working days
49
+ # Obs: Anbima members have access to the full history
50
+ >>> yd.get_data(asset_code="NTN-B", reference_date='2024-04-12')
51
+
52
+ BondType ReferenceDate MaturityDate BidRate AskRate IndicativeRate Price
53
+ NTN-B 2024-04-12 2024-08-15 0.07540 0.07504 0.07523 4,271.43565
54
+ NTN-B 2024-04-12 2025-05-15 0.05945 0.05913 0.05930 4,361.34391
55
+ NTN-B 2024-04-12 2026-08-15 0.05927 0.05897 0.05910 4,301.40082
56
+ ... ... ... ... ... ... ...
57
+ NTN-B 2024-04-12 2050-08-15 0.06039 0.06006 0.06023 4,299.28233
58
+ NTN-B 2024-04-12 2055-05-15 0.06035 0.05998 0.06017 4,367.13360
59
+ NTN-B 2024-04-12 2060-08-15 0.06057 0.06016 0.06036 4,292.26323
60
+ ```
61
+
62
+ ### Spreads Calculation
63
+ ```python
64
+ # Calculate the spread between two DI Futures contracts and the pre-fix bonds
65
+ >>> yd.calculate_spreads(spread_type="di_vs_pre", reference_date="2024-4-11")
66
+
67
+ BondType ReferenceDate MaturityDate DISpread
68
+ LTN 2024-04-11 2024-07-01 -20.28000
69
+ LTN 2024-04-11 2024-10-01 -10.19000
70
+ LTN 2024-04-11 2025-01-01 -15.05000
71
+ ... ... ... ...
72
+ NTN-F 2024-04-11 2031-01-01 -0.66000
73
+ NTN-F 2024-04-11 2033-01-01 -5.69000
74
+ NTN-F 2024-04-11 2035-01-01 -1.27000
75
+ ```
76
+
77
+ ### Business Days Tools (Brazilian holidays are automatically considered)
78
+ ```python
79
+ # Count the number of business days between two dates
80
+ # Start date is included, end date is excluded
81
+ >>> yd.count_bdays(start='2023-12-29', end='2024-01-02')
82
+ 1
83
+
84
+ # Get the next business day after a given date (offset=1)
85
+ >>> yd.offset_bdays(dates="2023-12-29", offset=1)
86
+ Timestamp('2024-01-02 00:00:00')
87
+
88
+ # Get the next business day if it is not a business day (offset=0)
89
+ >>> yd.offset_bdays(dates="2023-12-30", offset=0)
90
+ Timestamp('2024-01-02 00:00:00')
91
+
92
+ # Since 2023-12-29 is a business day, it returns the same date (offset=0)
93
+ >>> yd.offset_bdays(dates="2023-12-29", offset=0)
94
+ Timestamp('2023-12-29 00:00:00')
95
+
96
+ # Generate a pandas series with the business days between two dates
97
+ >>> yd.generate_bdays(start='2023-12-29', end='2024-01-03')
98
+ 0 2023-12-29
99
+ 1 2024-01-02
100
+ 2 2024-01-03
101
+ dtype: datetime64[ns]
102
+ ```
@@ -0,0 +1 @@
1
+ __version__ = "0.6.0"
@@ -0,0 +1,14 @@
1
+ from .__about__ import __version__
2
+ from .bday import count_bdays, generate_bdays, is_bday, offset_bdays
3
+ from .data_access import get_data
4
+ from .data_analysis import calculate_spreads
5
+
6
+ __all__ = [
7
+ "__version__",
8
+ "is_bday",
9
+ "generate_bdays",
10
+ "offset_bdays",
11
+ "count_bdays",
12
+ "get_data",
13
+ "calculate_spreads",
14
+ ]
@@ -0,0 +1,342 @@
1
+ from datetime import datetime
2
+ from typing import Literal, overload
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+
7
+ from .holidays import BrHolidays
8
+
9
+ SingleDateTypes = str | np.datetime64 | pd.Timestamp | datetime
10
+ SeriesDateTypes = list | tuple | np.ndarray | pd.Series | pd.Index | pd.DatetimeIndex
11
+
12
+ TO_TIMESTAMP_TYPES = (str, np.datetime64, datetime)
13
+ TO_SERIES_TYPES = (list, tuple, np.ndarray, pd.Series, pd.Index, pd.DatetimeIndex)
14
+
15
+ # Initialize the BrHolidays class
16
+ br_holidays = BrHolidays()
17
+
18
+
19
+ @overload
20
+ def _normalize_input_dates(
21
+ dates: SingleDateTypes | None,
22
+ ) -> pd.Timestamp: ...
23
+
24
+
25
+ @overload
26
+ def _normalize_input_dates(
27
+ dates: SeriesDateTypes,
28
+ ) -> pd.Series: ...
29
+
30
+
31
+ def _normalize_input_dates(
32
+ dates: SingleDateTypes | SeriesDateTypes | None = None,
33
+ ) -> pd.Timestamp | pd.Series:
34
+ if dates is None:
35
+ return pd.Timestamp.today().normalize()
36
+ elif isinstance(dates, pd.Timestamp):
37
+ return dates.normalize()
38
+ elif isinstance(dates, TO_TIMESTAMP_TYPES):
39
+ return pd.Timestamp(dates).normalize()
40
+ elif isinstance(dates, TO_SERIES_TYPES):
41
+ result = pd.to_datetime(dates)
42
+ return pd.Series(result).dt.normalize()
43
+ else:
44
+ raise ValueError("Invalid date format.")
45
+
46
+
47
+ def is_bday(date: SingleDateTypes | None = None) -> bool:
48
+ """
49
+ Checks if the input date is a business day.
50
+
51
+ Args:
52
+ date (str | np.datetime64 | pd.Timestamp | datetime, optional): The date to
53
+ check. If None, the current date is used.
54
+
55
+ Returns:
56
+ bool: True if the input date is a business day, False otherwise.
57
+
58
+ Examples:
59
+ >>> yd.is_bday('2023-12-25') # Christmas
60
+ False
61
+ >>> yd.is_bday() # Check if today is a business day
62
+ True
63
+ """
64
+ normalized_date = _normalize_input_dates(date)
65
+ # Shift the date if it is not a business day
66
+ adjusted_date = offset_bdays(normalized_date, 0)
67
+ return normalized_date == adjusted_date
68
+
69
+
70
+ def _convert_to_numpy_date(
71
+ dates: pd.Timestamp | pd.Series,
72
+ ) -> np.datetime64 | np.ndarray:
73
+ """
74
+ Converts the input dates to a numpy datetime64[D] format.
75
+
76
+ Args:
77
+ dates (Timestamp | Series): A single date or a Series of dates.
78
+
79
+ Returns:
80
+ np.datetime64 | np.ndarray: The input dates in a numpy datetime64[D] format.
81
+ """
82
+ if isinstance(dates, pd.Timestamp):
83
+ return np.datetime64(dates, "D")
84
+ else:
85
+ return dates.to_numpy().astype("datetime64[D]")
86
+
87
+
88
+ @overload
89
+ def offset_bdays(
90
+ dates: SingleDateTypes | None = None,
91
+ offset: int = 0,
92
+ roll: Literal["forward", "backward"] = "forward",
93
+ holiday_list: Literal["old", "new", "infer"] = "infer",
94
+ ) -> pd.Timestamp: ...
95
+
96
+
97
+ @overload
98
+ def offset_bdays(
99
+ dates: SeriesDateTypes,
100
+ offset: int = 0,
101
+ roll: Literal["forward", "backward"] = "forward",
102
+ holiday_list: Literal["old", "new", "infer"] = "infer",
103
+ ) -> pd.Series: ...
104
+
105
+
106
+ def offset_bdays(
107
+ dates: SingleDateTypes | SeriesDateTypes | None = None,
108
+ offset: int = 0,
109
+ roll: Literal["forward", "backward"] = "forward",
110
+ holiday_list: Literal["old", "new", "infer"] = "infer",
111
+ ) -> pd.Timestamp | pd.Series:
112
+ """
113
+ Offsets the dates to the next or previous business day, considering brazilian
114
+ holidays. This function supports both single dates and collections of dates,
115
+ handling them intelligently to return either a single offset date or a series of
116
+ offset dates. It is a wrapper for `numpy.busday_offset` adapted for Pandas data
117
+ types and holiday adjustments.
118
+
119
+ Args:
120
+ dates (str | np.datetime64 | pd.Timestamp | datetime | list | tuple | np.ndarray
121
+ | pd.Series | pd.Index | pd.DatetimeIndex, optional):
122
+ The date(s) to offset. Can be a single date in various formats (string,
123
+ `datetime`, `Timestamp`, etc.) or a collection of dates (list, tuple,
124
+ `Series`, etc.). If None, the current date is used.
125
+ offset (int): The number of business days to offset the dates. Positive for
126
+ future dates, negative for past dates. Zero will return the same date if
127
+ it's a business day, or the next business day otherwise.
128
+ roll (Literal["forward", "backward"], optional): Direction to roll the date if
129
+ it falls on a holiday or weekend. 'forward' to the next business day,
130
+ 'backward' to the previous. Defaults to 'forward'.
131
+ holiday_list (Literal["old", "new", "infer"], optional):
132
+ The list of holidays to consider. 'old' or 'new' use predefined lists, while
133
+ 'infer' determines the most appropriate list based on the input dates.
134
+ Defaults to "infer".
135
+
136
+ Returns:
137
+ pd.Timestamp | pd.Series: If a single date is provided, returns a single
138
+ `Timestamp` of the offset date. If a series of dates is provided, returns a
139
+ `Series` of offset dates.
140
+
141
+ Examples:
142
+ >>> date = '2023-12-23' # Saturday before Christmas
143
+ >>> yd.offset_bdays(date, 0)
144
+ Timestamp('2023-12-26')
145
+
146
+ >>> date = '2023-12-22' # Friday before Christmas
147
+ >>> yd.offset_bdays(date, 0)
148
+ Timestamp('2023-12-22') # No offset because it's a business day
149
+
150
+ >>> yd.offset_bdays(date, 1)
151
+ Timestamp('2023-12-26') # Offset to the next business day
152
+
153
+ >>> yd.offset_bdays(date, -1)
154
+ Timestamp('2023-12-21') # Offset to the previous business day
155
+
156
+ Note:
157
+ This function uses `numpy.busday_offset` under the hood, which means it follows
158
+ the same conventions and limitations for business day calculations. For detailed
159
+ information on error handling and behavior, refer to the `numpy.busday_offset`
160
+ documentation: https://numpy.org/doc/stable/reference/generated/numpy.busday_offset.html
161
+ """
162
+ normalized_dates = _normalize_input_dates(dates)
163
+
164
+ selected_holidays = br_holidays.get_applicable_holidays(
165
+ normalized_dates, holiday_list
166
+ )
167
+ selected_holidays_np = _convert_to_numpy_date(selected_holidays)
168
+
169
+ dates_np = _convert_to_numpy_date(normalized_dates)
170
+ offsetted_dates_np = np.busday_offset(
171
+ dates_np, offsets=offset, roll=roll, holidays=selected_holidays_np
172
+ )
173
+ if isinstance(offsetted_dates_np, np.datetime64):
174
+ return pd.Timestamp(offsetted_dates_np, unit="ns")
175
+ else:
176
+ result = pd.to_datetime(offsetted_dates_np, unit="ns")
177
+ return pd.Series(result)
178
+
179
+
180
+ @overload
181
+ def count_bdays(
182
+ start: SingleDateTypes | None = None,
183
+ end: SingleDateTypes | None = None,
184
+ holiday_list: Literal["old", "new", "infer"] = "infer",
185
+ ) -> int: ...
186
+
187
+
188
+ @overload
189
+ def count_bdays(
190
+ start: SeriesDateTypes,
191
+ end: SingleDateTypes | None,
192
+ holiday_list: Literal["old", "new", "infer"] = "infer",
193
+ ) -> pd.Series: ...
194
+
195
+
196
+ @overload
197
+ def count_bdays(
198
+ start: SingleDateTypes | None,
199
+ end: SeriesDateTypes,
200
+ holiday_list: Literal["old", "new", "infer"] = "infer",
201
+ ) -> pd.Series: ...
202
+
203
+
204
+ @overload
205
+ def count_bdays(
206
+ start: SeriesDateTypes,
207
+ end: SeriesDateTypes,
208
+ holiday_list: Literal["old", "new", "infer"] = "infer",
209
+ ) -> pd.Series: ...
210
+
211
+
212
+ def count_bdays(
213
+ start: SingleDateTypes | SeriesDateTypes | None = None,
214
+ end: SingleDateTypes | SeriesDateTypes | None = None,
215
+ holiday_list: Literal["old", "new", "infer"] = "infer",
216
+ ) -> int | pd.Series:
217
+ """
218
+ Counts the number of business days between a `start` and `end` date(s), inclusively
219
+ for the start date and exclusively for the end date. The function can handle single
220
+ dates, arrays of dates, and mixed inputs, returning either a single integer or a
221
+ Series depending on the inputs. It accounts for specified holidays, effectively
222
+ excluding them from the business day count.
223
+
224
+ Args:
225
+ start (str | np.datetime64 | pd.Timestamp | datetime | list | tuple |
226
+ np.ndarray | pd.Series | pd.Index | pd.DatetimeIndex, optional):
227
+ The start date(s) for counting. Defaults to the current date if None.
228
+ end (str | np.datetime64 | pd.Timestamp | datetime | list | tuple |
229
+ np.ndarray | pd.Series | pd.Index | pd.DatetimeIndex, optional):
230
+ The end date(s) for counting, which are excluded from the count themselves.
231
+ Defaults to the current date if None.
232
+ holiday_list (Literal["old", "new", "infer"], optional):
233
+ Specifies which set of holidays to consider in the count. 'old' or 'new'
234
+ refer to predefined holiday lists, while 'infer' automatically selects the
235
+ list based on the most recent date in the input. Defaults to "infer".
236
+
237
+ Returns:
238
+ int | pd.Series: Returns an integer if `start` and `end` are single dates,
239
+ or a Series if either or both are arrays of dates. The value(s) represent
240
+ the count of business days between `start` and `end`.
241
+
242
+ Notes:
243
+ - This function is a wrapper around `numpy.busday_count`, adapted to work
244
+ directly with various Pandas and Numpy date formats.
245
+ - It supports flexible date inputs, including single dates, lists, Series, and
246
+ more, for both `start` and `end` parameters.
247
+ - The return type depends on the input types: single dates return an int, while
248
+ arrays of dates return a pd.Series with the count for each date range.
249
+ - See `numpy.busday_count` documentation for more details on how holidays are
250
+ handled and how business day counts are calculated:
251
+ https://numpy.org/doc/stable/reference/generated/numpy.busday_count.html.
252
+
253
+ Examples:
254
+ >>> yd.count_bdays('2023-12-15', '2024-01-01')
255
+ 10
256
+
257
+ >>> start = '2023-01-01'
258
+ >>> end = pd.to_datetime(['2023-01-31', '2023-03-01'])
259
+ >>> yd.count_bdays(start, end)
260
+ pd.Series([22, 40], dtype='int64')
261
+ """
262
+ normalized_start = _normalize_input_dates(start)
263
+ normalized_end = _normalize_input_dates(end)
264
+
265
+ # Determine which list of holidays to use
266
+ selected_holidays = br_holidays.get_applicable_holidays(
267
+ normalized_start, holiday_list
268
+ )
269
+ selected_holidays_np = _convert_to_numpy_date(selected_holidays)
270
+
271
+ # Convert inputs to numpy datetime64[D] before calling numpy.busday_count
272
+ start_np = _convert_to_numpy_date(normalized_start)
273
+ end_np = _convert_to_numpy_date(normalized_end)
274
+
275
+ result_np = np.busday_count(start_np, end_np, holidays=selected_holidays_np)
276
+ if isinstance(result_np, np.int64):
277
+ return int(result_np)
278
+ else:
279
+ return pd.Series(result_np, dtype="Int64")
280
+
281
+
282
+ def generate_bdays(
283
+ start: SingleDateTypes | None = None,
284
+ end: SingleDateTypes | None = None,
285
+ inclusive: Literal["both", "neither", "left", "right"] = "both",
286
+ holiday_list: Literal["old", "new", "infer"] = "infer",
287
+ **kwargs,
288
+ ) -> pd.Series:
289
+ """
290
+ Generates a Series of business days between a `start` and `end` date, considering
291
+ the list of Brazilian holidays. It supports customization of holiday lists and
292
+ inclusion options for start and end dates. It wraps `pandas.bdate_range`.
293
+
294
+ Args:
295
+ start (str | np.datetime64 | pd.Timestamp | datetime, optional):
296
+ The start date for generating business days. Defaults to None, using the
297
+ current date.
298
+ end (str | np.datetime64 | pd.Timestamp | datetime, optional):
299
+ The end date for generating business days. Defaults to None, using the
300
+ current date.
301
+ inclusive (Literal["both", "neither", "left", "right"], optional):
302
+ Determines which of the start and end dates are included in the result.
303
+ Valid options are 'both', 'neither', 'left', 'right'. Defaults to 'both'.
304
+ holiday_list (Literal["old", "new", "infer"], optional):
305
+ Specifies the list of holidays to consider. 'old' or 'new' refer to
306
+ predefined lists, 'infer' selects the list based on the most recent date in
307
+ the range. Defaults to "infer".
308
+ **kwargs:
309
+ Additional keyword arguments passed to `pandas.bdate_range` for
310
+ customization.
311
+
312
+ Returns:
313
+ pd.Series: A Series representing a range of business days between the specified
314
+ start and end dates, considering the specified holidays.
315
+
316
+ Examples:
317
+ >>> yd.generate_bdays(start='2023-12-22', end='2024-01-02')
318
+ pd.Series(['2023-12-22', '2023-12-26', '2023-12-27', '2023-12-28', '2023-12-29',
319
+ '2024-01-02'], dtype='datetime64[ns]')
320
+
321
+ Note:
322
+ For detailed information on parameters and error handling, refer to
323
+ `pandas.bdate_range` documentation:
324
+ https://pandas.pydata.org/docs/reference/api/pandas.bdate_range.html.
325
+ """
326
+ normalized_start = _normalize_input_dates(start)
327
+ normalized_end = _normalize_input_dates(end)
328
+
329
+ selected_holidays = br_holidays.get_applicable_holidays(
330
+ normalized_start, holiday_list
331
+ )
332
+ selected_holidays_list = selected_holidays.to_list()
333
+
334
+ result = pd.bdate_range(
335
+ normalized_start,
336
+ normalized_end,
337
+ freq="C",
338
+ inclusive=inclusive,
339
+ holidays=selected_holidays_list,
340
+ **kwargs,
341
+ )
342
+ return pd.Series(result)
@@ -0,0 +1,51 @@
1
+ import pandas as pd
2
+
3
+ from . import di
4
+ from . import treasuries as tr
5
+ from .utils import _normalize_date
6
+
7
+
8
+ def get_data(
9
+ asset_code: str,
10
+ reference_date: str | pd.Timestamp | None = None,
11
+ **kwargs,
12
+ ) -> pd.DataFrame:
13
+ """
14
+ Fetches data for a specified asset type and reference date.
15
+
16
+ Args:
17
+ asset (str): The asset type. Available options are:
18
+ - "TRB": Fetches indicative rates for Brazilian treasury bonds from ANBIMA.
19
+ - "LTN": Fetches indicative rates for Brazilian LTN bonds from ANBIMA.
20
+ - "LFT": Fetches indicative rates for Brazilian LFT bonds from ANBIMA.
21
+ - "NTN-F": Fetches indicative rates for Brazilian NTN-F bonds from ANBIMA.
22
+ - "NTN-B": Fetches indicative rates for Brazilian NTN-B bonds from ANBIMA.
23
+ - "DI1": Fetches DI Futures rates from B3.
24
+ reference_date (str): Reference date for the data in YYYY-MM-DD format.
25
+
26
+ Returns:
27
+ pd.DataFrame: A DataFrame containing the fetched data.
28
+
29
+ Raises:
30
+ ValueError: If the specified source or asset type is not supported.
31
+ """
32
+ # Extract the internal use parameter with default value
33
+ return_raw = kwargs.get("return_raw", False)
34
+
35
+ # Validate the date, defaulting to the previous business day if not provided
36
+ normalized_date = _normalize_date(reference_date)
37
+
38
+ if asset_code.lower() == "trb":
39
+ # Fetch all indicative treasury rates from ANBIMA
40
+ return tr.fetch_data(reference_date=normalized_date, return_raw=return_raw)
41
+ elif asset_code.lower() in ["ltn", "lft", "ntn-f", "ntn-b"]:
42
+ # Fetch indicative rates for a specific type of Brazilian treasury bond
43
+ df = tr.fetch_data(reference_date=normalized_date)
44
+ return df.query(f"BondType == '{asset_code.upper()}'")
45
+
46
+ elif asset_code.lower() == "di1":
47
+ return di.fetch_data(
48
+ trade_date=normalized_date, source_type="bmf", return_raw=return_raw
49
+ )
50
+ else:
51
+ raise ValueError("Asset type not supported.")