PYield 0.46.7__tar.gz → 0.46.8__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.46.7 → pyield-0.46.8}/PKG-INFO +1 -1
- pyield-0.46.8/pyield/__about__.py +1 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/futures/__init__.py +29 -35
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/futures/historical.py +7 -11
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/price_report.py +9 -21
- pyield-0.46.7/pyield/__about__.py +0 -1
- {pyield-0.46.7 → pyield-0.46.8}/.gitignore +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/LICENSE +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/README.md +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/_internal/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/_internal/br_numbers.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/_internal/cache.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/_internal/converters.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/_internal/data_cache.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/_internal/retry.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/_internal/types.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/anbima/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/anbima/ettj_intraday.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/anbima/ettj_last.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/anbima/ima.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/anbima/imaq.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/anbima/tpf.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/_contracts.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/_validar_pregao.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/di1.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/di_over.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/futures/common.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/futures/intraday.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/b3/intraday_derivatives.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/auction.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/copom.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/ptax_api.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/rates.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/repo.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/trades_intraday.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/trades_monthly.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bc/vna.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bday/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bday/core.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bday/holidays/br_holidays_new.txt +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bday/holidays/br_holidays_old.txt +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/bday/holidays/brholidays.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/clock.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/fwd.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/interpolator.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/ipca/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/ipca/historical.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/ipca/projected.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/py.typed +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/rmd.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/selic/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/selic/cpm.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/selic/probabilities.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/__init__.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/auctions.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/benchmark.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/lft.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/ltn.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/ntnb.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/ntnb1.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/ntnbprinc.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/ntnc.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/ntnf.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/pre.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyield/tn/utils.py +0 -0
- {pyield-0.46.7 → pyield-0.46.8}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyield
|
|
3
|
-
Version: 0.46.
|
|
3
|
+
Version: 0.46.8
|
|
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.46.8"
|
|
@@ -19,7 +19,7 @@ logger = logging.getLogger(__name__)
|
|
|
19
19
|
def futures(
|
|
20
20
|
date: DateLike | ArrayLike,
|
|
21
21
|
contract_code: str | list[str],
|
|
22
|
-
full_report: bool
|
|
22
|
+
full_report: bool = False,
|
|
23
23
|
) -> pl.DataFrame:
|
|
24
24
|
"""Busca dados de um contrato futuro da B3 para a data de referência.
|
|
25
25
|
|
|
@@ -28,29 +28,25 @@ def futures(
|
|
|
28
28
|
Quando uma coleção é fornecida, os dados são buscados para cada
|
|
29
29
|
data individualmente e concatenados. Datas inválidas (feriados,
|
|
30
30
|
fins de semana, futuras) são silenciosamente ignoradas.
|
|
31
|
-
contract_code: Código do contrato futuro na B3 ou coleção de
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
contract_code: Código do contrato futuro na B3 ou coleção de
|
|
32
|
+
códigos. Aceita qualquer código de contrato futuro listado
|
|
33
|
+
na B3. Contratos com histórico pré-cacheado (desde 2018)
|
|
34
|
+
são retornados instantaneamente:
|
|
35
|
+
- Juros: DI1, DDI, FRC, FRO, DAP
|
|
36
|
+
- Moedas: DOL, WDO
|
|
37
|
+
- Índices: IND, WIN
|
|
38
|
+
Para os demais contratos (OC1, IAP, EUR, GBR, JAP, CNY,
|
|
39
|
+
ISP, WSP, BGI, CCM, ICF, SJC, SOY, ETH, GLD, etc.),
|
|
40
|
+
os dados são baixados diretamente da B3 a cada chamada.
|
|
41
|
+
full_report: Controla a fonte de dados quando o dado não está
|
|
42
|
+
no cache. Se False (padrão), tenta o simplified price
|
|
43
|
+
report (SPR, ~2 KB) primeiro e faz fallback para o price
|
|
44
|
+
report completo (PR, ~2 MB). Se True, usa apenas o PR —
|
|
43
45
|
indicado para processos batch noturnos.
|
|
44
46
|
|
|
45
47
|
Returns:
|
|
46
48
|
DataFrame Polars com os dados do contrato informado.
|
|
47
49
|
|
|
48
|
-
Notes:
|
|
49
|
-
Os contratos DI1, DDI, FRC, FRO, DAP, DOL, WDO, IND e WIN possuem
|
|
50
|
-
histórico pré-cacheado (desde 2018) e são retornados instantaneamente.
|
|
51
|
-
Para os demais contratos, os dados são baixados diretamente da B3 a
|
|
52
|
-
cada chamada, o que pode ser mais lento.
|
|
53
|
-
|
|
54
50
|
Examples:
|
|
55
51
|
>>> df = futures("31-05-2024", "DI1")
|
|
56
52
|
>>> df = futures("31-05-2024", "DAP")
|
|
@@ -101,7 +97,7 @@ def futures(
|
|
|
101
97
|
def _buscar_varias_datas(
|
|
102
98
|
datas: ArrayLike,
|
|
103
99
|
codigos: list[str],
|
|
104
|
-
full_report: bool
|
|
100
|
+
full_report: bool,
|
|
105
101
|
) -> pl.DataFrame:
|
|
106
102
|
"""Busca dados para múltiplas datas e concatena os resultados.
|
|
107
103
|
|
|
@@ -142,27 +138,25 @@ def _buscar_varias_datas(
|
|
|
142
138
|
def _buscar_por_fonte(
|
|
143
139
|
data: dt.date,
|
|
144
140
|
codigos: list[str],
|
|
145
|
-
full_report: bool
|
|
141
|
+
full_report: bool,
|
|
146
142
|
) -> pl.DataFrame:
|
|
147
|
-
"""Seleciona a fonte de dados com base
|
|
148
|
-
|
|
143
|
+
"""Seleciona a fonte de dados com base na data e horário.
|
|
144
|
+
|
|
145
|
+
Para datas passadas, usa dados consolidados (historical).
|
|
146
|
+
Para a data de hoje, depende do horário:
|
|
147
|
+
- Antes das 09:16: sem dados disponíveis (DataFrame vazio).
|
|
148
|
+
- Entre 09:16 e 19:00: dados intraday.
|
|
149
|
+
- A partir das 19:00: dados consolidados (historical).
|
|
150
|
+
"""
|
|
151
|
+
if data != clock.today():
|
|
149
152
|
return historical.historical(data, codigos, full_report)
|
|
150
153
|
|
|
151
154
|
horario = clock.now().time()
|
|
152
155
|
if horario >= HORA_INICIO_CONSOLIDADO:
|
|
153
|
-
|
|
154
|
-
df = historical.historical(data, codigos, full_report)
|
|
155
|
-
if not df.is_empty():
|
|
156
|
-
return df
|
|
157
|
-
return intraday.intraday(codigos)
|
|
158
|
-
|
|
156
|
+
return historical.historical(data, codigos, full_report)
|
|
159
157
|
if horario >= HORA_INICIO_INTRADAY:
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if not df.is_empty():
|
|
163
|
-
return df
|
|
164
|
-
|
|
165
|
-
return historical.historical(data, codigos, full_report)
|
|
158
|
+
return intraday.intraday(codigos)
|
|
159
|
+
return pl.DataFrame()
|
|
166
160
|
|
|
167
161
|
|
|
168
162
|
def available_dates(contract_code: str) -> pl.Series:
|
|
@@ -63,16 +63,15 @@ def _obter_pr_normalizado() -> pl.DataFrame:
|
|
|
63
63
|
def historical(
|
|
64
64
|
data: dt.date,
|
|
65
65
|
codigo_contrato: str | list[str],
|
|
66
|
-
full_report: bool
|
|
66
|
+
full_report: bool = False,
|
|
67
67
|
) -> pl.DataFrame:
|
|
68
68
|
"""Busca histórico de futuros priorizando o dataset PR cacheado.
|
|
69
69
|
|
|
70
70
|
Args:
|
|
71
71
|
data: Data de negociação.
|
|
72
72
|
codigo_contrato: Código(s) do contrato futuro na B3.
|
|
73
|
-
full_report: Se
|
|
74
|
-
Se
|
|
75
|
-
Se True, usa o price report completo (PR, ~2 MB).
|
|
73
|
+
full_report: Se False (padrão), tenta SPR primeiro e PR como
|
|
74
|
+
fallback. Se True, usa apenas o PR completo (~2 MB).
|
|
76
75
|
|
|
77
76
|
Returns:
|
|
78
77
|
DataFrame Polars com dados históricos de futuros.
|
|
@@ -202,16 +201,13 @@ def listar_datas_disponiveis(codigo_contrato: str) -> pl.Series:
|
|
|
202
201
|
)
|
|
203
202
|
|
|
204
203
|
|
|
205
|
-
def _buscar_price_report(
|
|
206
|
-
data: dt.date, codigo: str, full_report: bool | None
|
|
207
|
-
) -> pl.DataFrame:
|
|
204
|
+
def _buscar_price_report(data: dt.date, codigo: str, full_report: bool) -> pl.DataFrame:
|
|
208
205
|
"""Busca o price report da B3, com fallback SPR→PR.
|
|
209
206
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
e faz fallback para o PR se o SPR estiver vazio.
|
|
207
|
+
Se full_report é True, usa apenas o PR (completo).
|
|
208
|
+
Se False, tenta o SPR (leve) primeiro e faz fallback para o PR.
|
|
213
209
|
"""
|
|
214
|
-
if full_report
|
|
210
|
+
if full_report:
|
|
215
211
|
return _normalizar_colunas_pr(
|
|
216
212
|
fetch_price_report(date=data, contract_code=codigo, full_report=True)
|
|
217
213
|
)
|
|
@@ -102,30 +102,18 @@ def _baixar_zip_url(data: dt.date, relatorio_completo: bool) -> bytes:
|
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
def _extrair_xml_de_zip(conteudo_zip: bytes) -> bytes:
|
|
105
|
-
"""Extrai o XML
|
|
105
|
+
"""Extrai o XML do ZIP aninhado da B3 (ZIP externo → ZIP interno → XML)."""
|
|
106
106
|
with zipfile.ZipFile(io.BytesIO(conteudo_zip), "r") as zip_externo:
|
|
107
|
-
|
|
108
|
-
if not
|
|
107
|
+
nomes = zip_externo.namelist()
|
|
108
|
+
if not nomes:
|
|
109
109
|
raise ValueError("ZIP externo está vazio")
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
for nome in nomes_externos:
|
|
118
|
-
conteudo_interno = zip_externo.read(nome)
|
|
119
|
-
if conteudo_interno[:4] != b"PK\x03\x04":
|
|
120
|
-
continue
|
|
121
|
-
with zipfile.ZipFile(io.BytesIO(conteudo_interno), "r") as zip_interno:
|
|
122
|
-
nomes_xml = sorted(
|
|
123
|
-
n for n in zip_interno.namelist() if n.endswith(".xml")
|
|
124
|
-
)
|
|
125
|
-
if nomes_xml:
|
|
126
|
-
return zip_interno.read(nomes_xml[-1])
|
|
127
|
-
|
|
128
|
-
raise ValueError("Nenhum XML encontrado no ZIP")
|
|
111
|
+
conteudo_interno = zip_externo.read(nomes[0])
|
|
112
|
+
with zipfile.ZipFile(io.BytesIO(conteudo_interno), "r") as zip_interno:
|
|
113
|
+
nomes_xml = sorted(n for n in zip_interno.namelist() if n.endswith(".xml"))
|
|
114
|
+
if not nomes_xml:
|
|
115
|
+
raise ValueError("Nenhum XML encontrado no ZIP interno")
|
|
116
|
+
return zip_interno.read(nomes_xml[-1])
|
|
129
117
|
|
|
130
118
|
|
|
131
119
|
def _ticker_valido_para_contrato(ticker: str, codigo_contrato: str) -> bool:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.46.7"
|
|
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
|
|
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
|