PYield 0.45.1__tar.gz → 0.45.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 (69) hide show
  1. {pyield-0.45.1 → pyield-0.45.2}/PKG-INFO +1 -1
  2. pyield-0.45.2/pyield/__about__.py +1 -0
  3. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/auctions.py +32 -27
  4. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/lft.py +18 -9
  5. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/ltn.py +20 -2
  6. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/ntnb.py +21 -2
  7. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/ntnc.py +18 -2
  8. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/ntnf.py +22 -2
  9. pyield-0.45.1/pyield/__about__.py +0 -1
  10. {pyield-0.45.1 → pyield-0.45.2}/.gitignore +0 -0
  11. {pyield-0.45.1 → pyield-0.45.2}/LICENSE +0 -0
  12. {pyield-0.45.1 → pyield-0.45.2}/README.md +0 -0
  13. {pyield-0.45.1 → pyield-0.45.2}/pyield/__init__.py +0 -0
  14. {pyield-0.45.1 → pyield-0.45.2}/pyield/_internal/__init__.py +0 -0
  15. {pyield-0.45.1 → pyield-0.45.2}/pyield/_internal/cache.py +0 -0
  16. {pyield-0.45.1 → pyield-0.45.2}/pyield/_internal/converters.py +0 -0
  17. {pyield-0.45.1 → pyield-0.45.2}/pyield/_internal/data_cache.py +0 -0
  18. {pyield-0.45.1 → pyield-0.45.2}/pyield/_internal/retry.py +0 -0
  19. {pyield-0.45.1 → pyield-0.45.2}/pyield/_internal/types.py +0 -0
  20. {pyield-0.45.1 → pyield-0.45.2}/pyield/anbima/__init__.py +0 -0
  21. {pyield-0.45.1 → pyield-0.45.2}/pyield/anbima/difusao.py +0 -0
  22. {pyield-0.45.1 → pyield-0.45.2}/pyield/anbima/ettj_intraday.py +0 -0
  23. {pyield-0.45.1 → pyield-0.45.2}/pyield/anbima/ettj_last.py +0 -0
  24. {pyield-0.45.1 → pyield-0.45.2}/pyield/anbima/ima.py +0 -0
  25. {pyield-0.45.1 → pyield-0.45.2}/pyield/anbima/imaq.py +0 -0
  26. {pyield-0.45.1 → pyield-0.45.2}/pyield/anbima/tpf.py +0 -0
  27. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/__init__.py +0 -0
  28. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/_contracts.py +0 -0
  29. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/_validar_pregao.py +0 -0
  30. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/di1.py +0 -0
  31. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/di_over.py +0 -0
  32. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/futures/__init__.py +0 -0
  33. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/futures/common.py +0 -0
  34. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/futures/historical.py +0 -0
  35. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/futures/intraday.py +0 -0
  36. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/intraday_derivatives.py +0 -0
  37. {pyield-0.45.1 → pyield-0.45.2}/pyield/b3/price_report.py +0 -0
  38. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/__init__.py +0 -0
  39. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/auction.py +0 -0
  40. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/copom.py +0 -0
  41. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/ptax_api.py +0 -0
  42. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/rates.py +0 -0
  43. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/repo.py +0 -0
  44. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/trades_intraday.py +0 -0
  45. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/trades_monthly.py +0 -0
  46. {pyield-0.45.1 → pyield-0.45.2}/pyield/bc/vna.py +0 -0
  47. {pyield-0.45.1 → pyield-0.45.2}/pyield/bday/__init__.py +0 -0
  48. {pyield-0.45.1 → pyield-0.45.2}/pyield/bday/core.py +0 -0
  49. {pyield-0.45.1 → pyield-0.45.2}/pyield/bday/holidays/br_holidays_new.txt +0 -0
  50. {pyield-0.45.1 → pyield-0.45.2}/pyield/bday/holidays/br_holidays_old.txt +0 -0
  51. {pyield-0.45.1 → pyield-0.45.2}/pyield/bday/holidays/brholidays.py +0 -0
  52. {pyield-0.45.1 → pyield-0.45.2}/pyield/clock.py +0 -0
  53. {pyield-0.45.1 → pyield-0.45.2}/pyield/fwd.py +0 -0
  54. {pyield-0.45.1 → pyield-0.45.2}/pyield/interpolator.py +0 -0
  55. {pyield-0.45.1 → pyield-0.45.2}/pyield/ipca/__init__.py +0 -0
  56. {pyield-0.45.1 → pyield-0.45.2}/pyield/ipca/historical.py +0 -0
  57. {pyield-0.45.1 → pyield-0.45.2}/pyield/ipca/projected.py +0 -0
  58. {pyield-0.45.1 → pyield-0.45.2}/pyield/py.typed +0 -0
  59. {pyield-0.45.1 → pyield-0.45.2}/pyield/rmd.py +0 -0
  60. {pyield-0.45.1 → pyield-0.45.2}/pyield/selic/__init__.py +0 -0
  61. {pyield-0.45.1 → pyield-0.45.2}/pyield/selic/cpm.py +0 -0
  62. {pyield-0.45.1 → pyield-0.45.2}/pyield/selic/probabilities.py +0 -0
  63. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/__init__.py +0 -0
  64. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/benchmark.py +0 -0
  65. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/ntnb1.py +0 -0
  66. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/ntnbprinc.py +0 -0
  67. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/pre.py +0 -0
  68. {pyield-0.45.1 → pyield-0.45.2}/pyield/tn/utils.py +0 -0
  69. {pyield-0.45.1 → pyield-0.45.2}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyield
3
- Version: 0.45.1
3
+ Version: 0.45.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
@@ -0,0 +1 @@
1
+ __version__ = "0.45.2"
@@ -1,5 +1,6 @@
1
1
  import datetime as dt
2
2
  import logging
3
+ from collections.abc import Sequence
3
4
 
4
5
  import polars as pl
5
6
  import requests
@@ -7,8 +8,9 @@ from polars import selectors as cs
7
8
 
8
9
  from pyield import bc, bday
9
10
  from pyield._internal import converters as cv
11
+ from pyield._internal.cache import ttl_cache
10
12
  from pyield._internal.retry import retry_padrao
11
- from pyield._internal.types import DateLike, any_is_empty
13
+ from pyield._internal.types import DateLike, any_is_empty, is_collection
12
14
  from pyield.tn.ntnb import duration as duration_b
13
15
  from pyield.tn.ntnf import duration as duration_f
14
16
 
@@ -86,6 +88,7 @@ ORDEM_FINAL_COLUNAS = [
86
88
  ]
87
89
 
88
90
 
91
+ @ttl_cache()
89
92
  @retry_padrao
90
93
  def _buscar_dados_leilao(data_leilao: dt.date) -> list[dict]:
91
94
  """Busca os dados brutos da API do Tesouro para uma data específica.
@@ -358,15 +361,17 @@ def _selecionar_e_ordenar_colunas(df: pl.DataFrame) -> pl.DataFrame:
358
361
  return df.select(colunas_selecionadas).sort("data_1v", "titulo", "data_vencimento")
359
362
 
360
363
 
361
- def auction(auction_date: DateLike) -> pl.DataFrame:
364
+ def auction(auction_date: DateLike | Sequence[DateLike]) -> pl.DataFrame:
362
365
  """Consulta e processa os resultados de leilões de títulos do Tesouro Nacional.
363
366
 
364
- Busca os dados da API do Tesouro para a data informada e retorna um DataFrame
365
- estruturado com quantidades, financeiros, taxas de colocação, duration e DV01.
367
+ Busca os dados da API do Tesouro para a(s) data(s) informada(s) e retorna
368
+ um DataFrame estruturado com quantidades, financeiros, taxas de colocação,
369
+ duration e DV01.
366
370
 
367
371
  Args:
368
- auction_date: Data do leilão em qualquer formato aceito por DateLike
369
- (ex: "DD-MM-YYYY", datetime.date).
372
+ auction_date: Data ou sequência de datas do leilão em qualquer
373
+ formato aceito por DateLike (ex: "DD-MM-YYYY", datetime.date,
374
+ ou lista desses formatos).
370
375
 
371
376
  Returns:
372
377
  DataFrame com os dados processados do leilão. Em caso de erro na
@@ -421,28 +426,28 @@ def auction(auction_date: DateLike) -> pl.DataFrame:
421
426
  - taxa_maxima (Float64): taxa de juros máxima aceita, taxa de corte (decimal).
422
427
  """
423
428
  if any_is_empty(auction_date):
424
- logger.info("Nenhuma data de leilão informada.")
425
429
  return pl.DataFrame()
426
- try:
427
- auction_date = cv.converter_datas(auction_date)
428
- dados_leilao = _buscar_dados_leilao(auction_date)
429
- if not dados_leilao:
430
- logger.info("Sem dados de leilão disponíveis para %s.", auction_date)
431
- return pl.DataFrame()
432
- df = _transformar_dados_brutos(dados_leilao)
433
- df = _adicionar_duration(df)
434
- df = _adicionar_dv01(df)
435
- df = _adicionar_dv01_usd(df)
436
- df = _adicionar_prazo_medio(df)
437
- # Substituir eventuais NaNs por None para compatibilidade com bancos de dados
438
- df = df.with_columns(cs.float().fill_nan(None))
439
- df = _selecionar_e_ordenar_colunas(df)
440
430
 
441
- return df
442
-
443
- except requests.exceptions.RequestException as e:
444
- logger.error("Erro durante a requisição da API: %s", e)
431
+ datas: Sequence[DateLike] = (
432
+ auction_date if is_collection(auction_date) else [auction_date] # type: ignore[assignment]
433
+ )
434
+ resultados = [_processar_data_unica(d) for d in datas]
435
+ resultados = [df for df in resultados if not df.is_empty()]
436
+ if not resultados:
445
437
  return pl.DataFrame()
446
- except (ValueError, TypeError) as e:
447
- logger.error("Erro ao processar a resposta JSON: %s", e)
438
+ return pl.concat(resultados)
439
+
440
+
441
+ def _processar_data_unica(data_leilao: DateLike) -> pl.DataFrame:
442
+ """Busca e processa o leilão de uma única data."""
443
+ data = cv.converter_datas(data_leilao)
444
+ dados_leilao = _buscar_dados_leilao(data)
445
+ if not dados_leilao:
448
446
  return pl.DataFrame()
447
+ df = _transformar_dados_brutos(dados_leilao)
448
+ df = _adicionar_duration(df)
449
+ df = _adicionar_dv01(df)
450
+ df = _adicionar_dv01_usd(df)
451
+ df = _adicionar_prazo_medio(df)
452
+ df = df.with_columns(cs.float().fill_nan(None))
453
+ return _selecionar_e_ordenar_colunas(df)
@@ -17,16 +17,13 @@ def data(date: DateLike) -> pl.DataFrame:
17
17
  pl.DataFrame: DataFrame Polars com os dados de LFT.
18
18
 
19
19
  Output Columns:
20
- - BondType (String): Tipo do título (ex.: "LFT").
21
20
  - ReferenceDate (Date): Data de referência dos dados.
21
+ - BondType (String): Tipo do título (ex.: "LFT").
22
22
  - SelicCode (Int64): Código do título no SELIC.
23
23
  - IssueBaseDate (Date): Data base/emissão do título.
24
24
  - MaturityDate (Date): Data de vencimento do título.
25
25
  - BDToMat (Int64): Dias úteis entre referência e vencimento.
26
- - AvgMaturity (Float64): Prazo médio do título em dias corridos.
27
- - Duration (Float64): Macaulay Duration do título (anos).
28
- - DV01 (Float64): Variação no preço para 1bp de taxa.
29
- - DV01USD (Float64): DV01 convertido para USD pela PTAX do dia.
26
+ - AvgMaturity (Float64): Prazo médio do título em anos.
30
27
  - Price (Float64): Preço unitário (PU).
31
28
  - BidRate (Float64): Taxa de compra (decimal).
32
29
  - AskRate (Float64): Taxa de venda (decimal).
@@ -49,12 +46,10 @@ def data(date: DateLike) -> pl.DataFrame:
49
46
  BDToMat=bday.count_expr("ReferenceDate", "MaturityDate"),
50
47
  )
51
48
 
52
- # Adiciona Duration, AvgMaturity, DV01, DV01USD e DIRate
49
+ # Adiciona AvgMaturity e DIRate
53
50
  df = df.with_columns(
54
- Duration=pl.lit(0.0),
55
51
  AvgMaturity=pl.col("BDToMat") / 252,
56
52
  )
57
- df = utils.adicionar_dv01(df, data_ref)
58
53
  df = utils.adicionar_taxa_di(df, data_ref)
59
54
 
60
55
  df = df.with_columns(
@@ -64,7 +59,21 @@ def data(date: DateLike) -> pl.DataFrame:
64
59
  )
65
60
  )
66
61
 
67
- return df
62
+ 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",
76
+ )
68
77
 
69
78
 
70
79
  def maturities(date: DateLike) -> pl.Series:
@@ -20,8 +20,8 @@ def data(date: DateLike) -> pl.DataFrame:
20
20
  pl.DataFrame: DataFrame Polars com os dados de LTN.
21
21
 
22
22
  Output Columns:
23
- - BondType (String): Tipo do título (ex.: "LTN").
24
23
  - ReferenceDate (Date): Data de referência dos dados.
24
+ - BondType (String): Tipo do título (ex.: "LTN").
25
25
  - SelicCode (Int64): Código do título no SELIC.
26
26
  - IssueBaseDate (Date): Data base/emissão do título.
27
27
  - MaturityDate (Date): Data de vencimento do título.
@@ -68,7 +68,25 @@ def data(date: DateLike) -> pl.DataFrame:
68
68
  ),
69
69
  )
70
70
 
71
- return df
71
+ 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",
89
+ )
72
90
 
73
91
 
74
92
  def maturities(date: DateLike) -> pl.Series:
@@ -35,8 +35,8 @@ def data(date: DateLike) -> pl.DataFrame:
35
35
  pl.DataFrame: DataFrame Polars com os dados de NTN-B.
36
36
 
37
37
  Output Columns:
38
- - BondType (String): Tipo do título (ex.: "NTN-B").
39
38
  - ReferenceDate (Date): Data de referência dos dados.
39
+ - BondType (String): Tipo do título (ex.: "NTN-B").
40
40
  - SelicCode (Int64): Código do título no SELIC.
41
41
  - IssueBaseDate (Date): Data base/emissão do título.
42
42
  - MaturityDate (Date): Data de vencimento do título.
@@ -97,7 +97,26 @@ def data(date: DateLike) -> pl.DataFrame:
97
97
  taxas_forward = fwd.forwards(bdays=df["BDToMat"], rates=df["SpotRate"])
98
98
  df = df.with_columns(ForwardRate=taxas_forward)
99
99
 
100
- return df
100
+ return df.select(
101
+ "ReferenceDate",
102
+ "BondType",
103
+ "SelicCode",
104
+ "IssueBaseDate",
105
+ "MaturityDate",
106
+ "BDToMat",
107
+ "Duration",
108
+ "AvgMaturity",
109
+ "DV01",
110
+ "DV01USD",
111
+ "Price",
112
+ "BidRate",
113
+ "AskRate",
114
+ "IndicativeRate",
115
+ "DIRate",
116
+ "SpotRate",
117
+ "ForwardRate",
118
+ "ImpliedInflation",
119
+ )
101
120
 
102
121
 
103
122
  def maturities(date: DateLike) -> pl.Series:
@@ -51,8 +51,8 @@ def data(date: DateLike) -> pl.DataFrame:
51
51
  pl.DataFrame: DataFrame Polars com os dados de NTN-C.
52
52
 
53
53
  Output Columns:
54
- - BondType (String): Tipo do título (ex.: "NTN-C").
55
54
  - ReferenceDate (Date): Data de referência dos dados.
55
+ - BondType (String): Tipo do título (ex.: "NTN-C").
56
56
  - SelicCode (Int64): Código do título no SELIC.
57
57
  - IssueBaseDate (Date): Data base/emissão do título.
58
58
  - MaturityDate (Date): Data de vencimento do título.
@@ -87,7 +87,23 @@ def data(date: DateLike) -> pl.DataFrame:
87
87
  df = utils.adicionar_dv01(df, data_ref)
88
88
  df = utils.adicionar_taxa_di(df, data_ref)
89
89
 
90
- return df
90
+ return df.select(
91
+ "ReferenceDate",
92
+ "BondType",
93
+ "SelicCode",
94
+ "IssueBaseDate",
95
+ "MaturityDate",
96
+ "BDToMat",
97
+ "Duration",
98
+ "AvgMaturity",
99
+ "DV01",
100
+ "DV01USD",
101
+ "Price",
102
+ "BidRate",
103
+ "AskRate",
104
+ "IndicativeRate",
105
+ "DIRate",
106
+ )
91
107
 
92
108
 
93
109
  def payment_dates(
@@ -41,8 +41,8 @@ def data(date: DateLike) -> pl.DataFrame:
41
41
  pl.DataFrame: DataFrame Polars com os dados de NTN-F.
42
42
 
43
43
  Output Columns:
44
- - BondType (String): Tipo do título (ex.: "NTN-F").
45
44
  - ReferenceDate (Date): Data de referência dos dados.
45
+ - BondType (String): Tipo do título (ex.: "NTN-F").
46
46
  - SelicCode (Int64): Código do título no SELIC.
47
47
  - IssueBaseDate (Date): Data base/emissão do título.
48
48
  - MaturityDate (Date): Data de vencimento do título.
@@ -120,7 +120,27 @@ def data(date: DateLike) -> pl.DataFrame:
120
120
  ),
121
121
  )
122
122
 
123
- return df
123
+ return df.select(
124
+ "ReferenceDate",
125
+ "BondType",
126
+ "SelicCode",
127
+ "IssueBaseDate",
128
+ "MaturityDate",
129
+ "BDToMat",
130
+ "AvgMaturity",
131
+ "Duration",
132
+ "DV01",
133
+ "DV01USD",
134
+ "Price",
135
+ "BidRate",
136
+ "AskRate",
137
+ "IndicativeRate",
138
+ "DIRate",
139
+ "SpotRate",
140
+ "DISpread",
141
+ "DINetSpread",
142
+ "Premium",
143
+ )
124
144
 
125
145
 
126
146
  def maturities(date: DateLike) -> pl.Series:
@@ -1 +0,0 @@
1
- __version__ = "0.45.1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes