PYield 0.40.4__tar.gz → 0.40.6__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.
- {pyield-0.40.4 → pyield-0.40.6}/PKG-INFO +157 -156
- pyield-0.40.6/README.md +268 -0
- pyield-0.40.6/pyield/__about__.py +1 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/anbima/difusao.py +13 -11
- {pyield-0.40.4 → pyield-0.40.6}/pyield/anbima/ima.py +1 -1
- {pyield-0.40.4 → pyield-0.40.6}/pyield/anbima/imaq.py +35 -22
- {pyield-0.40.4 → pyield-0.40.6}/pyield/anbima/tpf.py +21 -36
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/di1.py +19 -18
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/di_over.py +5 -5
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/futures/__init__.py +11 -17
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/futures/xml.py +3 -3
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/auction.py +7 -7
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/ptax_api.py +7 -7
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/rates.py +21 -21
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/repo.py +4 -4
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/trades_monthly.py +5 -7
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/vna.py +6 -6
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bday/core.py +97 -81
- pyield-0.40.6/pyield/converters.py +76 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/fwd.py +7 -7
- {pyield-0.40.4 → pyield-0.40.6}/pyield/interpolator.py +5 -5
- {pyield-0.40.4 → pyield-0.40.6}/pyield/ipca/historical.py +9 -9
- {pyield-0.40.4 → pyield-0.40.6}/pyield/ipca/projected.py +2 -2
- pyield-0.40.6/pyield/retry.py +62 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/auctions.py +5 -5
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/benchmark.py +3 -3
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/lft.py +16 -18
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/ltn.py +25 -28
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/ntnb.py +59 -78
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/ntnc.py +28 -35
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/ntnf.py +87 -86
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/pre.py +6 -6
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/tools.py +26 -12
- {pyield-0.40.4 → pyield-0.40.6}/pyield/types.py +33 -20
- {pyield-0.40.4 → pyield-0.40.6}/pyproject.toml +0 -1
- pyield-0.40.4/README.md +0 -267
- pyield-0.40.4/pyield/__about__.py +0 -1
- pyield-0.40.4/pyield/converters.py +0 -97
- pyield-0.40.4/pyield/retry.py +0 -98
- {pyield-0.40.4 → pyield-0.40.6}/.gitignore +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/LICENSE +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/__init__.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/anbima/__init__.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/anbima/ettj_intraday.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/anbima/ettj_last.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/__init__.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/futures/common.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/futures/historical.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/b3/futures/intraday.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/__init__.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bc/trades_intraday.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bday/__init__.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bday/holidays/__init__.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bday/holidays/br_holidays_new.txt +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bday/holidays/br_holidays_old.txt +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/bday/holidays/brholidays.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/config.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/conftest.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/data_cache.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/ipca/__init__.py +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/py.typed +0 -0
- {pyield-0.40.4 → pyield-0.40.6}/pyield/tn/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PYield
|
|
3
|
-
Version: 0.40.
|
|
3
|
+
Version: 0.40.6
|
|
4
4
|
Summary: A Python library for analysis of fixed income instruments in Brazil
|
|
5
5
|
Project-URL: Source, https://github.com/crdcj/PYield
|
|
6
6
|
Author-email: Carlos Carvalho <cr.cj@outlook.com>
|
|
@@ -72,96 +72,70 @@ Visit the [full documentation for PYield](https://crdcj.github.io/PYield/).
|
|
|
72
72
|
- **Easy Integration**: Seamless integration with pandas data analysis workflows.
|
|
73
73
|
- **Type Hints**: Full support for static type checking, enhancing development experience and code quality.
|
|
74
74
|
|
|
75
|
-
##
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
`
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Referencing these unions in function docstrings means you can pass any of the listed types interchangeably; conversion is handled internally.
|
|
75
|
+
## Overview & Navigation
|
|
76
|
+
|
|
77
|
+
PYield is split into focused namespaces. Each function and class has a rich docstring (the online site is generated from them via MkDocs). The quickest learning path is: open a Python shell, import a namespace, call `help()`.
|
|
78
|
+
|
|
79
|
+
### Top-Level Namespace (Cheat Sheet)
|
|
80
|
+
Symbols exported directly by `pyield.__all__` (available via `from pyield import ...`). Prefer these first:
|
|
81
|
+
|
|
82
|
+
| Symbol | Kind | Purpose |
|
|
83
|
+
|--------|------|---------|
|
|
84
|
+
| `bday` | module | Business day calendar (count, offset, generate). |
|
|
85
|
+
| `anbima` | module | ANBIMA diffusion & curve endpoints. |
|
|
86
|
+
| `bc` | module | BCB indicators (SELIC Over, PTAX, repo rates). |
|
|
87
|
+
| `b3` | module | B3 domain (futures submodules). |
|
|
88
|
+
| `di1` | module | DI1 futures data & analytics. |
|
|
89
|
+
| `futures` | function | Fetch futures (see `help(futures)`). |
|
|
90
|
+
| `forward` | function | Single period forward rate from spot curve. |
|
|
91
|
+
| `forwards` | function | Vectorized forward rate construction. |
|
|
92
|
+
| `Interpolator` | class | Rate interpolation (linear / flat_forward). |
|
|
93
|
+
| `ltn` | module | LTN bond data & analytics. |
|
|
94
|
+
| `ntnb` | module | NTN-B pricing, spot, forward, BEI. |
|
|
95
|
+
| `ntnc` | module | NTN-C (if available in current dataset). |
|
|
96
|
+
| `ntnf` | module | NTN-F DI spreads & related analytics. |
|
|
97
|
+
| `lft` | module | LFT bond tools. |
|
|
98
|
+
| `pre` | module | Zero-coupon (pré-fixado) helpers. |
|
|
99
|
+
| `ipca` | module | Inflation historical & projections. |
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### Learning Path
|
|
103
|
+
1. Install: `pip install pyield`.
|
|
104
|
+
2. Choose a domain: e.g. bonds (`from pyield import ntnb`).
|
|
105
|
+
3. Inspect: `dir(ntnb)` then `help(ntnb.quotation)`.
|
|
106
|
+
4. Reproduce the docstring example verbatim.
|
|
107
|
+
5. Chain outputs (Polars DataFrames / Series) into your pipeline; convert to pandas only if unavoidable.
|
|
108
|
+
|
|
109
|
+
### Minimal Quick Start
|
|
110
|
+
```python
|
|
111
|
+
from pyield import bday, ntnb, bc
|
|
114
112
|
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
# Calendar
|
|
114
|
+
business_days = bday.count("02-01-2025", "15-01-2025")
|
|
117
115
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- ISO: `YYYY-MM-DD` (e.g., `2024-05-31`)
|
|
116
|
+
# Bond quotation (base 100)
|
|
117
|
+
q = ntnb.quotation("31-05-2024", "15-05-2035", 0.06149)
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- A collection of strings must not mix different styles; the first non-null value defines the format.
|
|
125
|
-
- Nulls are preserved; empty collections are not allowed.
|
|
119
|
+
# SELIC Over single day
|
|
120
|
+
selic = bc.selic_over("31-05-2024")
|
|
126
121
|
|
|
127
|
-
|
|
128
|
-
Always parse external inputs explicitly when constructing your own pipelines:
|
|
129
|
-
```python
|
|
130
|
-
import pandas as pd
|
|
131
|
-
dt_val = pd.to_datetime("31-05-2024", format="%d-%m-%Y")
|
|
132
|
-
iso_val = pd.to_datetime("2024-05-31", format="%Y-%m-%d")
|
|
122
|
+
print(business_days, q, selic)
|
|
133
123
|
```
|
|
134
124
|
|
|
135
|
-
###
|
|
125
|
+
### Docstrings = Source of Truth
|
|
126
|
+
If any README description conflicts with behavior, prefer the docstring. It documents:
|
|
127
|
+
* Parameters & types
|
|
128
|
+
* Edge cases / null semantics
|
|
129
|
+
* References (e.g. ANBIMA methodology PDFs)
|
|
130
|
+
* Examples guaranteed to run (CI checks)
|
|
136
131
|
|
|
137
|
-
|
|
132
|
+
See also: [Custom Types & Data Handling](#custom-types--data-handling) for input normalization rules.
|
|
138
133
|
|
|
139
|
-
|
|
140
|
-
- Scalar functions (dates, prices, quotations, spreads, durations): return `None` when any required argument is missing or empty.
|
|
141
|
-
- Collection (vectorized) functions: if the entire relevant input is missing/empty, return an empty Polars `DataFrame`/`Series` (or `None` for purely scalar semantics). Individual null elements propagate as `null` values in the resulting Polars Series/DataFrame.
|
|
142
|
-
- Empty collections where a shape is mandatory (e.g. an empty date array for conversion) raise `ValueError` rather than returning a silently empty result.
|
|
143
|
-
- Date string collections must share a single format; the first non-null defines it.
|
|
144
|
-
- Numeric computations only produce `NaN` when an internal arithmetic step yields an undefined value (rare — typical missing input short-circuits to `None`).
|
|
145
|
-
|
|
146
|
-
Examples:
|
|
147
|
-
```python
|
|
148
|
-
>>> from pyield import ntnb, bday
|
|
149
|
-
# Missing settlement -> None
|
|
150
|
-
>>> ntnb.quotation(None, "15-05-2035", 0.06149)
|
|
151
|
-
None
|
|
152
|
-
|
|
153
|
-
# Null start date in business day count -> None
|
|
154
|
-
>>> bday.count(None, "01-01-2025")
|
|
155
|
-
None
|
|
134
|
+
## Installation
|
|
156
135
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
Series: 'bdays' [i64]
|
|
161
|
-
[
|
|
162
|
-
22
|
|
163
|
-
null
|
|
164
|
-
]
|
|
136
|
+
You can install PYield using pip:
|
|
137
|
+
```sh
|
|
138
|
+
pip install pyield
|
|
165
139
|
```
|
|
166
140
|
## How to use PYield
|
|
167
141
|
### Brazilian Treasury Bonds Tools
|
|
@@ -222,88 +196,115 @@ datetime.date(2024, 1, 2)
|
|
|
222
196
|
# Returns same date if already business day (offset=0)
|
|
223
197
|
>>> bday.offset("29-12-2023", 0)
|
|
224
198
|
datetime.date(2023, 12, 29)
|
|
225
|
-
|
|
226
|
-
# Generate business day series
|
|
227
|
-
>>> bday.generate(start="22-12-2023", end="02-01-2024")
|
|
228
|
-
shape: (6,)
|
|
229
|
-
Series: '' [date]
|
|
230
|
-
[
|
|
231
|
-
2023-12-22
|
|
232
|
-
2023-12-26
|
|
233
|
-
2023-12-27
|
|
234
|
-
2023-12-28
|
|
235
|
-
2023-12-29
|
|
236
|
-
2024-01-02
|
|
237
|
-
]
|
|
238
199
|
```
|
|
239
200
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
201
|
+
## Custom Types & Data Handling
|
|
202
|
+
|
|
203
|
+
This section documents the internal typing and data normalization rules adopted across PYield so users can rely on predictable inputs/outputs and null semantics.
|
|
204
|
+
|
|
205
|
+
### DateLike (scalar inputs)
|
|
206
|
+
`DateLike` is a union used anywhere a single date is accepted:
|
|
207
|
+
|
|
208
|
+
* `str` (accepted formats below)
|
|
209
|
+
* `datetime.date`
|
|
210
|
+
* `datetime.datetime`
|
|
211
|
+
* `pandas.Timestamp`
|
|
212
|
+
* `numpy.datetime64`
|
|
213
|
+
|
|
214
|
+
Returned scalar dates are normalized to `datetime.date` (no timezone).
|
|
215
|
+
|
|
216
|
+
### ArrayLike (collection inputs)
|
|
217
|
+
`ArrayLike` covers any homogeneous collection of values accepted by vectorized functions:
|
|
218
|
+
|
|
219
|
+
* `Sequence[Any]` (e.g. `list`, `tuple`)
|
|
220
|
+
* `pandas.Series`
|
|
221
|
+
* `polars.Series`
|
|
222
|
+
* `numpy.ndarray`
|
|
223
|
+
|
|
224
|
+
Internally collections of date-like values are converted to a `polars.Series` with dtype `Date`.
|
|
225
|
+
|
|
226
|
+
### Supported Date String Formats
|
|
258
227
|
|
|
259
|
-
|
|
228
|
+
* Brazilian day‑first (dash): `DD-MM-YYYY` (e.g. `31-05-2024`)
|
|
229
|
+
* Brazilian day‑first (slash): `DD/MM/YYYY` (e.g. `31/05/2024`)
|
|
230
|
+
* ISO: `YYYY-MM-DD` (e.g. `2024-05-31`)
|
|
231
|
+
|
|
232
|
+
Rules:
|
|
233
|
+
1. No ambiguous inference: `2024-05-06` is always ISO (`YYYY-MM-DD`).
|
|
234
|
+
2. Collections: the first non-null/non-empty string determines the format for the entire collection.
|
|
235
|
+
3. Strings not matching that inferred format become `null` (instead of raising) to keep vectorization robust.
|
|
236
|
+
4. A collection containing only null/empty strings becomes a `Date` Series of all nulls.
|
|
237
|
+
|
|
238
|
+
Recommendation (defensive pipelines):
|
|
260
239
|
```python
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
>>> bc.selic_over_series("26-01-2025").head(5)
|
|
265
|
-
shape: (5, 2)
|
|
266
|
-
┌────────────┬────────┐
|
|
267
|
-
│ Date ┆ Value │
|
|
268
|
-
│ --- ┆ --- │
|
|
269
|
-
│ date ┆ f64 │
|
|
270
|
-
├────────────┼────────┤
|
|
271
|
-
│ 2025-01-27 ┆ 0.1215 │
|
|
272
|
-
│ 2025-01-28 ┆ 0.1215 │
|
|
273
|
-
│ 2025-01-29 ┆ 0.1215 │
|
|
274
|
-
│ 2025-01-30 ┆ 0.1315 │
|
|
275
|
-
│ 2025-01-31 ┆ 0.1315 │
|
|
276
|
-
└────────────┴────────┘
|
|
277
|
-
|
|
278
|
-
# SELIC Over for a single date
|
|
279
|
-
>>> bc.selic_over("31-05-2024")
|
|
280
|
-
0.104 # 10.40%
|
|
240
|
+
import pandas as pd
|
|
241
|
+
dt_val = pd.to_datetime("31-05-2024", format="%d-%m-%Y")
|
|
242
|
+
iso_val = pd.to_datetime("2024-05-31", format="%Y-%m-%d")
|
|
281
243
|
```
|
|
282
244
|
|
|
283
|
-
###
|
|
245
|
+
### Conversion Summary
|
|
246
|
+
|
|
247
|
+
| Input | Output Normalization |
|
|
248
|
+
|-------------------------------------|--------------------------------------|
|
|
249
|
+
| "31-05-2024" | datetime.date(2024, 5, 31) |
|
|
250
|
+
| ["31-05-2024", "01-06-2024"] | polars.Series<Date>[2024-05-31,…] |
|
|
251
|
+
| ["31-05-2024", None] | polars.Series<Date>[2024-05-31,null] |
|
|
252
|
+
| ["31-05-2024", "2024-06-01"] | second -> null (mismatched format) |
|
|
253
|
+
| [] (where shape mandatory) | ValueError (function-dependent) |
|
|
254
|
+
|
|
255
|
+
### Nullability & Early Short-Circuit
|
|
256
|
+
|
|
257
|
+
The internal helper `has_nullable_args(*args)` returns `True` if any argument is considered "nullable". An argument is nullable when it is:
|
|
258
|
+
|
|
259
|
+
* `None`
|
|
260
|
+
* `NaN` (float)
|
|
261
|
+
* Empty string `""`
|
|
262
|
+
* Empty collection: `[]`, `()`, `{}`
|
|
263
|
+
* Empty pandas `DataFrame` / `Series` / `Index`
|
|
264
|
+
* Empty polars `DataFrame` / `Series`
|
|
265
|
+
* NumPy `ndarray` with `size == 0`
|
|
266
|
+
|
|
267
|
+
Policy:
|
|
268
|
+
* Scalar-style functions:
|
|
269
|
+
* Pure date counters/adjusters may return `None` when a required scalar date is missing.
|
|
270
|
+
* Valuation / rate functions (`quotation`, `price`, `duration`, `dv01`) return `float('nan')` when inputs are nullable or a cash-flow schedule cannot be built.
|
|
271
|
+
* Vectorized functions: an entirely missing/empty driving input yields an empty `DataFrame`/`Series` (or `None` if semantics are purely scalar); element-level nulls propagate.
|
|
272
|
+
* Arithmetic emits `NaN` only for truly undefined operations—most missing cases short-circuit sooner (or return `nan` as above for valuation functions).
|
|
273
|
+
|
|
274
|
+
### Practical Examples
|
|
284
275
|
```python
|
|
285
|
-
>>> from pyield import
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
>>>
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
276
|
+
>>> from pyield import ntnb, bday
|
|
277
|
+
|
|
278
|
+
# Missing settlement -> nan (empty cash-flow schedule)
|
|
279
|
+
>>> ntnb.quotation(None, "15-05-2035", 0.06149)
|
|
280
|
+
nan
|
|
281
|
+
|
|
282
|
+
# Date output with null start date -> None
|
|
283
|
+
>>> bday.count(None, "01-01-2025")
|
|
284
|
+
None
|
|
285
|
+
|
|
286
|
+
# Element-level null propagation
|
|
287
|
+
>>> bday.count(["01-01-2024", None], "01-02-2024")
|
|
288
|
+
shape: (2,)
|
|
289
|
+
Series: 'bdays' [i64]
|
|
290
|
+
[
|
|
291
|
+
22
|
|
292
|
+
null
|
|
293
|
+
]
|
|
292
294
|
```
|
|
293
295
|
|
|
294
|
-
###
|
|
295
|
-
|
|
296
|
+
### Pandas Interop
|
|
297
|
+
Polars objects are the canonical return types. Convert explicitly when you need pandas:
|
|
296
298
|
```python
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
>>> known_bdays = [30, 60, 90]
|
|
300
|
-
>>> known_rates = [0.045, 0.05, 0.055]
|
|
301
|
-
>>> linear_interpolator = Interpolator("linear", known_bdays, known_rates)
|
|
302
|
-
>>> linear_interpolator(45) # Interpolate the interest rate for a given number of business days.
|
|
303
|
-
0.0475
|
|
304
|
-
|
|
305
|
-
# Use the flat forward method for interpolation.
|
|
306
|
-
>>> ff_interpolator = Interpolator("flat_forward", known_bdays, known_rates)
|
|
307
|
-
>>> ff_interpolator(45)
|
|
308
|
-
0.04833068080970859
|
|
299
|
+
df_pandas = df.to_pandas(use_pyarrow_extension_array=True)
|
|
300
|
+
series_pandas = s.to_pandas(use_pyarrow_extension_array=True)
|
|
309
301
|
```
|
|
302
|
+
|
|
303
|
+
### Rationale
|
|
304
|
+
Using Polars + Arrow dtypes provides:
|
|
305
|
+
* Deterministic schema & faster IO
|
|
306
|
+
* Efficient vectorized date casting
|
|
307
|
+
* Clear null vs. missing semantics
|
|
308
|
+
* Reduced overhead vs. repeated Pandas conversions
|
|
309
|
+
|
|
310
|
+
These conventions keep public APIs flexible on input while consistent on output.
|
pyield-0.40.6/README.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
[](https://pypi.python.org/pypi/pyield)
|
|
2
|
+
[](https://python.org "Go to Python homepage")
|
|
3
|
+
[](https://github.com/crdcj/PYield/blob/main/LICENSE)
|
|
4
|
+
|
|
5
|
+
# PYield: Brazilian Fixed Income Toolkit
|
|
6
|
+
|
|
7
|
+
PYield is a Python library designed for the analysis of Brazilian fixed income instruments. Leveraging the power of popular Python libraries like Polars, Pandas, Numpy and Requests, PYield simplifies the process of obtaining and processing data from key sources such as ANBIMA, BCB, IBGE and B3.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
### ✅ Polars migration from version 0.40.0 onwards:
|
|
11
|
+
|
|
12
|
+
All public functions now return **Polars DataFrames or Series** as the canonical format. This provides stronger typing, faster execution and more reliable date/rate handling. The last version to return Pandas objects by default was **0.39.xx**.
|
|
13
|
+
|
|
14
|
+
Need Pandas? Convert explicitly:
|
|
15
|
+
```python
|
|
16
|
+
df_pandas = df.to_pandas(use_pyarrow_extension_array=True)
|
|
17
|
+
series_pandas = s.to_pandas(use_pyarrow_extension_array=True)
|
|
18
|
+
```
|
|
19
|
+
The internal typing relies on PyArrow-backed dtypes for consistency across numeric and date operations.
|
|
20
|
+
|
|
21
|
+
## Documentation
|
|
22
|
+
|
|
23
|
+
Visit the [full documentation for PYield](https://crdcj.github.io/PYield/).
|
|
24
|
+
|
|
25
|
+
## Key Features
|
|
26
|
+
|
|
27
|
+
- **Data Collection**: Automated fetching of data from ANBIMA and B3.
|
|
28
|
+
- **Data Processing**: Efficient processing and normalization of fixed income data.
|
|
29
|
+
- **Analysis Tools**: Built-in functions for common analysis tasks in fixed income markets.
|
|
30
|
+
- **Easy Integration**: Seamless integration with pandas data analysis workflows.
|
|
31
|
+
- **Type Hints**: Full support for static type checking, enhancing development experience and code quality.
|
|
32
|
+
|
|
33
|
+
## Overview & Navigation
|
|
34
|
+
|
|
35
|
+
PYield is split into focused namespaces. Each function and class has a rich docstring (the online site is generated from them via MkDocs). The quickest learning path is: open a Python shell, import a namespace, call `help()`.
|
|
36
|
+
|
|
37
|
+
### Top-Level Namespace (Cheat Sheet)
|
|
38
|
+
Symbols exported directly by `pyield.__all__` (available via `from pyield import ...`). Prefer these first:
|
|
39
|
+
|
|
40
|
+
| Symbol | Kind | Purpose |
|
|
41
|
+
|--------|------|---------|
|
|
42
|
+
| `bday` | module | Business day calendar (count, offset, generate). |
|
|
43
|
+
| `anbima` | module | ANBIMA diffusion & curve endpoints. |
|
|
44
|
+
| `bc` | module | BCB indicators (SELIC Over, PTAX, repo rates). |
|
|
45
|
+
| `b3` | module | B3 domain (futures submodules). |
|
|
46
|
+
| `di1` | module | DI1 futures data & analytics. |
|
|
47
|
+
| `futures` | function | Fetch futures (see `help(futures)`). |
|
|
48
|
+
| `forward` | function | Single period forward rate from spot curve. |
|
|
49
|
+
| `forwards` | function | Vectorized forward rate construction. |
|
|
50
|
+
| `Interpolator` | class | Rate interpolation (linear / flat_forward). |
|
|
51
|
+
| `ltn` | module | LTN bond data & analytics. |
|
|
52
|
+
| `ntnb` | module | NTN-B pricing, spot, forward, BEI. |
|
|
53
|
+
| `ntnc` | module | NTN-C (if available in current dataset). |
|
|
54
|
+
| `ntnf` | module | NTN-F DI spreads & related analytics. |
|
|
55
|
+
| `lft` | module | LFT bond tools. |
|
|
56
|
+
| `pre` | module | Zero-coupon (pré-fixado) helpers. |
|
|
57
|
+
| `ipca` | module | Inflation historical & projections. |
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Learning Path
|
|
61
|
+
1. Install: `pip install pyield`.
|
|
62
|
+
2. Choose a domain: e.g. bonds (`from pyield import ntnb`).
|
|
63
|
+
3. Inspect: `dir(ntnb)` then `help(ntnb.quotation)`.
|
|
64
|
+
4. Reproduce the docstring example verbatim.
|
|
65
|
+
5. Chain outputs (Polars DataFrames / Series) into your pipeline; convert to pandas only if unavoidable.
|
|
66
|
+
|
|
67
|
+
### Minimal Quick Start
|
|
68
|
+
```python
|
|
69
|
+
from pyield import bday, ntnb, bc
|
|
70
|
+
|
|
71
|
+
# Calendar
|
|
72
|
+
business_days = bday.count("02-01-2025", "15-01-2025")
|
|
73
|
+
|
|
74
|
+
# Bond quotation (base 100)
|
|
75
|
+
q = ntnb.quotation("31-05-2024", "15-05-2035", 0.06149)
|
|
76
|
+
|
|
77
|
+
# SELIC Over single day
|
|
78
|
+
selic = bc.selic_over("31-05-2024")
|
|
79
|
+
|
|
80
|
+
print(business_days, q, selic)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Docstrings = Source of Truth
|
|
84
|
+
If any README description conflicts with behavior, prefer the docstring. It documents:
|
|
85
|
+
* Parameters & types
|
|
86
|
+
* Edge cases / null semantics
|
|
87
|
+
* References (e.g. ANBIMA methodology PDFs)
|
|
88
|
+
* Examples guaranteed to run (CI checks)
|
|
89
|
+
|
|
90
|
+
See also: [Custom Types & Data Handling](#custom-types--data-handling) for input normalization rules.
|
|
91
|
+
|
|
92
|
+
## Installation
|
|
93
|
+
|
|
94
|
+
You can install PYield using pip:
|
|
95
|
+
```sh
|
|
96
|
+
pip install pyield
|
|
97
|
+
```
|
|
98
|
+
## How to use PYield
|
|
99
|
+
### Brazilian Treasury Bonds Tools
|
|
100
|
+
```python
|
|
101
|
+
>>> from pyield import ltn, ntnb, ntnf
|
|
102
|
+
|
|
103
|
+
# Get ANBIMA LTN data for a given date
|
|
104
|
+
>>> ltn.data("23-08-2024")
|
|
105
|
+
shape: (13, 14)
|
|
106
|
+
┌──────────────┬─────────┬──────────┬──────────────┬───┬─────────┬─────────┬───────────────┬────────┐
|
|
107
|
+
│ ReferenceDate│ BondType│ SelicCode│ IssueBaseDate│ … │ BidRate │ AskRate │ IndicativeRate│ DIRate │
|
|
108
|
+
│ --- │ --- │ --- │ --- │ │ --- │ --- │ --- │ --- │
|
|
109
|
+
│ date │ str │ i64 │ date │ │ f64 │ f64 │ f64 │ f64 │
|
|
110
|
+
├──────────────┼─────────┼──────────┼──────────────┼───┼─────────┼─────────┼───────────────┼────────┤
|
|
111
|
+
│ 2024-08-23 │ LTN │ 100000 │ 2022-07-08 │ … │ 0.10459 │ 0.104252│ 0.104416 │ 0.10472│
|
|
112
|
+
│ 2024-08-23 │ LTN │ 100000 │ 2018-02-01 │ … │ 0.107366│ 0.107016│ 0.107171 │ 0.10823│
|
|
113
|
+
│ 2024-08-23 │ LTN │ 100000 │ 2023-01-06 │ … │ 0.110992│ 0.110746│ 0.110866 │ 0.11179│
|
|
114
|
+
│ … │ … │ … │ … │ … │ … │ … │ … │ … │
|
|
115
|
+
└──────────────┴─────────┴──────────┴──────────────┴───┴─────────┴─────────┴───────────────┴────────┘
|
|
116
|
+
|
|
117
|
+
# Calculate the quotation of an NTN-B bond (base 100, truncated to 4 decimals)
|
|
118
|
+
>>> ntnb.quotation("31-05-2024", "15-05-2035", 0.061490)
|
|
119
|
+
99.3651
|
|
120
|
+
>>> ntnb.quotation("31-05-2024", "15-08-2060", 0.061878)
|
|
121
|
+
99.5341
|
|
122
|
+
|
|
123
|
+
# DI Spreads: IndicativeRate - SettlementRate (bps=True multiplies by 10_000)
|
|
124
|
+
>>> ntnf.di_spreads("30-05-2025", bps=True)
|
|
125
|
+
shape: (5, 3)
|
|
126
|
+
┌─────────┬─────────────┬──────────┐
|
|
127
|
+
│ BondType│ MaturityDate│ DISpread │
|
|
128
|
+
│ --- │ --- │ --- │
|
|
129
|
+
│ str │ date │ f64 │
|
|
130
|
+
├─────────┼─────────────┼──────────┤
|
|
131
|
+
│ NTN-F │ 2027-01-01 │ -3.31 │
|
|
132
|
+
│ NTN-F │ 2029-01-01 │ 14.21 │
|
|
133
|
+
│ NTN-F │ 2031-01-01 │ 21.61 │
|
|
134
|
+
│ NTN-F │ 2033-01-01 │ 11.51 │
|
|
135
|
+
│ NTN-F │ 2035-01-01 │ 22.0 │
|
|
136
|
+
└─────────┴─────────────┴──────────┘
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Business Days Tools (Brazilian holidays automatically considered)
|
|
140
|
+
```python
|
|
141
|
+
>>> from pyield import bday
|
|
142
|
+
# Count business days (start inclusive, end exclusive)
|
|
143
|
+
>>> bday.count("29-12-2023", "02-01-2024")
|
|
144
|
+
1
|
|
145
|
+
|
|
146
|
+
# Next business day after given date (offset=1)
|
|
147
|
+
>>> bday.offset("29-12-2023", 1)
|
|
148
|
+
datetime.date(2024, 1, 2)
|
|
149
|
+
|
|
150
|
+
# Adjust to next business day when not a business day (offset=0)
|
|
151
|
+
>>> bday.offset("30-12-2023", 0)
|
|
152
|
+
datetime.date(2024, 1, 2)
|
|
153
|
+
|
|
154
|
+
# Returns same date if already business day (offset=0)
|
|
155
|
+
>>> bday.offset("29-12-2023", 0)
|
|
156
|
+
datetime.date(2023, 12, 29)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Custom Types & Data Handling
|
|
160
|
+
|
|
161
|
+
This section documents the internal typing and data normalization rules adopted across PYield so users can rely on predictable inputs/outputs and null semantics.
|
|
162
|
+
|
|
163
|
+
### DateLike (scalar inputs)
|
|
164
|
+
`DateLike` is a union used anywhere a single date is accepted:
|
|
165
|
+
|
|
166
|
+
* `str` (accepted formats below)
|
|
167
|
+
* `datetime.date`
|
|
168
|
+
* `datetime.datetime`
|
|
169
|
+
* `pandas.Timestamp`
|
|
170
|
+
* `numpy.datetime64`
|
|
171
|
+
|
|
172
|
+
Returned scalar dates are normalized to `datetime.date` (no timezone).
|
|
173
|
+
|
|
174
|
+
### ArrayLike (collection inputs)
|
|
175
|
+
`ArrayLike` covers any homogeneous collection of values accepted by vectorized functions:
|
|
176
|
+
|
|
177
|
+
* `Sequence[Any]` (e.g. `list`, `tuple`)
|
|
178
|
+
* `pandas.Series`
|
|
179
|
+
* `polars.Series`
|
|
180
|
+
* `numpy.ndarray`
|
|
181
|
+
|
|
182
|
+
Internally collections of date-like values are converted to a `polars.Series` with dtype `Date`.
|
|
183
|
+
|
|
184
|
+
### Supported Date String Formats
|
|
185
|
+
|
|
186
|
+
* Brazilian day‑first (dash): `DD-MM-YYYY` (e.g. `31-05-2024`)
|
|
187
|
+
* Brazilian day‑first (slash): `DD/MM/YYYY` (e.g. `31/05/2024`)
|
|
188
|
+
* ISO: `YYYY-MM-DD` (e.g. `2024-05-31`)
|
|
189
|
+
|
|
190
|
+
Rules:
|
|
191
|
+
1. No ambiguous inference: `2024-05-06` is always ISO (`YYYY-MM-DD`).
|
|
192
|
+
2. Collections: the first non-null/non-empty string determines the format for the entire collection.
|
|
193
|
+
3. Strings not matching that inferred format become `null` (instead of raising) to keep vectorization robust.
|
|
194
|
+
4. A collection containing only null/empty strings becomes a `Date` Series of all nulls.
|
|
195
|
+
|
|
196
|
+
Recommendation (defensive pipelines):
|
|
197
|
+
```python
|
|
198
|
+
import pandas as pd
|
|
199
|
+
dt_val = pd.to_datetime("31-05-2024", format="%d-%m-%Y")
|
|
200
|
+
iso_val = pd.to_datetime("2024-05-31", format="%Y-%m-%d")
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Conversion Summary
|
|
204
|
+
|
|
205
|
+
| Input | Output Normalization |
|
|
206
|
+
|-------------------------------------|--------------------------------------|
|
|
207
|
+
| "31-05-2024" | datetime.date(2024, 5, 31) |
|
|
208
|
+
| ["31-05-2024", "01-06-2024"] | polars.Series<Date>[2024-05-31,…] |
|
|
209
|
+
| ["31-05-2024", None] | polars.Series<Date>[2024-05-31,null] |
|
|
210
|
+
| ["31-05-2024", "2024-06-01"] | second -> null (mismatched format) |
|
|
211
|
+
| [] (where shape mandatory) | ValueError (function-dependent) |
|
|
212
|
+
|
|
213
|
+
### Nullability & Early Short-Circuit
|
|
214
|
+
|
|
215
|
+
The internal helper `has_nullable_args(*args)` returns `True` if any argument is considered "nullable". An argument is nullable when it is:
|
|
216
|
+
|
|
217
|
+
* `None`
|
|
218
|
+
* `NaN` (float)
|
|
219
|
+
* Empty string `""`
|
|
220
|
+
* Empty collection: `[]`, `()`, `{}`
|
|
221
|
+
* Empty pandas `DataFrame` / `Series` / `Index`
|
|
222
|
+
* Empty polars `DataFrame` / `Series`
|
|
223
|
+
* NumPy `ndarray` with `size == 0`
|
|
224
|
+
|
|
225
|
+
Policy:
|
|
226
|
+
* Scalar-style functions:
|
|
227
|
+
* Pure date counters/adjusters may return `None` when a required scalar date is missing.
|
|
228
|
+
* Valuation / rate functions (`quotation`, `price`, `duration`, `dv01`) return `float('nan')` when inputs are nullable or a cash-flow schedule cannot be built.
|
|
229
|
+
* Vectorized functions: an entirely missing/empty driving input yields an empty `DataFrame`/`Series` (or `None` if semantics are purely scalar); element-level nulls propagate.
|
|
230
|
+
* Arithmetic emits `NaN` only for truly undefined operations—most missing cases short-circuit sooner (or return `nan` as above for valuation functions).
|
|
231
|
+
|
|
232
|
+
### Practical Examples
|
|
233
|
+
```python
|
|
234
|
+
>>> from pyield import ntnb, bday
|
|
235
|
+
|
|
236
|
+
# Missing settlement -> nan (empty cash-flow schedule)
|
|
237
|
+
>>> ntnb.quotation(None, "15-05-2035", 0.06149)
|
|
238
|
+
nan
|
|
239
|
+
|
|
240
|
+
# Date output with null start date -> None
|
|
241
|
+
>>> bday.count(None, "01-01-2025")
|
|
242
|
+
None
|
|
243
|
+
|
|
244
|
+
# Element-level null propagation
|
|
245
|
+
>>> bday.count(["01-01-2024", None], "01-02-2024")
|
|
246
|
+
shape: (2,)
|
|
247
|
+
Series: 'bdays' [i64]
|
|
248
|
+
[
|
|
249
|
+
22
|
|
250
|
+
null
|
|
251
|
+
]
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Pandas Interop
|
|
255
|
+
Polars objects are the canonical return types. Convert explicitly when you need pandas:
|
|
256
|
+
```python
|
|
257
|
+
df_pandas = df.to_pandas(use_pyarrow_extension_array=True)
|
|
258
|
+
series_pandas = s.to_pandas(use_pyarrow_extension_array=True)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Rationale
|
|
262
|
+
Using Polars + Arrow dtypes provides:
|
|
263
|
+
* Deterministic schema & faster IO
|
|
264
|
+
* Efficient vectorized date casting
|
|
265
|
+
* Clear null vs. missing semantics
|
|
266
|
+
* Reduced overhead vs. repeated Pandas conversions
|
|
267
|
+
|
|
268
|
+
These conventions keep public APIs flexible on input while consistent on output.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.40.6"
|