pyield 0.47.2__tar.gz → 0.47.3__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.47.2 → pyield-0.47.3}/PKG-INFO +9 -10
- {pyield-0.47.2 → pyield-0.47.3}/README.md +8 -9
- pyield-0.47.3/pyield/__about__.py +1 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/price_report.py +66 -76
- pyield-0.47.2/pyield/__about__.py +0 -1
- {pyield-0.47.2 → pyield-0.47.3}/.gitignore +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/LICENSE +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/_internal/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/_internal/br_numbers.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/_internal/cache.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/_internal/converters.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/_internal/data_cache.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/_internal/retry.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/_internal/types.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/anbima/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/anbima/ettj_intraday.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/anbima/ettj_last.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/anbima/ima.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/anbima/imaq.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/anbima/tpf.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/_contracts.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/_validar_pregao.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/derivatives_intraday.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/di1.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/di_over.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/futures/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/futures/common.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/futures/historical.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/b3/futures/intraday.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/auction.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/copom.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/ptax_api.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/rates.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/repo.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/trades_intraday.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/trades_monthly.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bc/vna.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bday/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bday/core.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bday/holidays/br_holidays_new.txt +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bday/holidays/br_holidays_old.txt +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/bday/holidays/brholidays.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/clock.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/fwd.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/interpolator.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/ipca/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/ipca/historical.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/ipca/projected.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/py.typed +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/rmd.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/selic/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/selic/cpm.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/selic/probabilities.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/__init__.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/auctions.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/benchmark.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/lft.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/ltn.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/ntnb.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/ntnb1.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/ntnbprinc.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/ntnc.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/ntnf.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/pre.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyield/tn/utils.py +0 -0
- {pyield-0.47.2 → pyield-0.47.3}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyield
|
|
3
|
-
Version: 0.47.
|
|
3
|
+
Version: 0.47.3
|
|
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
|
|
@@ -206,23 +206,22 @@ ntnf.di_spreads("30-05-2025", bps=True)
|
|
|
206
206
|
## Dados de Futuros
|
|
207
207
|
|
|
208
208
|
```python
|
|
209
|
-
from pyield import futures
|
|
209
|
+
from pyield import futures, futures_intraday
|
|
210
210
|
|
|
211
211
|
# DI1 (Futuro de Depósito Interfinanceiro)
|
|
212
212
|
futures("31-05-2024", "DI1")
|
|
213
213
|
|
|
214
|
-
# Outros contratos disponíveis:
|
|
215
|
-
# - Juros: DI1, DDI,
|
|
216
|
-
# - Moedas: DOL, WDO
|
|
217
|
-
# - Índices: IND, WIN
|
|
218
|
-
# - Commodities: BGI, CCM, ICF, CNL, SJC, SOY, ETH, GLD
|
|
214
|
+
# Outros contratos disponíveis no cache histórico:
|
|
215
|
+
# - Juros: DI1, DDI, FRC, FRO, DAP
|
|
216
|
+
# - Moedas: DOL, WDO
|
|
217
|
+
# - Índices: IND, WIN
|
|
219
218
|
futures("31-05-2024", "DAP")
|
|
220
219
|
|
|
221
|
-
#
|
|
222
|
-
futures("
|
|
220
|
+
# Múltiplas datas de uma vez
|
|
221
|
+
futures(["29-05-2024", "31-05-2024"], "DI1")
|
|
223
222
|
|
|
224
223
|
# Dados intradiários (quando o mercado estiver aberto)
|
|
225
|
-
|
|
224
|
+
futures_intraday("DI1") # Retorna dados ao vivo durante o horário de negociação
|
|
226
225
|
```
|
|
227
226
|
|
|
228
227
|
## Tratamento de Datas
|
|
@@ -162,23 +162,22 @@ ntnf.di_spreads("30-05-2025", bps=True)
|
|
|
162
162
|
## Dados de Futuros
|
|
163
163
|
|
|
164
164
|
```python
|
|
165
|
-
from pyield import futures
|
|
165
|
+
from pyield import futures, futures_intraday
|
|
166
166
|
|
|
167
167
|
# DI1 (Futuro de Depósito Interfinanceiro)
|
|
168
168
|
futures("31-05-2024", "DI1")
|
|
169
169
|
|
|
170
|
-
# Outros contratos disponíveis:
|
|
171
|
-
# - Juros: DI1, DDI,
|
|
172
|
-
# - Moedas: DOL, WDO
|
|
173
|
-
# - Índices: IND, WIN
|
|
174
|
-
# - Commodities: BGI, CCM, ICF, CNL, SJC, SOY, ETH, GLD
|
|
170
|
+
# Outros contratos disponíveis no cache histórico:
|
|
171
|
+
# - Juros: DI1, DDI, FRC, FRO, DAP
|
|
172
|
+
# - Moedas: DOL, WDO
|
|
173
|
+
# - Índices: IND, WIN
|
|
175
174
|
futures("31-05-2024", "DAP")
|
|
176
175
|
|
|
177
|
-
#
|
|
178
|
-
futures("
|
|
176
|
+
# Múltiplas datas de uma vez
|
|
177
|
+
futures(["29-05-2024", "31-05-2024"], "DI1")
|
|
179
178
|
|
|
180
179
|
# Dados intradiários (quando o mercado estiver aberto)
|
|
181
|
-
|
|
180
|
+
futures_intraday("DI1") # Retorna dados ao vivo durante o horário de negociação
|
|
182
181
|
```
|
|
183
182
|
|
|
184
183
|
## Tratamento de Datas
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.47.3"
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
import datetime as dt
|
|
2
2
|
import io
|
|
3
|
-
import logging
|
|
4
3
|
import zipfile
|
|
5
|
-
from functools import lru_cache
|
|
6
4
|
|
|
7
5
|
import polars as pl
|
|
8
6
|
import requests
|
|
9
7
|
from lxml import etree
|
|
10
|
-
from lxml.etree import _Element
|
|
11
8
|
|
|
12
9
|
import pyield._internal.converters as cv
|
|
10
|
+
from pyield._internal.cache import ttl_cache
|
|
13
11
|
from pyield._internal.retry import retry_padrao
|
|
14
12
|
from pyield._internal.types import DateLike, any_is_empty
|
|
15
13
|
from pyield.b3._contracts import normalizar_codigos_contrato
|
|
16
14
|
from pyield.b3._validar_pregao import data_negociacao_valida
|
|
17
15
|
|
|
18
|
-
registro = logging.getLogger(__name__)
|
|
19
|
-
|
|
20
16
|
# --- Constantes de Processamento XML ---
|
|
21
17
|
NAMESPACE_B3 = "urn:bvmf.217.01.xsd"
|
|
22
18
|
NAMESPACES = {"ns": NAMESPACE_B3}
|
|
23
19
|
# ZIP válido do price report ~2KB; 1KB detecta arquivos "sem dados"
|
|
24
20
|
MIN_TAMANHO_ZIP_BYTES = 1024
|
|
25
|
-
|
|
21
|
+
XPATH_TODOS_TICKERS = "//ns:TckrSymb"
|
|
26
22
|
XPATH_DATA_NEGOCIACAO = ".//ns:TradDt/ns:Dt"
|
|
27
23
|
XPATH_ATRIBUTOS_INSTRUMENTO = ".//ns:FinInstrmAttrbts"
|
|
28
24
|
XPATH_DETALHES_NEGOCIO = ".//ns:TradDtls"
|
|
@@ -74,10 +70,11 @@ COLUNAS_PRICE_REPORT: list[tuple[str, str, type[pl.DataType]]] = [
|
|
|
74
70
|
("5.32", "MinTradLmt", pl.Float64),
|
|
75
71
|
]
|
|
76
72
|
|
|
77
|
-
#
|
|
78
|
-
|
|
73
|
+
# Schema completo: nome_xml → tipo_polars. Garante ordem e tipagem constante.
|
|
74
|
+
SCHEMA_PRICE_REPORT = {nome: tipo for _, nome, tipo in COLUNAS_PRICE_REPORT}
|
|
79
75
|
|
|
80
76
|
|
|
77
|
+
@ttl_cache()
|
|
81
78
|
@retry_padrao
|
|
82
79
|
def _baixar_zip_url(data: dt.date, relatorio_completo: bool) -> bytes:
|
|
83
80
|
data_str = data.strftime("%y%m%d")
|
|
@@ -124,7 +121,7 @@ def price_report_extract(conteudo_zip: bytes) -> bytes:
|
|
|
124
121
|
return zip_interno.read(nomes_xml[-1])
|
|
125
122
|
|
|
126
123
|
|
|
127
|
-
def _extrair_dados_contrato(elemento_ticker: _Element) -> dict | None:
|
|
124
|
+
def _extrair_dados_contrato(elemento_ticker: etree._Element) -> dict | None:
|
|
128
125
|
if elemento_ticker.text is None:
|
|
129
126
|
return None
|
|
130
127
|
pai = elemento_ticker.getparent()
|
|
@@ -155,11 +152,7 @@ def _extrair_dados_contrato(elemento_ticker: _Element) -> dict | None:
|
|
|
155
152
|
return dados_ticker
|
|
156
153
|
|
|
157
154
|
|
|
158
|
-
def _parsear_xml_registros(
|
|
159
|
-
xml_bytes: bytes,
|
|
160
|
-
prefixo_ticker: str,
|
|
161
|
-
comprimento_ticker: int | None = None,
|
|
162
|
-
) -> list[dict]:
|
|
155
|
+
def _parsear_xml_registros(xml_bytes: bytes) -> list[dict]:
|
|
163
156
|
analisador = etree.XMLParser(
|
|
164
157
|
ns_clean=True,
|
|
165
158
|
remove_blank_text=True,
|
|
@@ -169,72 +162,70 @@ def _parsear_xml_registros(
|
|
|
169
162
|
no_network=True,
|
|
170
163
|
load_dtd=False,
|
|
171
164
|
)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if not isinstance(resultado_xpath, list):
|
|
177
|
-
return []
|
|
178
|
-
|
|
179
|
-
elementos_ticker = resultado_xpath
|
|
180
|
-
|
|
181
|
-
if not elementos_ticker:
|
|
165
|
+
arvore = etree.parse(io.BytesIO(xml_bytes), parser=analisador)
|
|
166
|
+
resultado_xpath = arvore.xpath(XPATH_TODOS_TICKERS, namespaces=NAMESPACES)
|
|
167
|
+
elementos: list[etree._Element] = resultado_xpath # type: ignore[assignment]
|
|
168
|
+
if not elementos:
|
|
182
169
|
return []
|
|
183
170
|
|
|
184
171
|
registros = []
|
|
185
|
-
for elemento in
|
|
186
|
-
if not isinstance(elemento, etree._Element):
|
|
187
|
-
continue
|
|
172
|
+
for elemento in elementos:
|
|
188
173
|
dados_contrato = _extrair_dados_contrato(elemento)
|
|
189
174
|
if dados_contrato is not None:
|
|
190
|
-
|
|
191
|
-
if comprimento_ticker is None or len(ticker) == comprimento_ticker:
|
|
192
|
-
registros.append(dados_contrato)
|
|
175
|
+
registros.append(dados_contrato)
|
|
193
176
|
return registros
|
|
194
177
|
|
|
195
178
|
|
|
196
179
|
def _converter_para_df(registros: list[dict]) -> pl.DataFrame:
|
|
197
180
|
df = pl.DataFrame(registros)
|
|
198
181
|
# Casting usa os nomes originais do XML, que são constantes
|
|
199
|
-
tipos_coluna = {k: v for k, v in
|
|
200
|
-
|
|
182
|
+
tipos_coluna = {k: v for k, v in SCHEMA_PRICE_REPORT.items() if k in df.columns}
|
|
183
|
+
df = df.cast(tipos_coluna, strict=False) # type: ignore
|
|
184
|
+
# Adiciona colunas ausentes com null e garante ordem/schema constante
|
|
185
|
+
colunas_faltantes = {
|
|
186
|
+
nome: pl.lit(None).cast(tipo)
|
|
187
|
+
for nome, tipo in SCHEMA_PRICE_REPORT.items()
|
|
188
|
+
if nome not in df.columns
|
|
189
|
+
}
|
|
190
|
+
if colunas_faltantes:
|
|
191
|
+
df = df.with_columns(**colunas_faltantes)
|
|
192
|
+
return df.select(SCHEMA_PRICE_REPORT.keys())
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _processar_xml_extraido(xml_bytes: bytes) -> pl.DataFrame:
|
|
196
|
+
registros = _parsear_xml_registros(xml_bytes)
|
|
197
|
+
if not registros:
|
|
198
|
+
return pl.DataFrame()
|
|
199
|
+
return _converter_para_df(registros).sort("TckrSymb")
|
|
201
200
|
|
|
202
201
|
|
|
203
|
-
def
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
def _filtrar_df(
|
|
203
|
+
df: pl.DataFrame,
|
|
204
|
+
prefixos: list[str],
|
|
206
205
|
comprimento_ticker: int | None = None,
|
|
207
206
|
) -> pl.DataFrame:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if xml_bytes
|
|
211
|
-
else []
|
|
212
|
-
)
|
|
213
|
-
if not registros:
|
|
214
|
-
return pl.DataFrame()
|
|
207
|
+
if comprimento_ticker:
|
|
208
|
+
df = df.filter(pl.col("TckrSymb").str.len_chars() == comprimento_ticker)
|
|
215
209
|
|
|
216
|
-
|
|
210
|
+
if prefixos:
|
|
211
|
+
filtro = pl.any_horizontal(
|
|
212
|
+
pl.col("TckrSymb").str.starts_with(p) for p in prefixos
|
|
213
|
+
)
|
|
214
|
+
df = df.filter(filtro)
|
|
217
215
|
return df.sort("TckrSymb")
|
|
218
216
|
|
|
219
217
|
|
|
220
|
-
|
|
221
|
-
def _obter_xml_price_report(data: dt.date, relatorio_completo: bool) -> bytes:
|
|
218
|
+
def _obter_df_price_report(data: dt.date, relatorio_completo: bool) -> pl.DataFrame:
|
|
222
219
|
dados_zip = _baixar_zip_url(data, relatorio_completo)
|
|
223
220
|
if not dados_zip:
|
|
224
|
-
return
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
except zipfile.BadZipFile:
|
|
228
|
-
registro.warning("ZIP corrompido na transmissão, re-baixando...")
|
|
229
|
-
dados_zip = _baixar_zip_url(data, relatorio_completo)
|
|
230
|
-
if not dados_zip:
|
|
231
|
-
return bytes()
|
|
232
|
-
return price_report_extract(dados_zip)
|
|
221
|
+
return pl.DataFrame()
|
|
222
|
+
xml_bytes = price_report_extract(dados_zip)
|
|
223
|
+
return _processar_xml_extraido(xml_bytes)
|
|
233
224
|
|
|
234
225
|
|
|
235
226
|
def price_report_fetch(
|
|
236
227
|
date: DateLike,
|
|
237
|
-
ticker_prefix: str | list[str],
|
|
228
|
+
ticker_prefix: str | list[str] | None = None,
|
|
238
229
|
ticker_length: int | None = None,
|
|
239
230
|
full_report: bool = False,
|
|
240
231
|
) -> pl.DataFrame:
|
|
@@ -259,7 +250,8 @@ def price_report_fetch(
|
|
|
259
250
|
'YYYY-MM-DD' ou objeto datetime.date.
|
|
260
251
|
ticker_prefix: Prefixo do ticker B3 (ex.: 'DI1', 'DOL',
|
|
261
252
|
'CPM') ou lista de prefixos (ex.: ['DI1', 'DAP']).
|
|
262
|
-
Usado como filtro starts-with no XML.
|
|
253
|
+
Usado como filtro starts-with no XML. Se None (padrão),
|
|
254
|
+
retorna todos os ativos sem filtro.
|
|
263
255
|
ticker_length: Comprimento exato do ticker para filtrar registros.
|
|
264
256
|
Se None (padrão), retorna todos os tickers que casam com o
|
|
265
257
|
prefixo (ex.: 6 para futuros, 13 para opções).
|
|
@@ -333,8 +325,7 @@ def price_report_fetch(
|
|
|
333
325
|
>>> df.is_empty()
|
|
334
326
|
True
|
|
335
327
|
"""
|
|
336
|
-
|
|
337
|
-
if any_is_empty(date) or not prefixos:
|
|
328
|
+
if any_is_empty(date):
|
|
338
329
|
return pl.DataFrame()
|
|
339
330
|
|
|
340
331
|
date = cv.converter_datas(date)
|
|
@@ -342,20 +333,19 @@ def price_report_fetch(
|
|
|
342
333
|
if not data_negociacao_valida(date):
|
|
343
334
|
return pl.DataFrame()
|
|
344
335
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if not dataframes:
|
|
336
|
+
df = _obter_df_price_report(date, full_report)
|
|
337
|
+
if df.is_empty() or ticker_prefix is None:
|
|
338
|
+
return df
|
|
339
|
+
|
|
340
|
+
prefixos = normalizar_codigos_contrato(ticker_prefix)
|
|
341
|
+
if not prefixos:
|
|
352
342
|
return pl.DataFrame()
|
|
353
|
-
return
|
|
343
|
+
return _filtrar_df(df, prefixos, ticker_length)
|
|
354
344
|
|
|
355
345
|
|
|
356
346
|
def price_report_read(
|
|
357
347
|
xml_bytes: bytes,
|
|
358
|
-
ticker_prefix: str | list[str],
|
|
348
|
+
ticker_prefix: str | list[str] | None = None,
|
|
359
349
|
ticker_length: int | None = None,
|
|
360
350
|
) -> pl.DataFrame:
|
|
361
351
|
"""Lê e processa o price report da B3 a partir do conteúdo XML bruto.
|
|
@@ -367,6 +357,7 @@ def price_report_read(
|
|
|
367
357
|
xml_bytes: Conteúdo do XML em bytes (já descomprimido).
|
|
368
358
|
ticker_prefix: Prefixo do ticker B3 (ex.: 'DI1', 'DOL',
|
|
369
359
|
'CPM') ou lista de prefixos (ex.: ['DI1', 'DAP']).
|
|
360
|
+
Se None (padrão), retorna todos os ativos sem filtro.
|
|
370
361
|
ticker_length: Comprimento exato do ticker para filtrar registros.
|
|
371
362
|
Se None (padrão), retorna todos os tickers que casam com o
|
|
372
363
|
prefixo.
|
|
@@ -375,15 +366,14 @@ def price_report_read(
|
|
|
375
366
|
pl.DataFrame: DataFrame com as mesmas colunas documentadas em
|
|
376
367
|
:func:`price_report_fetch`.
|
|
377
368
|
"""
|
|
378
|
-
|
|
379
|
-
if any_is_empty(xml_bytes) or not prefixos:
|
|
369
|
+
if any_is_empty(xml_bytes):
|
|
380
370
|
return pl.DataFrame()
|
|
381
371
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
df
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if not
|
|
372
|
+
df = _processar_xml_extraido(xml_bytes)
|
|
373
|
+
if df.is_empty() or ticker_prefix is None:
|
|
374
|
+
return df
|
|
375
|
+
|
|
376
|
+
prefixos = normalizar_codigos_contrato(ticker_prefix)
|
|
377
|
+
if not prefixos:
|
|
388
378
|
return pl.DataFrame()
|
|
389
|
-
return
|
|
379
|
+
return _filtrar_df(df, prefixos, ticker_length)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.47.2"
|
|
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
|
|
File without changes
|