PYield 0.43.1__tar.gz → 0.43.2__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 (66) hide show
  1. {pyield-0.43.1 → pyield-0.43.2}/PKG-INFO +69 -60
  2. pyield-0.43.2/README.md +204 -0
  3. pyield-0.43.2/pyield/__about__.py +1 -0
  4. pyield-0.43.2/pyield/_internal/__init__.py +5 -0
  5. {pyield-0.43.1/pyield → pyield-0.43.2/pyield/_internal}/converters.py +52 -61
  6. {pyield-0.43.1/pyield → pyield-0.43.2/pyield/_internal}/data_cache.py +1 -1
  7. {pyield-0.43.1 → pyield-0.43.2}/pyield/anbima/difusao.py +2 -2
  8. {pyield-0.43.1 → pyield-0.43.2}/pyield/anbima/ettj_intraday.py +1 -1
  9. {pyield-0.43.1 → pyield-0.43.2}/pyield/anbima/ettj_last.py +1 -1
  10. {pyield-0.43.1 → pyield-0.43.2}/pyield/anbima/ima.py +1 -1
  11. {pyield-0.43.1 → pyield-0.43.2}/pyield/anbima/imaq.py +2 -2
  12. {pyield-0.43.1 → pyield-0.43.2}/pyield/anbima/tpf.py +4 -4
  13. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/di1.py +37 -79
  14. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/di_over.py +2 -2
  15. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/futures/core.py +2 -2
  16. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/futures/historical/historical_b3.py +1 -1
  17. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/futures/historical/historical_bmf.py +1 -1
  18. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/futures/intraday.py +1 -1
  19. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/price_report.py +3 -3
  20. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/auction.py +3 -3
  21. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/ptax_api.py +3 -3
  22. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/rates.py +3 -3
  23. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/repo.py +3 -3
  24. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/trades_intraday.py +1 -1
  25. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/trades_monthly.py +3 -3
  26. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/vna.py +3 -3
  27. {pyield-0.43.1 → pyield-0.43.2}/pyield/bday/core.py +65 -53
  28. {pyield-0.43.1 → pyield-0.43.2}/pyield/fwd.py +1 -1
  29. {pyield-0.43.1 → pyield-0.43.2}/pyield/interpolator.py +1 -1
  30. {pyield-0.43.1 → pyield-0.43.2}/pyield/ipca/historical.py +3 -3
  31. {pyield-0.43.1 → pyield-0.43.2}/pyield/ipca/projected.py +1 -1
  32. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/auctions.py +3 -3
  33. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/lft.py +1 -1
  34. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/ltn.py +1 -1
  35. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/ntnb.py +2 -2
  36. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/ntnb1.py +2 -2
  37. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/ntnbprinc.py +26 -26
  38. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/ntnc.py +2 -2
  39. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/ntnf.py +2 -2
  40. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/pre.py +1 -1
  41. pyield-0.43.1/README.md +0 -195
  42. pyield-0.43.1/pyield/__about__.py +0 -1
  43. pyield-0.43.1/pyield/conftest.py +0 -24
  44. {pyield-0.43.1 → pyield-0.43.2}/.gitignore +0 -0
  45. {pyield-0.43.1 → pyield-0.43.2}/LICENSE +0 -0
  46. {pyield-0.43.1 → pyield-0.43.2}/pyield/__init__.py +0 -0
  47. {pyield-0.43.1/pyield → pyield-0.43.2/pyield/_internal}/retry.py +0 -0
  48. {pyield-0.43.1/pyield → pyield-0.43.2/pyield/_internal}/types.py +0 -0
  49. {pyield-0.43.1 → pyield-0.43.2}/pyield/anbima/__init__.py +0 -0
  50. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/__init__.py +0 -0
  51. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/common.py +0 -0
  52. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/futures/__init__.py +0 -0
  53. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/futures/historical/__init__.py +0 -0
  54. {pyield-0.43.1 → pyield-0.43.2}/pyield/b3/futures/historical/core.py +0 -0
  55. {pyield-0.43.1 → pyield-0.43.2}/pyield/bc/__init__.py +0 -0
  56. {pyield-0.43.1 → pyield-0.43.2}/pyield/bday/__init__.py +0 -0
  57. {pyield-0.43.1 → pyield-0.43.2}/pyield/bday/holidays/br_holidays_new.txt +0 -0
  58. {pyield-0.43.1 → pyield-0.43.2}/pyield/bday/holidays/br_holidays_old.txt +0 -0
  59. {pyield-0.43.1 → pyield-0.43.2}/pyield/bday/holidays/brholidays.py +0 -0
  60. {pyield-0.43.1 → pyield-0.43.2}/pyield/clock.py +0 -0
  61. {pyield-0.43.1 → pyield-0.43.2}/pyield/ipca/__init__.py +0 -0
  62. {pyield-0.43.1 → pyield-0.43.2}/pyield/py.typed +0 -0
  63. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/__init__.py +0 -0
  64. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/benchmark.py +0 -0
  65. {pyield-0.43.1 → pyield-0.43.2}/pyield/tn/tools.py +0 -0
  66. {pyield-0.43.1 → pyield-0.43.2}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyield
3
- Version: 0.43.1
3
+ Version: 0.43.2
4
4
  Summary: A Python library for analysis of fixed income instruments in Brazil
5
5
  Project-URL: Homepage, https://github.com/crdcj/PYield
6
6
  Project-URL: Documentation, https://crdcj.github.io/PYield
@@ -47,76 +47,80 @@ Description-Content-Type: text/markdown
47
47
  [![Made with Python](https://img.shields.io/badge/Python->=3.12-blue?logo=python&logoColor=white)](https://python.org "Go to Python homepage")
48
48
  [![License](https://img.shields.io/badge/License-MIT-blue)](https://github.com/crdcj/PYield/blob/main/LICENSE)
49
49
 
50
- # PYield: Brazilian Fixed Income Toolkit
50
+ # PYield: Toolkit de Renda Fixa Brasileira
51
51
 
52
- PYield is a Python library for analyzing Brazilian fixed income instruments. It fetches and processes data from ANBIMA, BCB, IBGE and B3, returning Polars DataFrames for fast, type-safe data pipelines.
52
+ Português | [English](https://github.com/crdcj/PYield/blob/main/README.en.md)
53
53
 
54
- ## Installation
54
+ PYield é uma biblioteca Python voltada para análise de títulos públicos brasileiros. Ela busca e processa dados da ANBIMA, BCB, IBGE, B3 e **Tesouro Nacional**, retornando DataFrames do Polars para pipelines rápidos e com tipagem consistente.
55
+
56
+ Embora inclua dados e ferramentas de outros mercados (como DI1, DAP e PTAX), esses recursos são auxiliares para o objetivo central: análise, precificação e acompanhamento de títulos públicos.
57
+
58
+ ## Instalação
55
59
 
56
60
  ```sh
57
61
  pip install pyield
58
62
  ```
59
63
 
60
- ## Quick Start
64
+ ## Início Rápido
61
65
 
62
66
  ```python
63
67
  import pyield as yd
64
68
 
65
- # Business days (foundation of all calculations)
69
+ # Dias úteis (base de todos os cálculos)
66
70
  yd.bday.count("02-01-2025", "15-01-2025") # -> 9
67
71
  yd.bday.offset("29-12-2023", 1) # -> datetime.date(2024, 1, 2)
68
72
 
69
- # DI Futures curve
73
+ # Curva de DI Futuro
70
74
  df = yd.futures("31-05-2024", "DI1")
71
75
  # Columns: TradeDate, TickerSymbol, ExpirationDate, BDaysToExp, SettlementRate, ...
72
76
 
73
- # Rate interpolation (flat forward, 252 bdays/year convention)
77
+ # Interpolação de taxas (flat forward, convenção 252 dias úteis/ano)
74
78
  interp = yd.Interpolator("flat_forward", df["BDaysToExp"], df["SettlementRate"])
75
79
  interp(45) # -> 0.04833...
76
80
  interp([30, 60]) # -> pl.Series with interpolated rates
77
81
 
78
- # Treasury bond pricing
82
+ # Precificação de títulos públicos
79
83
  yd.ntnb.quotation("31-05-2024", "15-05-2035", 0.061490) # -> 99.3651
80
84
 
81
- # BCB indicators
85
+ # Indicadores do BCB
82
86
  yd.bc.selic_over("31-05-2024") # -> 0.000414...
83
87
  ```
84
88
 
85
- A Colab notebook with more examples is available:
89
+ Um notebook no Colab com mais exemplos:
86
90
 
87
91
  [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/crdcj/PYield/blob/main/examples/pyield_quickstart.ipynb)
88
92
 
89
- ## Core Building Blocks
93
+ ## Blocos Principais
90
94
 
91
- ### Business Days (`bday`)
95
+ ### Dias Úteis (`bday`)
92
96
 
93
- The `bday` module is the foundation of PYield. All date calculations (pricing, duration, forward rates) depend on accurate business day counting with Brazilian holidays.
97
+ O módulo `bday` é a base do PYield. Todos os cálculos com datas (preço, duration, taxas a termo) dependem da contagem correta de dias úteis com feriados brasileiros.
94
98
 
95
99
  ```python
96
100
  from pyield import bday
97
101
 
98
- # Count business days (start inclusive, end exclusive)
102
+ # Conta dias úteis (início inclusivo, fim exclusivo)
99
103
  bday.count("29-12-2023", "02-01-2024") # -> 1
100
104
 
101
- # Offset by N business days
105
+ # Avança N dias úteis
102
106
  bday.offset("29-12-2023", 1) # -> datetime.date(2024, 1, 2)
103
107
 
104
- # Adjust non-business day to next business day
108
+ # Ajusta dia não útil para o próximo dia útil
105
109
  bday.offset("30-12-2023", 0) # -> datetime.date(2024, 1, 2)
106
110
 
107
- # Generate business day range
111
+ # Gera intervalo de dias úteis
108
112
  bday.generate("22-12-2023", "02-01-2024")
109
113
  # -> Series: [2023-12-22, 2023-12-26, 2023-12-27, 2023-12-28, 2023-12-29, 2024-01-02]
110
114
 
111
- # Check if date is business day
115
+ # Verifica se a data é dia útil
112
116
  bday.is_business_day("25-12-2023") # -> False (Christmas)
113
117
  ```
114
118
 
115
- All functions support vectorized operations with lists, Series, or arrays.
119
+ Todas as funções suportam operações vetorizadas com listas, Series ou arrays.
116
120
 
117
- ### Rate Interpolation (`Interpolator`)
121
+ ### Interpolação de Taxas (`Interpolator`)
118
122
 
119
- The `Interpolator` class interpolates interest rates using the 252 business days/year convention standard in Brazil.
123
+ A classe `Interpolator` interpola taxas usando a convenção de 252 dias úteis/ano, padrão no mercado brasileiro.
120
124
 
121
125
  ```python
122
126
  from pyield import Interpolator
@@ -124,95 +128,100 @@ from pyield import Interpolator
124
128
  known_bdays = [30, 60, 90]
125
129
  known_rates = [0.045, 0.05, 0.055]
126
130
 
127
- # Flat forward interpolation (market standard)
131
+ # Interpolação flat forward (padrão de mercado)
128
132
  interp = Interpolator("flat_forward", known_bdays, known_rates)
129
133
  interp(45) # -> 0.04833...
130
134
 
131
- # Linear interpolation
135
+ # Interpolação linear
132
136
  linear = Interpolator("linear", known_bdays, known_rates)
133
137
  linear(45) # -> 0.0475
134
138
 
135
- # Vectorized
139
+ # Vetorizado
136
140
  interp([15, 45, 75]) # -> pl.Series with 3 rates
137
141
 
138
- # Extrapolation (disabled by default, returns NaN)
142
+ # Extrapolação (desabilitada por padrão, retorna NaN)
139
143
  interp(100) # -> nan
140
144
  Interpolator("flat_forward", known_bdays, known_rates, extrapolate=True)(100) # -> 0.055
141
145
  ```
142
146
 
143
- ### Forward Rates (`forward`, `forwards`)
147
+ ### Taxas a Termo (`forward`, `forwards`)
144
148
 
145
- Calculate forward rates from spot curves:
149
+ Calcula taxas a termo a partir de curvas spot:
146
150
 
147
151
  ```python
148
152
  from pyield import forward, forwards
149
153
 
150
- # Single forward rate between two points
154
+ # Taxa a termo única entre dois pontos
151
155
  forward(bday1=10, bday2=20, rate1=0.05, rate2=0.06) # -> 0.0700952...
152
156
 
153
- # Vectorized forward curve from spot rates
157
+ # Curva a termo vetorizada a partir de taxas spot
154
158
  bdays = [10, 20, 30]
155
159
  rates = [0.05, 0.06, 0.07]
156
160
  forwards(bdays, rates) # -> Series: [0.05, 0.070095, 0.090284]
157
161
  ```
158
162
 
159
- ## Modules Overview
163
+ ## Visão Geral dos Módulos
160
164
 
161
- | Module | Purpose |
165
+ | Módulo | Finalidade |
162
166
  |--------|---------|
163
- | `bday` | Business day calendar with Brazilian holidays |
164
- | `futures` | B3 futures data (DI1, DDI, FRC, DAP, DOL, WDO, IND, WIN) |
165
- | `Interpolator` | Rate interpolation (flat_forward, linear) |
166
- | `forward` / `forwards` | Forward rate calculation |
167
- | `ltn`, `ntnb`, `ntnf`, `lft`, `ntnc` | Treasury bond pricing and analytics |
168
- | `anbima` | ANBIMA data (TPF prices, yield curves, IMA indices) |
169
- | `bc` | BCB indicators (SELIC, PTAX, repo rates, VNA) |
170
- | `ipca` | Inflation data (historical and projections) |
171
- | `today` / `now` | Current date/time in Brazil (America/Sao_Paulo) |
172
-
173
- ## Treasury Bonds
167
+ | `bday` | Calendário de dias úteis com feriados brasileiros |
168
+ | `futures` | Dados de futuros da B3 (DI1, DDI, FRC, DAP, DOL, WDO, IND, WIN) |
169
+ | `Interpolator` | Interpolação de taxas (flat_forward, linear) |
170
+ | `forward` / `forwards` | Cálculo de taxas a termo |
171
+ | `ltn`, `ntnb`, `ntnf`, `lft`, `ntnc` | Precificação e análise de títulos públicos |
172
+ | `anbima` | Dados da ANBIMA (preços de TPF, curvas de juros, índices IMA) |
173
+ | `bc` | Indicadores do BCB (SELIC, PTAX, repos, VNA) |
174
+ | `ipca` | Dados de inflação (histórico e projeções) |
175
+ | `today` / `now` | Data/hora atual no Brasil (America/Sao_Paulo) |
176
+
177
+ ## Títulos Públicos
174
178
 
175
179
  ```python
176
180
  from pyield import ltn, ntnb, ntnf
177
181
 
178
- # Fetch ANBIMA indicative rates
182
+ # Busca taxas indicativas da ANBIMA
179
183
  ltn.data("23-08-2024") # -> DataFrame with LTN bonds
180
184
  ntnb.data("23-08-2024") # -> DataFrame with NTN-B bonds
181
185
 
182
- # Calculate bond quotation (base 100)
186
+ # Calcula cotação do título (base 100)
183
187
  ntnb.quotation("31-05-2024", "15-05-2035", 0.061490) # -> 99.3651
184
188
  ntnb.quotation("31-05-2024", "15-08-2060", 0.061878) # -> 99.5341
185
189
 
186
- # DI spreads (bps=True multiplies by 10,000)
190
+ # Spreads de DI (bps=True multiplica por 10.000)
187
191
  ntnf.di_spreads("30-05-2025", bps=True)
188
192
  # -> DataFrame: BondType, MaturityDate, DISpread
189
193
  ```
190
194
 
191
- ## Futures Data
195
+ ## Dados de Futuros
192
196
 
193
197
  ```python
194
198
  from pyield import futures
195
199
 
196
- # DI1 (Interbank Deposit Futures)
200
+ # DI1 (Futuro de Depósito Interfinanceiro)
197
201
  futures("31-05-2024", "DI1")
198
202
 
199
- # Other contracts: DDI, FRC, DAP, DOL, WDO, IND, WIN
203
+ # Outros contratos: DDI, FRC, DAP, DOL, WDO, IND, WIN
200
204
  futures("31-05-2024", "DAP")
201
205
 
202
- # Intraday data (when market is open)
203
- futures("16-01-2025", "DI1") # Returns live data if called during trading hours
206
+ # Dados intradiários (quando o mercado estiver aberto)
207
+ futures("16-01-2025", "DI1") # Retorna dados ao vivo durante o horário de negociação
204
208
  ```
205
209
 
206
- ## Date Handling
210
+ ## Tratamento de Datas
207
211
 
208
- PYield accepts flexible date inputs (`DateLike`):
212
+ PYield aceita entradas de data flexíveis (`DateLike`):
209
213
  - Strings: `"31-05-2024"`, `"31/05/2024"`, `"2024-05-31"`
210
214
  - `datetime.date`, `datetime.datetime`
211
215
  - `pandas.Timestamp`, `numpy.datetime64`
212
216
 
213
- Scalar functions return `datetime.date`. Vectorized functions return `polars.Series`.
217
+ Funções escalares retornam `datetime.date`. Funções vetorizadas retornam `polars.Series`.
218
+
219
+ O parsing de strings é elemento a elemento entre os formatos aceitos. Strings
220
+ inválidas são convertidas para valores nulos (`None` em saídas escalares e `null`
221
+ em saídas vetorizadas).
214
222
 
215
- Null handling: scalar functions return `float('nan')` for missing inputs (propagates through calculations). Vectorized functions propagate `null` element-wise.
223
+ Tratamento de nulos: funções escalares retornam `float('nan')` para entradas ausentes
224
+ (propaga nos cálculos). Funções vetorizadas propagam `null` elemento a elemento.
216
225
 
217
226
  ```python
218
227
  from pyield import ntnb, bday
@@ -221,19 +230,19 @@ ntnb.quotation(None, "15-05-2035", 0.06149) # -> nan
221
230
  bday.count(["01-01-2024", None], "01-02-2024") # -> Series: [22, null]
222
231
  ```
223
232
 
224
- ## Polars Migration (v0.40.0+)
233
+ ## Migração para Polars (v0.40.0+)
225
234
 
226
- All functions return **Polars DataFrames/Series**. To convert to Pandas:
235
+ Todas as funções retornam **DataFrames/Series do Polars**. Para converter para Pandas:
227
236
 
228
237
  ```python
229
238
  df_pandas = df.to_pandas(use_pyarrow_extension_array=True)
230
239
  ```
231
240
 
232
- ## Documentation
241
+ ## Documentação
233
242
 
234
- Full documentation: [crdcj.github.io/PYield](https://crdcj.github.io/PYield/)
243
+ Documentação completa: [crdcj.github.io/PYield](https://crdcj.github.io/PYield/)
235
244
 
236
- ## Tests
245
+ ## Testes
237
246
 
238
247
  ```sh
239
248
  pytest pyield --doctest-modules
@@ -0,0 +1,204 @@
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.12-blue?logo=python&logoColor=white)](https://python.org "Go to Python homepage")
3
+ [![License](https://img.shields.io/badge/License-MIT-blue)](https://github.com/crdcj/PYield/blob/main/LICENSE)
4
+
5
+ # PYield: Toolkit de Renda Fixa Brasileira
6
+
7
+ Português | [English](https://github.com/crdcj/PYield/blob/main/README.en.md)
8
+
9
+ PYield é uma biblioteca Python voltada para análise de títulos públicos brasileiros. Ela busca e processa dados da ANBIMA, BCB, IBGE, B3 e **Tesouro Nacional**, retornando DataFrames do Polars para pipelines rápidos e com tipagem consistente.
10
+
11
+ Embora inclua dados e ferramentas de outros mercados (como DI1, DAP e PTAX), esses recursos são auxiliares para o objetivo central: análise, precificação e acompanhamento de títulos públicos.
12
+
13
+ ## Instalação
14
+
15
+ ```sh
16
+ pip install pyield
17
+ ```
18
+
19
+ ## Início Rápido
20
+
21
+ ```python
22
+ import pyield as yd
23
+
24
+ # Dias úteis (base de todos os cálculos)
25
+ yd.bday.count("02-01-2025", "15-01-2025") # -> 9
26
+ yd.bday.offset("29-12-2023", 1) # -> datetime.date(2024, 1, 2)
27
+
28
+ # Curva de DI Futuro
29
+ df = yd.futures("31-05-2024", "DI1")
30
+ # Columns: TradeDate, TickerSymbol, ExpirationDate, BDaysToExp, SettlementRate, ...
31
+
32
+ # Interpolação de taxas (flat forward, convenção 252 dias úteis/ano)
33
+ interp = yd.Interpolator("flat_forward", df["BDaysToExp"], df["SettlementRate"])
34
+ interp(45) # -> 0.04833...
35
+ interp([30, 60]) # -> pl.Series with interpolated rates
36
+
37
+ # Precificação de títulos públicos
38
+ yd.ntnb.quotation("31-05-2024", "15-05-2035", 0.061490) # -> 99.3651
39
+
40
+ # Indicadores do BCB
41
+ yd.bc.selic_over("31-05-2024") # -> 0.000414...
42
+ ```
43
+
44
+ Um notebook no Colab com mais exemplos:
45
+
46
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/crdcj/PYield/blob/main/examples/pyield_quickstart.ipynb)
47
+
48
+ ## Blocos Principais
49
+
50
+ ### Dias Úteis (`bday`)
51
+
52
+ O módulo `bday` é a base do PYield. Todos os cálculos com datas (preço, duration, taxas a termo) dependem da contagem correta de dias úteis com feriados brasileiros.
53
+
54
+ ```python
55
+ from pyield import bday
56
+
57
+ # Conta dias úteis (início inclusivo, fim exclusivo)
58
+ bday.count("29-12-2023", "02-01-2024") # -> 1
59
+
60
+ # Avança N dias úteis
61
+ bday.offset("29-12-2023", 1) # -> datetime.date(2024, 1, 2)
62
+
63
+ # Ajusta dia não útil para o próximo dia útil
64
+ bday.offset("30-12-2023", 0) # -> datetime.date(2024, 1, 2)
65
+
66
+ # Gera intervalo de dias úteis
67
+ bday.generate("22-12-2023", "02-01-2024")
68
+ # -> Series: [2023-12-22, 2023-12-26, 2023-12-27, 2023-12-28, 2023-12-29, 2024-01-02]
69
+
70
+ # Verifica se a data é dia útil
71
+ bday.is_business_day("25-12-2023") # -> False (Christmas)
72
+ ```
73
+
74
+ Todas as funções suportam operações vetorizadas com listas, Series ou arrays.
75
+
76
+ ### Interpolação de Taxas (`Interpolator`)
77
+
78
+ A classe `Interpolator` interpola taxas usando a convenção de 252 dias úteis/ano, padrão no mercado brasileiro.
79
+
80
+ ```python
81
+ from pyield import Interpolator
82
+
83
+ known_bdays = [30, 60, 90]
84
+ known_rates = [0.045, 0.05, 0.055]
85
+
86
+ # Interpolação flat forward (padrão de mercado)
87
+ interp = Interpolator("flat_forward", known_bdays, known_rates)
88
+ interp(45) # -> 0.04833...
89
+
90
+ # Interpolação linear
91
+ linear = Interpolator("linear", known_bdays, known_rates)
92
+ linear(45) # -> 0.0475
93
+
94
+ # Vetorizado
95
+ interp([15, 45, 75]) # -> pl.Series with 3 rates
96
+
97
+ # Extrapolação (desabilitada por padrão, retorna NaN)
98
+ interp(100) # -> nan
99
+ Interpolator("flat_forward", known_bdays, known_rates, extrapolate=True)(100) # -> 0.055
100
+ ```
101
+
102
+ ### Taxas a Termo (`forward`, `forwards`)
103
+
104
+ Calcula taxas a termo a partir de curvas spot:
105
+
106
+ ```python
107
+ from pyield import forward, forwards
108
+
109
+ # Taxa a termo única entre dois pontos
110
+ forward(bday1=10, bday2=20, rate1=0.05, rate2=0.06) # -> 0.0700952...
111
+
112
+ # Curva a termo vetorizada a partir de taxas spot
113
+ bdays = [10, 20, 30]
114
+ rates = [0.05, 0.06, 0.07]
115
+ forwards(bdays, rates) # -> Series: [0.05, 0.070095, 0.090284]
116
+ ```
117
+
118
+ ## Visão Geral dos Módulos
119
+
120
+ | Módulo | Finalidade |
121
+ |--------|---------|
122
+ | `bday` | Calendário de dias úteis com feriados brasileiros |
123
+ | `futures` | Dados de futuros da B3 (DI1, DDI, FRC, DAP, DOL, WDO, IND, WIN) |
124
+ | `Interpolator` | Interpolação de taxas (flat_forward, linear) |
125
+ | `forward` / `forwards` | Cálculo de taxas a termo |
126
+ | `ltn`, `ntnb`, `ntnf`, `lft`, `ntnc` | Precificação e análise de títulos públicos |
127
+ | `anbima` | Dados da ANBIMA (preços de TPF, curvas de juros, índices IMA) |
128
+ | `bc` | Indicadores do BCB (SELIC, PTAX, repos, VNA) |
129
+ | `ipca` | Dados de inflação (histórico e projeções) |
130
+ | `today` / `now` | Data/hora atual no Brasil (America/Sao_Paulo) |
131
+
132
+ ## Títulos Públicos
133
+
134
+ ```python
135
+ from pyield import ltn, ntnb, ntnf
136
+
137
+ # Busca taxas indicativas da ANBIMA
138
+ ltn.data("23-08-2024") # -> DataFrame with LTN bonds
139
+ ntnb.data("23-08-2024") # -> DataFrame with NTN-B bonds
140
+
141
+ # Calcula cotação do título (base 100)
142
+ ntnb.quotation("31-05-2024", "15-05-2035", 0.061490) # -> 99.3651
143
+ ntnb.quotation("31-05-2024", "15-08-2060", 0.061878) # -> 99.5341
144
+
145
+ # Spreads de DI (bps=True multiplica por 10.000)
146
+ ntnf.di_spreads("30-05-2025", bps=True)
147
+ # -> DataFrame: BondType, MaturityDate, DISpread
148
+ ```
149
+
150
+ ## Dados de Futuros
151
+
152
+ ```python
153
+ from pyield import futures
154
+
155
+ # DI1 (Futuro de Depósito Interfinanceiro)
156
+ futures("31-05-2024", "DI1")
157
+
158
+ # Outros contratos: DDI, FRC, DAP, DOL, WDO, IND, WIN
159
+ futures("31-05-2024", "DAP")
160
+
161
+ # Dados intradiários (quando o mercado estiver aberto)
162
+ futures("16-01-2025", "DI1") # Retorna dados ao vivo durante o horário de negociação
163
+ ```
164
+
165
+ ## Tratamento de Datas
166
+
167
+ PYield aceita entradas de data flexíveis (`DateLike`):
168
+ - Strings: `"31-05-2024"`, `"31/05/2024"`, `"2024-05-31"`
169
+ - `datetime.date`, `datetime.datetime`
170
+ - `pandas.Timestamp`, `numpy.datetime64`
171
+
172
+ Funções escalares retornam `datetime.date`. Funções vetorizadas retornam `polars.Series`.
173
+
174
+ O parsing de strings é elemento a elemento entre os formatos aceitos. Strings
175
+ inválidas são convertidas para valores nulos (`None` em saídas escalares e `null`
176
+ em saídas vetorizadas).
177
+
178
+ Tratamento de nulos: funções escalares retornam `float('nan')` para entradas ausentes
179
+ (propaga nos cálculos). Funções vetorizadas propagam `null` elemento a elemento.
180
+
181
+ ```python
182
+ from pyield import ntnb, bday
183
+
184
+ ntnb.quotation(None, "15-05-2035", 0.06149) # -> nan
185
+ bday.count(["01-01-2024", None], "01-02-2024") # -> Series: [22, null]
186
+ ```
187
+
188
+ ## Migração para Polars (v0.40.0+)
189
+
190
+ Todas as funções retornam **DataFrames/Series do Polars**. Para converter para Pandas:
191
+
192
+ ```python
193
+ df_pandas = df.to_pandas(use_pyarrow_extension_array=True)
194
+ ```
195
+
196
+ ## Documentação
197
+
198
+ Documentação completa: [crdcj.github.io/PYield](https://crdcj.github.io/PYield/)
199
+
200
+ ## Testes
201
+
202
+ ```sh
203
+ pytest pyield --doctest-modules
204
+ ```
@@ -0,0 +1 @@
1
+ __version__ = "0.43.2"
@@ -0,0 +1,5 @@
1
+ """Namespace interno para utilitários compartilhados do pacote.
2
+
3
+ Este módulo não faz parte da API pública estável do PYield.
4
+ """
5
+
@@ -3,56 +3,54 @@ from typing import overload
3
3
 
4
4
  import polars as pl
5
5
 
6
- from pyield import types
7
- from pyield.types import ArrayLike, DateLike
6
+ from pyield._internal import types
7
+ from pyield._internal.types import ArrayLike, DateLike
8
8
 
9
9
 
10
- def _validar_formato_data(date_str: str) -> str:
11
- """Valida se a string de data está em formatos suportados e retorna o *formato*.
10
+ def converter_datas_expr(expr: pl.Expr | str) -> pl.Expr:
11
+ """Converte expressão Polars para ``Date`` com parse tolerante por linha.
12
12
 
13
- Formatos aceitos:
14
- - Brasileiro: ``dd-mm-YYYY`` ou ``dd/mm/YYYY`` (day-first explícito)
15
- - ISO: ``YYYY-mm-dd``
16
-
17
- Regras / Observações:
18
- - Não fazemos autodetecção ambígua: ``2024-05-06`` só é válido como ISO.
19
- - Uma coleção (coluna) não deve misturar estilos.
20
- - Retorna o padrão para uso explícito em ``pl.Series.str.to_date(..., format=fmt)``.
13
+ Esta função é voltada para pipelines em ``DataFrame``/``LazyFrame``.
14
+ O parse aceita os formatos ``dd-mm-YYYY``, ``dd/mm/YYYY`` e ``YYYY-mm-dd``.
15
+ Valores inválidos (incluindo string vazia) viram ``null``.
21
16
 
22
17
  Args:
23
- date_str: String de data a ser validada.
18
+ expr: Expressão Polars ou nome da coluna com datas.
24
19
 
25
20
  Returns:
26
- O padrão ``strftime`` correspondente ao formato detectado.
27
-
28
- Raises:
29
- ValueError: Se não corresponder a nenhum dos formatos suportados.
21
+ Uma ``pl.Expr`` com dtype ``Date``.
30
22
 
31
23
  Examples:
32
- >>> _validar_formato_data("25-12-2024")
33
- '%d-%m-%Y'
34
- >>> _validar_formato_data("25/12/2024")
35
- '%d/%m/%Y'
36
- >>> _validar_formato_data("2024-12-25")
37
- '%Y-%m-%d'
38
- >>> _validar_formato_data("12.25.2024")
39
- Traceback (most recent call last):
40
- ...
41
- ValueError: Formato de data inválido: '12.25.2024'. Formatos aceitos: dd-mm-YYYY, dd/mm/YYYY ou YYYY-mm-dd.
42
- >>> _validar_formato_data("not-a-date")
43
- Traceback (most recent call last):
44
- ...
45
- ValueError: Formato de data inválido: 'not-a-date'. Formatos aceitos: dd-mm-YYYY, dd/mm/YYYY ou YYYY-mm-dd.
46
- """ # noqa:E501
47
- for fmt in ("%d-%m-%Y", "%d/%m/%Y", "%Y-%m-%d"):
48
- try:
49
- dt.datetime.strptime(date_str, fmt)
50
- return fmt
51
- except ValueError:
52
- pass
53
- raise ValueError(
54
- f"Formato de data inválido: '{date_str}'."
55
- " Formatos aceitos: dd-mm-YYYY, dd/mm/YYYY ou YYYY-mm-dd."
24
+ >>> import polars as pl
25
+ >>> df = pl.DataFrame(
26
+ ... {"d": ["02-01-2024", "03/01/2024", "2024-01-04", "31-02-2024", ""]}
27
+ ... )
28
+ >>> df.select(converter_datas_expr("d"))
29
+ shape: (5, 1)
30
+ ┌────────────┐
31
+ │ d │
32
+ │ --- │
33
+ │ date │
34
+ ╞════════════╡
35
+ │ 2024-01-02 │
36
+ │ 2024-01-03 │
37
+ │ 2024-01-04 │
38
+ │ null │
39
+ │ null │
40
+ └────────────┘
41
+ """
42
+ if isinstance(expr, str):
43
+ expr = pl.col(expr)
44
+
45
+ # Fallback por linha: o primeiro valor não-nulo vence.
46
+ # Se o elemento já for Date, o cast resolve no 1o termo.
47
+ # Se o elemento for null, ele permanece null em todos os termos.
48
+ expr_str = expr.cast(pl.String, strict=False).str.strip_chars()
49
+ return pl.coalesce(
50
+ expr.cast(pl.Date, strict=False),
51
+ expr_str.str.to_date(format="%d-%m-%Y", strict=False),
52
+ expr_str.str.to_date(format="%d/%m/%Y", strict=False),
53
+ expr_str.str.to_date(format="%Y-%m-%d", strict=False),
56
54
  )
57
55
 
58
56
 
@@ -74,8 +72,8 @@ def converter_datas(
74
72
  - Coleções (list, tuple, ndarray, Series) retornam ``pl.Series`` com dtype ``Date``
75
73
  - Entradas nulas retornam ``None``
76
74
 
77
- O formato da string é detectado automaticamente pelo primeiro valor não-nulo
78
- da coleção usando ``_validar_formato_data()``.
75
+ O parse de strings é feito por elemento com fallback entre formatos
76
+ suportados. Valores inválidos viram ``null``.
79
77
 
80
78
  Args:
81
79
  dates: Data(s) a converter. Aceita:
@@ -109,7 +107,7 @@ def converter_datas(
109
107
  Conversão de lista de strings:
110
108
  >>> converter_datas(["01-01-2024", "15-06-2024"])
111
109
  shape: (2,)
112
- Series: '' [date]
110
+ Series: 'dates' [date]
113
111
  [
114
112
  2024-01-01
115
113
  2024-06-15
@@ -126,7 +124,7 @@ def converter_datas(
126
124
  Lista com valores nulos propaga os nulls:
127
125
  >>> converter_datas(["01-01-2024", None])
128
126
  shape: (2,)
129
- Series: '' [date]
127
+ Series: 'dates' [date]
130
128
  [
131
129
  2024-01-01
132
130
  null
@@ -135,19 +133,19 @@ def converter_datas(
135
133
  Lista com strings vazias vira série nula:
136
134
  >>> converter_datas(["", " "])
137
135
  shape: (2,)
138
- Series: '' [date]
136
+ Series: 'dates' [date]
139
137
  [
140
138
  null
141
139
  null
142
140
  ]
143
141
 
144
- Formatos mistos: formato do primeiro valor válido prevalece:
142
+ Formatos mistos por linha:
145
143
  >>> converter_datas(["25-12-2024", "2024-12-26"])
146
144
  shape: (2,)
147
- Series: '' [date]
145
+ Series: 'dates' [date]
148
146
  [
149
147
  2024-12-25
150
- null
148
+ 2024-12-26
151
149
  ]
152
150
  """
153
151
  if not types.is_collection(dates):
@@ -157,18 +155,11 @@ def converter_datas(
157
155
  eh_escalar = False
158
156
  serie = pl.Series(values=dates)
159
157
 
160
- if serie.dtype == pl.String:
161
- # Usa primeiro valor não-nulo para determinar o formato.
162
- valores_validos = serie.str.strip_chars().replace("", None).drop_nulls()
163
- if valores_validos.len() > 0:
164
- formato = _validar_formato_data(valores_validos.item(0))
165
- serie = serie.str.to_date(format=formato, strict=False)
166
- else:
167
- serie = pl.Series(values=[None] * serie.len(), dtype=pl.Date)
168
- else:
169
- # Para todos os outros dtypes (datetime, date, etc.),
170
- # o cast nativo do Polars é suficiente e muito rápido.
171
- serie = serie.cast(pl.Date)
158
+ serie = (
159
+ pl.DataFrame({"dates": serie}, nan_to_null=True)
160
+ .select(converter_datas_expr("dates"))
161
+ .get_column("dates")
162
+ )
172
163
 
173
164
  if eh_escalar:
174
165
  return serie.item()
@@ -8,7 +8,7 @@ import polars as pl
8
8
  import requests
9
9
 
10
10
  from pyield.clock import now
11
- from pyield.retry import retry_padrao
11
+ from pyield._internal.retry import retry_padrao
12
12
 
13
13
  URL_BASE = "https://github.com/crdcj/pyield-data/releases/latest/download"
14
14
  registro = logging.getLogger(__name__)