PYield 0.46.1__tar.gz → 0.46.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 (71) hide show
  1. {pyield-0.46.1 → pyield-0.46.2}/PKG-INFO +12 -1
  2. {pyield-0.46.1 → pyield-0.46.2}/README.md +11 -0
  3. pyield-0.46.2/pyield/__about__.py +1 -0
  4. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/_validar_pregao.py +4 -12
  5. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/ptax_api.py +26 -24
  6. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/trades_monthly.py +3 -0
  7. {pyield-0.46.1 → pyield-0.46.2}/pyield/fwd.py +1 -1
  8. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/lft.py +34 -36
  9. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/ltn.py +94 -94
  10. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/ntnb.py +209 -205
  11. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/ntnb1.py +30 -30
  12. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/ntnc.py +71 -67
  13. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/ntnf.py +188 -181
  14. pyield-0.46.2/pyield/tn/pre.py +203 -0
  15. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/utils.py +52 -13
  16. pyield-0.46.1/pyield/__about__.py +0 -1
  17. pyield-0.46.1/pyield/tn/pre.py +0 -198
  18. {pyield-0.46.1 → pyield-0.46.2}/.gitignore +0 -0
  19. {pyield-0.46.1 → pyield-0.46.2}/LICENSE +0 -0
  20. {pyield-0.46.1 → pyield-0.46.2}/pyield/__init__.py +0 -0
  21. {pyield-0.46.1 → pyield-0.46.2}/pyield/_internal/__init__.py +0 -0
  22. {pyield-0.46.1 → pyield-0.46.2}/pyield/_internal/br_numbers.py +0 -0
  23. {pyield-0.46.1 → pyield-0.46.2}/pyield/_internal/cache.py +0 -0
  24. {pyield-0.46.1 → pyield-0.46.2}/pyield/_internal/converters.py +0 -0
  25. {pyield-0.46.1 → pyield-0.46.2}/pyield/_internal/data_cache.py +0 -0
  26. {pyield-0.46.1 → pyield-0.46.2}/pyield/_internal/retry.py +0 -0
  27. {pyield-0.46.1 → pyield-0.46.2}/pyield/_internal/types.py +0 -0
  28. {pyield-0.46.1 → pyield-0.46.2}/pyield/anbima/__init__.py +0 -0
  29. {pyield-0.46.1 → pyield-0.46.2}/pyield/anbima/difusao.py +0 -0
  30. {pyield-0.46.1 → pyield-0.46.2}/pyield/anbima/ettj_intraday.py +0 -0
  31. {pyield-0.46.1 → pyield-0.46.2}/pyield/anbima/ettj_last.py +0 -0
  32. {pyield-0.46.1 → pyield-0.46.2}/pyield/anbima/ima.py +0 -0
  33. {pyield-0.46.1 → pyield-0.46.2}/pyield/anbima/imaq.py +0 -0
  34. {pyield-0.46.1 → pyield-0.46.2}/pyield/anbima/tpf.py +0 -0
  35. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/__init__.py +0 -0
  36. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/_contracts.py +0 -0
  37. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/di1.py +0 -0
  38. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/di_over.py +0 -0
  39. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/futures/__init__.py +0 -0
  40. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/futures/common.py +0 -0
  41. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/futures/historical.py +0 -0
  42. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/futures/intraday.py +0 -0
  43. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/intraday_derivatives.py +0 -0
  44. {pyield-0.46.1 → pyield-0.46.2}/pyield/b3/price_report.py +0 -0
  45. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/__init__.py +0 -0
  46. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/auction.py +0 -0
  47. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/copom.py +0 -0
  48. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/rates.py +0 -0
  49. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/repo.py +0 -0
  50. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/trades_intraday.py +0 -0
  51. {pyield-0.46.1 → pyield-0.46.2}/pyield/bc/vna.py +0 -0
  52. {pyield-0.46.1 → pyield-0.46.2}/pyield/bday/__init__.py +0 -0
  53. {pyield-0.46.1 → pyield-0.46.2}/pyield/bday/core.py +0 -0
  54. {pyield-0.46.1 → pyield-0.46.2}/pyield/bday/holidays/br_holidays_new.txt +0 -0
  55. {pyield-0.46.1 → pyield-0.46.2}/pyield/bday/holidays/br_holidays_old.txt +0 -0
  56. {pyield-0.46.1 → pyield-0.46.2}/pyield/bday/holidays/brholidays.py +0 -0
  57. {pyield-0.46.1 → pyield-0.46.2}/pyield/clock.py +0 -0
  58. {pyield-0.46.1 → pyield-0.46.2}/pyield/interpolator.py +0 -0
  59. {pyield-0.46.1 → pyield-0.46.2}/pyield/ipca/__init__.py +0 -0
  60. {pyield-0.46.1 → pyield-0.46.2}/pyield/ipca/historical.py +0 -0
  61. {pyield-0.46.1 → pyield-0.46.2}/pyield/ipca/projected.py +0 -0
  62. {pyield-0.46.1 → pyield-0.46.2}/pyield/py.typed +0 -0
  63. {pyield-0.46.1 → pyield-0.46.2}/pyield/rmd.py +0 -0
  64. {pyield-0.46.1 → pyield-0.46.2}/pyield/selic/__init__.py +0 -0
  65. {pyield-0.46.1 → pyield-0.46.2}/pyield/selic/cpm.py +0 -0
  66. {pyield-0.46.1 → pyield-0.46.2}/pyield/selic/probabilities.py +0 -0
  67. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/__init__.py +0 -0
  68. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/auctions.py +0 -0
  69. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/benchmark.py +0 -0
  70. {pyield-0.46.1 → pyield-0.46.2}/pyield/tn/ntnbprinc.py +0 -0
  71. {pyield-0.46.1 → pyield-0.46.2}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyield
3
- Version: 0.46.1
3
+ Version: 0.46.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
@@ -247,6 +247,17 @@ ntnb.quotation(None, "15-05-2035", 0.06149) # -> nan
247
247
  bday.count(["01-01-2024", None], "01-02-2024") # -> Series: [22, null]
248
248
  ```
249
249
 
250
+ Consultas sem dados disponíveis (data futura, feriado, fim de semana ou
251
+ fonte indisponível) retornam DataFrame vazio ou `nan`, sem lançar exceção:
252
+
253
+ ```python
254
+ from pyield import bc, futures
255
+
256
+ futures("01-01-2030", "DI1").is_empty() # -> True (data futura)
257
+ bc.tpf_monthly_trades("01-01-2030").is_empty() # -> True (mês futuro)
258
+ bc.ptax("25-12-2025") # -> nan (feriado)
259
+ ```
260
+
250
261
  ## Migração para Polars (v0.40.0+)
251
262
 
252
263
  A partir da versão 0.40.0, todas as saídas tabulares passaram de Pandas para **Polars**. Entradas vetoriais que antes aceitavam `pd.Series` e `np.ndarray` agora aceitam apenas listas, tuplas ou `pl.Series`. Para converter:
@@ -203,6 +203,17 @@ ntnb.quotation(None, "15-05-2035", 0.06149) # -> nan
203
203
  bday.count(["01-01-2024", None], "01-02-2024") # -> Series: [22, null]
204
204
  ```
205
205
 
206
+ Consultas sem dados disponíveis (data futura, feriado, fim de semana ou
207
+ fonte indisponível) retornam DataFrame vazio ou `nan`, sem lançar exceção:
208
+
209
+ ```python
210
+ from pyield import bc, futures
211
+
212
+ futures("01-01-2030", "DI1").is_empty() # -> True (data futura)
213
+ bc.tpf_monthly_trades("01-01-2030").is_empty() # -> True (mês futuro)
214
+ bc.ptax("25-12-2025") # -> nan (feriado)
215
+ ```
216
+
206
217
  ## Migração para Polars (v0.40.0+)
207
218
 
208
219
  A partir da versão 0.40.0, todas as saídas tabulares passaram de Pandas para **Polars**. Entradas vetoriais que antes aceitavam `pd.Series` e `np.ndarray` agora aceitam apenas listas, tuplas ou `pl.Series`. Para converter:
@@ -0,0 +1 @@
1
+ __version__ = "0.46.2"
@@ -1,10 +1,7 @@
1
1
  import datetime as dt
2
- import logging
3
2
 
4
3
  from pyield import bday, clock
5
4
 
6
- registro = logging.getLogger(__name__)
7
-
8
5
 
9
6
  def data_negociacao_valida(data_negociacao: dt.date) -> bool:
10
7
  """Valida se a data de referência é utilizável para consulta.
@@ -13,24 +10,19 @@ def data_negociacao_valida(data_negociacao: dt.date) -> bool:
13
10
  - Deve ser um dia útil brasileiro.
14
11
  - Não pode estar no futuro (maior que a data corrente no Brasil).
15
12
 
16
- Retorna True se válida, False caso contrário (e loga um aviso).
13
+ Retorna True se válida, False caso contrário.
17
14
  """
18
15
  if data_negociacao > clock.today():
19
- registro.warning(f"A data informada {data_negociacao} está no futuro.")
20
16
  return False
21
17
  if not bday.is_business_day(data_negociacao):
22
- registro.warning(f"A data informada {data_negociacao} não é dia útil.")
23
18
  return False
24
19
 
25
20
  # Não tem pregão na véspera de Natal e Ano Novo
26
- datas_fechadas_especiais = { # Datas especiais
27
- dt.date(data_negociacao.year, 12, 24), # Véspera de Natal
28
- dt.date(data_negociacao.year, 12, 31), # Véspera de Ano Novo
21
+ datas_fechadas_especiais = {
22
+ dt.date(data_negociacao.year, 12, 24),
23
+ dt.date(data_negociacao.year, 12, 31),
29
24
  }
30
25
  if data_negociacao in datas_fechadas_especiais:
31
- registro.warning(
32
- f"Não há pregão na véspera de Natal e de Ano Novo: {data_negociacao}"
33
- )
34
26
  return False
35
27
 
36
28
  return True
@@ -69,13 +69,15 @@ def _processar_df(df: pl.DataFrame) -> pl.DataFrame:
69
69
  )
70
70
  .with_columns(
71
71
  data=pl.col("data_hora").cast(pl.Date),
72
+ hora=pl.col("data_hora").dt.time(),
72
73
  cotacao_media=pl.mean_horizontal("cotacao_compra", "cotacao_venda").round(
73
74
  5
74
75
  ),
75
76
  )
76
- .unique(subset=["data"], keep="last")
77
- .select("data", "data_hora", "cotacao_compra", "cotacao_venda", "cotacao_media")
78
77
  .sort("data_hora")
78
+ .unique(subset=["data"], keep="last")
79
+ .select("data", "hora", "cotacao_compra", "cotacao_venda", "cotacao_media")
80
+ .sort("data")
79
81
  )
80
82
 
81
83
 
@@ -100,7 +102,7 @@ def ptax_series(
100
102
 
101
103
  Output Columns:
102
104
  * data (Date): data da cotação.
103
- * data_hora (Datetime): data e hora da cotação.
105
+ * hora (Time): hora da cotação.
104
106
  * cotacao_compra (Float64): taxa de compra em R$.
105
107
  * cotacao_venda (Float64): taxa de venda em R$.
106
108
  * cotacao_media (Float64): média de compra/venda (5 casas).
@@ -122,30 +124,30 @@ def ptax_series(
122
124
  >>> from pyield import bc
123
125
  >>> bc.ptax_series(start="20-04-2025", end="25-04-2025")
124
126
  shape: (4, 5)
125
- ┌────────────┬─────────────────────────┬────────────────┬───────────────┬───────────────┐
126
- │ data ┆ data_hora ┆ cotacao_compra ┆ cotacao_venda ┆ cotacao_media │
127
- │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
128
- │ date ┆ datetime[μs] ┆ f64 ┆ f64 ┆ f64 │
129
- ╞════════════╪═════════════════════════╪════════════════╪═══════════════╪═══════════════╡
130
- │ 2025-04-22 ┆ 2025-04-22 13:09:35.629 ┆ 5.749 ┆ 5.7496 ┆ 5.7493 │
131
- │ 2025-04-23 ┆ 2025-04-23 13:06:30.443 ┆ 5.6874 ┆ 5.688 ┆ 5.6877 │
132
- │ 2025-04-24 ┆ 2025-04-24 13:04:29.639 ┆ 5.6732 ┆ 5.6738 ┆ 5.6735 │
133
- │ 2025-04-25 ┆ 2025-04-25 13:09:26.592 ┆ 5.684 ┆ 5.6846 ┆ 5.6843 │
134
- └────────────┴─────────────────────────┴────────────────┴───────────────┴───────────────┘
127
+ ┌────────────┬──────────────┬────────────────┬───────────────┬───────────────┐
128
+ │ data ┆ hora ┆ cotacao_compra ┆ cotacao_venda ┆ cotacao_media │
129
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
130
+ │ date ┆ time ┆ f64 ┆ f64 ┆ f64 │
131
+ ╞════════════╪══════════════╪════════════════╪═══════════════╪═══════════════╡
132
+ │ 2025-04-22 ┆ 13:09:35.629 ┆ 5.749 ┆ 5.7496 ┆ 5.7493 │
133
+ │ 2025-04-23 ┆ 13:06:30.443 ┆ 5.6874 ┆ 5.688 ┆ 5.6877 │
134
+ │ 2025-04-24 ┆ 13:04:29.639 ┆ 5.6732 ┆ 5.6738 ┆ 5.6735 │
135
+ │ 2025-04-25 ┆ 13:09:26.592 ┆ 5.684 ┆ 5.6846 ┆ 5.6843 │
136
+ └────────────┴──────────────┴────────────────┴───────────────┴───────────────┘
135
137
 
136
138
  >>> bc.ptax_series(start="02-01-1995", end="06-01-1995")
137
139
  shape: (5, 5)
138
- ┌────────────┬─────────────────────┬────────────────┬───────────────┬───────────────┐
139
- │ data ┆ data_hora ┆ cotacao_compra ┆ cotacao_venda ┆ cotacao_media │
140
- │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
141
- │ date ┆ datetime[μs] ┆ f64 ┆ f64 ┆ f64 │
142
- ╞════════════╪═════════════════════╪════════════════╪═══════════════╪═══════════════╡
143
- │ 1995-01-02 ┆ 1995-01-02 18:20:00 ┆ 0.843 ┆ 0.845 ┆ 0.844 │
144
- │ 1995-01-03 ┆ 1995-01-03 18:25:00 ┆ 0.844 ┆ 0.846 ┆ 0.845 │
145
- │ 1995-01-04 ┆ 1995-01-04 18:12:00 ┆ 0.844 ┆ 0.846 ┆ 0.845 │
146
- │ 1995-01-05 ┆ 1995-01-05 18:07:00 ┆ 0.842 ┆ 0.844 ┆ 0.843 │
147
- │ 1995-01-06 ┆ 1995-01-06 18:12:00 ┆ 0.839 ┆ 0.841 ┆ 0.84 │
148
- └────────────┴─────────────────────┴────────────────┴───────────────┴───────────────┘
140
+ ┌────────────┬──────────┬────────────────┬───────────────┬───────────────┐
141
+ │ data ┆ hora ┆ cotacao_compra ┆ cotacao_venda ┆ cotacao_media │
142
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
143
+ │ date ┆ time ┆ f64 ┆ f64 ┆ f64 │
144
+ ╞════════════╪══════════╪════════════════╪═══════════════╪═══════════════╡
145
+ │ 1995-01-02 ┆ 18:20:00 ┆ 0.843 ┆ 0.845 ┆ 0.844 │
146
+ │ 1995-01-03 ┆ 18:25:00 ┆ 0.844 ┆ 0.846 ┆ 0.845 │
147
+ │ 1995-01-04 ┆ 18:12:00 ┆ 0.844 ┆ 0.846 ┆ 0.845 │
148
+ │ 1995-01-05 ┆ 18:07:00 ┆ 0.842 ┆ 0.844 ┆ 0.843 │
149
+ │ 1995-01-06 ┆ 18:12:00 ┆ 0.839 ┆ 0.841 ┆ 0.84 │
150
+ └────────────┴──────────┴────────────────┴───────────────┴───────────────┘
149
151
  """
150
152
  if start:
151
153
  start = cv.converter_datas(start)
@@ -23,6 +23,7 @@ from pyield._internal.cache import ttl_cache
23
23
  from pyield._internal.converters import converter_datas
24
24
  from pyield._internal.retry import retry_padrao
25
25
  from pyield._internal.types import DateLike, any_is_empty
26
+ from pyield.clock import today
26
27
 
27
28
  URL_BASE = "https://www4.bcb.gov.br/pom/demab/negociacoes/download"
28
29
 
@@ -148,6 +149,8 @@ def tpf_monthly_trades(target_date: DateLike, extragroup: bool = False) -> pl.Da
148
149
  if any_is_empty(target_date):
149
150
  return pl.DataFrame()
150
151
  data_alvo = converter_datas(target_date)
152
+ if (data_alvo.year, data_alvo.month) > (today().year, today().month):
153
+ return pl.DataFrame()
151
154
  url = _montar_url(data_alvo, extragroup)
152
155
  conteudo_zip = _baixar_zip(url)
153
156
  arquivo_extraido = _descompactar_zip(conteudo_zip)
@@ -103,7 +103,7 @@ def forwards(
103
103
  >>> # Exemplo com taxas indicativas de NTN-B em 16-09-2025
104
104
  >>> from pyield import ntnb
105
105
  >>> df = ntnb.data("16-09-2025")
106
- >>> yd.forwards(df["BDToMat"], df["IndicativeRate"])
106
+ >>> yd.forwards(df["dias_uteis"], df["taxa_indicativa"])
107
107
  shape: (13,)
108
108
  Series: 'fwd' [f64]
109
109
  [
@@ -1,7 +1,7 @@
1
1
  import polars as pl
2
2
 
3
3
  import pyield._internal.converters as cv
4
- from pyield import anbima, bday
4
+ from pyield import bday
5
5
  from pyield._internal.types import DateLike, any_is_empty
6
6
  from pyield.tn import utils
7
7
 
@@ -17,62 +17,60 @@ def data(date: DateLike) -> pl.DataFrame:
17
17
  pl.DataFrame: DataFrame Polars com os dados de LFT.
18
18
 
19
19
  Output Columns:
20
- - ReferenceDate (Date): Data de referência dos dados.
21
- - BondType (String): Tipo do título (ex.: "LFT").
22
- - SelicCode (Int64): Código do título no SELIC.
23
- - IssueBaseDate (Date): Data base/emissão do título.
24
- - MaturityDate (Date): Data de vencimento do título.
25
- - BDToMat (Int64): Dias úteis entre referência e vencimento.
26
- - AvgMaturity (Float64): Prazo médio do título em anos.
27
- - Price (Float64): Preço unitário (PU).
28
- - BidRate (Float64): Taxa de compra (decimal).
29
- - AskRate (Float64): Taxa de venda (decimal).
30
- - IndicativeRate (Float64): Taxa indicativa (decimal).
31
- - DIRate (Float64): Taxa DI interpolada (flat forward).
32
- - Premium (Float64): Rentabilidade da LFT sobre o DI.
20
+ - data_referencia (Date): Data de referência dos dados.
21
+ - titulo (String): Tipo do título (ex.: "LFT").
22
+ - codigo_selic (Int64): Código do título no SELIC.
23
+ - data_base (Date): Data base/emissão do título.
24
+ - data_vencimento (Date): Data de vencimento do título.
25
+ - dias_uteis (Int64): Dias úteis entre referência e vencimento.
26
+ - prazo_medio (Float64): Prazo médio do título em anos.
27
+ - pu (Float64): Preço unitário (PU).
28
+ - taxa_compra (Float64): Taxa de compra (decimal).
29
+ - taxa_venda (Float64): Taxa de venda (decimal).
30
+ - taxa_indicativa (Float64): Taxa indicativa (decimal).
31
+ - taxa_di (Float64): Taxa DI interpolada pelo método flat forward.
32
+ - rentabilidade (Float64): Rentabilidade da LFT sobre o DI.
33
33
 
34
34
  Examples:
35
35
  >>> from pyield import lft
36
36
  >>> df_lft = lft.data("23-08-2024") # doctest: +SKIP
37
37
  """
38
- df = anbima.tpf(date, "LFT")
38
+ df = utils.obter_tpf(date, "LFT")
39
39
  if df.is_empty():
40
40
  return df
41
41
 
42
42
  data_ref = cv.converter_datas(date)
43
43
 
44
- # Adiciona BDToMat (dado derivado, não vem da ANBIMA)
45
44
  df = df.with_columns(
46
- BDToMat=bday.count_expr("ReferenceDate", "MaturityDate"),
45
+ dias_uteis=bday.count_expr("data_referencia", "data_vencimento"),
47
46
  )
48
47
 
49
- # Adiciona AvgMaturity e DIRate
50
48
  df = df.with_columns(
51
- AvgMaturity=pl.col("BDToMat") / 252,
49
+ prazo_medio=pl.col("dias_uteis") / 252,
52
50
  )
53
51
  df = utils.adicionar_taxa_di(df, data_ref)
54
52
 
55
53
  df = df.with_columns(
56
- Premium=pl.struct("IndicativeRate", "DIRate").map_elements(
57
- lambda s: premium(s["IndicativeRate"], s["DIRate"]),
54
+ rentabilidade=pl.struct("taxa_indicativa", "taxa_di").map_elements(
55
+ lambda s: premium(s["taxa_indicativa"], s["taxa_di"]),
58
56
  return_dtype=pl.Float64,
59
57
  )
60
58
  )
61
59
 
62
60
  return df.select(
63
- "ReferenceDate",
64
- "BondType",
65
- "SelicCode",
66
- "IssueBaseDate",
67
- "MaturityDate",
68
- "BDToMat",
69
- "AvgMaturity",
70
- "Price",
71
- "BidRate",
72
- "AskRate",
73
- "IndicativeRate",
74
- "DIRate",
75
- "Premium",
61
+ "data_referencia",
62
+ "titulo",
63
+ "codigo_selic",
64
+ "data_base",
65
+ "data_vencimento",
66
+ "dias_uteis",
67
+ "prazo_medio",
68
+ "pu",
69
+ "taxa_compra",
70
+ "taxa_venda",
71
+ "taxa_indicativa",
72
+ "taxa_di",
73
+ "rentabilidade",
76
74
  )
77
75
 
78
76
 
@@ -90,7 +88,7 @@ def maturities(date: DateLike) -> pl.Series:
90
88
  >>> from pyield import lft
91
89
  >>> lft.maturities("22-08-2024")
92
90
  shape: (14,)
93
- Series: 'MaturityDate' [date]
91
+ Series: 'data_vencimento' [date]
94
92
  [
95
93
  2024-09-01
96
94
  2025-03-01
@@ -105,7 +103,7 @@ def maturities(date: DateLike) -> pl.Series:
105
103
  2030-09-01
106
104
  ]
107
105
  """
108
- return data(date)["MaturityDate"]
106
+ return data(date)["data_vencimento"]
109
107
 
110
108
 
111
109
  def quotation(
@@ -1,7 +1,7 @@
1
1
  import polars as pl
2
2
 
3
3
  import pyield._internal.converters as cv
4
- from pyield import anbima, bday, fwd
4
+ from pyield import bday, fwd
5
5
  from pyield._internal.types import DateLike, any_is_empty
6
6
  from pyield.tn import utils
7
7
  from pyield.tn.pre import di_spreads as pre_di_spreads
@@ -20,72 +20,71 @@ def data(date: DateLike) -> pl.DataFrame:
20
20
  pl.DataFrame: DataFrame Polars com os dados de LTN.
21
21
 
22
22
  Output Columns:
23
- - ReferenceDate (Date): Data de referência dos dados.
24
- - BondType (String): Tipo do título (ex.: "LTN").
25
- - SelicCode (Int64): Código do título no SELIC.
26
- - IssueBaseDate (Date): Data base/emissão do título.
27
- - MaturityDate (Date): Data de vencimento do título.
28
- - BDToMat (Int64): Dias úteis entre referência e vencimento.
29
- - Duration (Float64): Macaulay Duration do título (anos).
30
- - AvgMaturity (Float64): Prazo médio do título (anos).
31
- - DV01 (Float64): Variação no preço para 1bp de taxa.
32
- - DV01USD (Float64): DV01 convertido para USD pela PTAX do dia.
33
- - Price (Float64): Preço unitário (PU).
34
- - BidRate (Float64): Taxa de compra (decimal).
35
- - AskRate (Float64): Taxa de venda (decimal).
36
- - IndicativeRate (Float64): Taxa indicativa (decimal).
37
- - DIRate (Float64): Taxa DI interpolada (flat forward).
38
- - DISpread (Float64): Spread sobre o DI (IndicativeRate - DIRate).
39
- - Premium (Float64): Rentabilidade diária da LTN sobre o DI.
23
+ - data_referencia (Date): Data de referência dos dados.
24
+ - titulo (String): Tipo do título (ex.: "LTN").
25
+ - codigo_selic (Int64): Código do título no SELIC.
26
+ - data_base (Date): Data base/emissão do título.
27
+ - data_vencimento (Date): Data de vencimento do título.
28
+ - dias_uteis (Int64): Dias úteis entre referência e vencimento.
29
+ - duration (Float64): Macaulay Duration do título (anos).
30
+ - prazo_medio (Float64): Prazo médio do título (anos).
31
+ - dv01 (Float64): Variação no preço para 1bp de taxa.
32
+ - dv01_usd (Float64): DV01 convertido para USD pela PTAX do dia.
33
+ - pu (Float64): Preço unitário (PU).
34
+ - taxa_compra (Float64): Taxa de compra (decimal).
35
+ - taxa_venda (Float64): Taxa de venda (decimal).
36
+ - taxa_indicativa (Float64): Taxa indicativa (decimal).
37
+ - taxa_di (Float64): Taxa DI interpolada pelo método flat forward.
38
+ - spread_di (Float64): Spread sobre o DI (também conhecido como
39
+ prêmio).
40
+ - rentabilidade (Float64): Rentabilidade diária da LTN sobre o DI.
40
41
 
41
42
  Examples:
42
43
  >>> from pyield import ltn
43
44
  >>> df_ltn = ltn.data("23-08-2024") # doctest: +SKIP
44
45
  """
45
- df = anbima.tpf(date, "LTN")
46
+ df = utils.obter_tpf(date, "LTN")
46
47
  if df.is_empty():
47
48
  return df
48
49
 
49
50
  data_ref = cv.converter_datas(date)
50
51
 
51
- # Adiciona BDToMat (dado derivado, não vem da ANBIMA)
52
52
  df = df.with_columns(
53
- BDToMat=bday.count_expr("ReferenceDate", "MaturityDate"),
53
+ dias_uteis=bday.count_expr("data_referencia", "data_vencimento"),
54
54
  )
55
55
 
56
- # Adiciona Duration, AvgMaturity, DV01, DV01USD e DIRate
57
56
  df = df.with_columns(
58
- Duration=pl.col("BDToMat") / 252,
59
- ).with_columns(AvgMaturity=pl.col("Duration"))
57
+ duration=pl.col("dias_uteis") / 252,
58
+ ).with_columns(prazo_medio=pl.col("duration"))
60
59
  df = utils.adicionar_dv01(df, data_ref)
61
60
  df = utils.adicionar_taxa_di(df, data_ref)
62
61
 
63
62
  df = df.with_columns(
64
- DISpread=pl.col("IndicativeRate") - pl.col("DIRate"),
65
- Premium=pl.struct("IndicativeRate", "DIRate").map_elements(
66
- lambda s: premium(s["IndicativeRate"], s["DIRate"]),
63
+ spread_di=pl.col("taxa_indicativa") - pl.col("taxa_di"),
64
+ rentabilidade=pl.struct("taxa_indicativa", "taxa_di").map_elements(
65
+ lambda s: premium(s["taxa_indicativa"], s["taxa_di"]),
67
66
  return_dtype=pl.Float64,
68
67
  ),
69
68
  )
70
69
 
71
70
  return df.select(
72
- "ReferenceDate",
73
- "BondType",
74
- "SelicCode",
75
- "IssueBaseDate",
76
- "MaturityDate",
77
- "BDToMat",
78
- "Duration",
79
- "AvgMaturity",
80
- "DV01",
81
- "DV01USD",
82
- "Price",
83
- "BidRate",
84
- "AskRate",
85
- "IndicativeRate",
86
- "DIRate",
87
- "DISpread",
88
- "Premium",
71
+ "data_referencia",
72
+ "titulo",
73
+ "codigo_selic",
74
+ "data_base",
75
+ "data_vencimento",
76
+ "dias_uteis",
77
+ "duration",
78
+ "prazo_medio",
79
+ "dv01",
80
+ "dv01_usd",
81
+ "pu",
82
+ "taxa_compra",
83
+ "taxa_venda",
84
+ "taxa_indicativa",
85
+ "taxa_di",
86
+ "spread_di",
87
+ "rentabilidade",
89
88
  )
90
89
 
91
90
 
@@ -103,7 +102,7 @@ def maturities(date: DateLike) -> pl.Series:
103
102
  >>> from pyield import ltn
104
103
  >>> ltn.maturities("22-08-2024")
105
104
  shape: (13,)
106
- Series: 'MaturityDate' [date]
105
+ Series: 'data_vencimento' [date]
107
106
  [
108
107
  2024-10-01
109
108
  2025-01-01
@@ -118,7 +117,7 @@ def maturities(date: DateLike) -> pl.Series:
118
117
  2030-01-01
119
118
  ]
120
119
  """
121
- return data(date)["MaturityDate"]
120
+ return data(date)["data_vencimento"]
122
121
 
123
122
 
124
123
  def price(
@@ -224,7 +223,7 @@ def premium(ltn_rate: float, di_rate: float) -> float:
224
223
  taxa_diaria_ltn = (1 + ltn_rate) ** (1 / 252) - 1
225
224
  taxa_diaria_di = (1 + di_rate) ** (1 / 252) - 1
226
225
 
227
- # Retorno do cálculo do prêmio
226
+ # Retorno do cálculo da rentabilidade
228
227
  return taxa_diaria_ltn / taxa_diaria_di
229
228
 
230
229
 
@@ -264,7 +263,7 @@ def di_spreads(date: DateLike, bps: bool = False) -> pl.DataFrame:
264
263
  Calcula o DI Spread para títulos prefixados (LTN e NTN-F) em uma data de referência.
265
264
 
266
265
  Definição do spread (forma bruta):
267
- DISpread_raw = IndicativeRate - SettlementRate
266
+ spread_di = taxa_indicativa - taxa de ajuste do DI
268
267
 
269
268
  Quando ``bps=False`` a coluna retorna essa diferença em formato decimal
270
269
  (ex: 0.000439 ≈ 4.39 bps). Quando ``bps=True`` o valor é automaticamente
@@ -272,16 +271,17 @@ def di_spreads(date: DateLike, bps: bool = False) -> pl.DataFrame:
272
271
 
273
272
  Args:
274
273
  date (DateLike): Data de referência para buscar as taxas.
275
- bps (bool): Se True, retorna DISpread já convertido em basis points.
274
+ bps (bool): Se True, retorna spread_di já convertido em basis points.
276
275
  Padrão False.
277
276
 
278
277
  Returns:
279
278
  pl.DataFrame: DataFrame com as colunas do spread.
280
279
 
281
280
  Output Columns:
282
- - BondType (String): Tipo do título.
283
- - MaturityDate (Date): Data de vencimento.
284
- - DISpread (Float64): Spread em decimal ou bps conforme parâmetro.
281
+ - titulo (String): Tipo do título.
282
+ - data_vencimento (Date): Data de vencimento.
283
+ - spread_di (Float64): Spread em decimal ou bps conforme parâmetro
284
+ (também conhecido como prêmio).
285
285
 
286
286
  Raises:
287
287
  ValueError: Se os dados de DI não possuem 'SettlementRate' ou estão vazios.
@@ -290,25 +290,25 @@ def di_spreads(date: DateLike, bps: bool = False) -> pl.DataFrame:
290
290
  >>> from pyield import ltn
291
291
  >>> ltn.di_spreads("30-05-2025", bps=True)
292
292
  shape: (13, 3)
293
- ┌──────────┬──────────────┬──────────┐
294
- │ BondType ┆ MaturityDate ┆ DISpread │
295
- │ --- ┆ --- ┆ --- │
296
- │ str ┆ date ┆ f64 │
297
- ╞══════════╪══════════════╪══════════╡
298
- │ LTN ┆ 2025-07-01 ┆ 4.39 │
299
- │ LTN ┆ 2025-10-01 ┆ -9.0 │
300
- │ LTN ┆ 2026-01-01 ┆ -4.88 │
301
- │ LTN ┆ 2026-04-01 ┆ -4.45 │
302
- │ LTN ┆ 2026-07-01 ┆ 0.81 │
303
- │ … ┆ … ┆ … │
304
- │ LTN ┆ 2028-01-01 ┆ 0.55 │
305
- │ LTN ┆ 2028-07-01 ┆ 1.5 │
306
- │ LTN ┆ 2029-01-01 ┆ 10.77 │
307
- │ LTN ┆ 2030-01-01 ┆ 11.0 │
308
- │ LTN ┆ 2032-01-01 ┆ 11.24 │
309
- └──────────┴──────────────┴──────────┘
293
+ ┌────────┬─────────────────┬───────────┐
294
+ │ titulo ┆ data_vencimento ┆ spread_di │
295
+ │ --- ┆ --- ┆ --- │
296
+ │ str ┆ date ┆ f64 │
297
+ ╞════════╪═════════════════╪═══════════╡
298
+ │ LTN ┆ 2025-07-01 ┆ 4.39 │
299
+ │ LTN ┆ 2025-10-01 ┆ -9.0 │
300
+ │ LTN ┆ 2026-01-01 ┆ -4.88 │
301
+ │ LTN ┆ 2026-04-01 ┆ -4.45 │
302
+ │ LTN ┆ 2026-07-01 ┆ 0.81 │
303
+ │ … ┆ … ┆ … │
304
+ │ LTN ┆ 2028-01-01 ┆ 0.55 │
305
+ │ LTN ┆ 2028-07-01 ┆ 1.5 │
306
+ │ LTN ┆ 2029-01-01 ┆ 10.77 │
307
+ │ LTN ┆ 2030-01-01 ┆ 11.0 │
308
+ │ LTN ┆ 2032-01-01 ┆ 11.24 │
309
+ └────────┴─────────────────┴───────────┘
310
310
  """
311
- return pre_di_spreads(date, bps=bps).filter(pl.col("BondType") == "LTN")
311
+ return pre_di_spreads(date, bps=bps).filter(pl.col("titulo") == "LTN")
312
312
 
313
313
 
314
314
  def forwards(date: DateLike) -> pl.DataFrame:
@@ -325,35 +325,35 @@ def forwards(date: DateLike) -> pl.DataFrame:
325
325
  pl.DataFrame: DataFrame com as taxas forward.
326
326
 
327
327
  Output Columns:
328
- - MaturityDate (Date): Data de vencimento.
329
- - BDToMat (Int64): Dias úteis entre referência e vencimento.
330
- - IndicativeRate (Float64): Taxa spot (zero cupom).
331
- - ForwardRate (Float64): Taxa forward.
328
+ - data_vencimento (Date): Data de vencimento.
329
+ - dias_uteis (Int64): Dias úteis entre referência e vencimento.
330
+ - taxa_indicativa (Float64): Taxa spot (zero cupom).
331
+ - taxa_forward (Float64): Taxa forward.
332
332
 
333
333
  Examples:
334
334
  >>> from pyield import ltn
335
335
  >>> ltn.forwards("17-10-2025")
336
336
  shape: (13, 4)
337
- ┌──────────────┬─────────┬────────────────┬─────────────┐
338
- │ MaturityDate ┆ BDToMat ┆ IndicativeRate ┆ ForwardRate │
339
- │ --- ┆ --- ┆ --- ┆ --- │
340
- │ date ┆ i64 ┆ f64 ┆ f64 │
341
- ╞══════════════╪═════════╪════════════════╪═════════════╡
342
- │ 2026-01-01 ┆ 52 ┆ 0.148307 ┆ 0.148307 │
343
- │ 2026-04-01 ┆ 113 ┆ 0.147173 ┆ 0.146207 │
344
- │ 2026-07-01 ┆ 174 ┆ 0.145206 ┆ 0.141571 │
345
- │ 2026-10-01 ┆ 239 ┆ 0.142424 ┆ 0.13501 │
346
- │ 2027-04-01 ┆ 361 ┆ 0.138155 ┆ 0.129838 │
347
- │ … ┆ … ┆ … ┆ … │
348
- │ 2028-07-01 ┆ 676 ┆ 0.133411 ┆ 0.131654 │
349
- │ 2029-01-01 ┆ 800 ┆ 0.134254 ┆ 0.138861 │
350
- │ 2029-07-01 ┆ 924 ┆ 0.135264 ┆ 0.141802 │
351
- │ 2030-01-01 ┆ 1049 ┆ 0.135967 ┆ 0.141177 │
352
- │ 2032-01-01 ┆ 1553 ┆ 0.13883 ┆ 0.144812 │
353
- └──────────────┴─────────┴────────────────┴─────────────┘
337
+ ┌─────────────────┬────────────┬─────────────────┬──────────────┐
338
+ │ data_vencimento ┆ dias_uteis ┆ taxa_indicativa ┆ taxa_forward │
339
+ │ --- ┆ --- ┆ --- ┆ --- │
340
+ │ date ┆ i64 ┆ f64 ┆ f64 │
341
+ ╞═════════════════╪════════════╪═════════════════╪══════════════╡
342
+ │ 2026-01-01 ┆ 52 ┆ 0.148307 ┆ 0.148307 │
343
+ │ 2026-04-01 ┆ 113 ┆ 0.147173 ┆ 0.146207 │
344
+ │ 2026-07-01 ┆ 174 ┆ 0.145206 ┆ 0.141571 │
345
+ │ 2026-10-01 ┆ 239 ┆ 0.142424 ┆ 0.13501 │
346
+ │ 2027-04-01 ┆ 361 ┆ 0.138155 ┆ 0.129838 │
347
+ │ … ┆ … ┆ … ┆ … │
348
+ │ 2028-07-01 ┆ 676 ┆ 0.133411 ┆ 0.131654 │
349
+ │ 2029-01-01 ┆ 800 ┆ 0.134254 ┆ 0.138861 │
350
+ │ 2029-07-01 ┆ 924 ┆ 0.135264 ┆ 0.141802 │
351
+ │ 2030-01-01 ┆ 1049 ┆ 0.135967 ┆ 0.141177 │
352
+ │ 2032-01-01 ┆ 1553 ┆ 0.13883 ┆ 0.144812 │
353
+ └─────────────────┴────────────┴─────────────────┴──────────────┘
354
354
  """
355
355
  if any_is_empty(date):
356
356
  return pl.DataFrame()
357
- df = data(date).select("MaturityDate", "BDToMat", "IndicativeRate")
358
- taxas_forward = fwd.forwards(bdays=df["BDToMat"], rates=df["IndicativeRate"])
359
- return df.with_columns(ForwardRate=taxas_forward).sort("MaturityDate")
357
+ df = data(date).select("data_vencimento", "dias_uteis", "taxa_indicativa")
358
+ taxas_forward = fwd.forwards(bdays=df["dias_uteis"], rates=df["taxa_indicativa"])
359
+ return df.with_columns(taxa_forward=taxas_forward).sort("data_vencimento")