PYield 0.36.0__tar.gz → 0.36.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.
- {pyield-0.36.0 → pyield-0.36.2}/.gitignore +3 -1
- {pyield-0.36.0 → pyield-0.36.2}/PKG-INFO +1 -1
- pyield-0.36.2/pyield/__about__.py +1 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/anbima/imaq.py +9 -2
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/auction.py +72 -29
- pyield-0.36.2/pyield/tn/__init__.py +3 -0
- pyield-0.36.0/pyield/tn/auction.py → pyield-0.36.2/pyield/tn/benchmark.py +17 -11
- {pyield-0.36.0 → pyield-0.36.2}/pyproject.toml +4 -19
- pyield-0.36.0/pyield/__about__.py +0 -1
- pyield-0.36.0/pyield/tn/__init__.py +0 -3
- {pyield-0.36.0 → pyield-0.36.2}/LICENSE +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/README.md +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/__init__.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/anbima/__init__.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/anbima/ettj.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/anbima/ima.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/anbima/ipca.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/anbima/tpf.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/__init__.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/di1.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/di_over.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/futures/__init__.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/futures/common.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/futures/historical.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/futures/intraday.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/b3/futures/xml.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/__init__.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/bcdata.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/ptax.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/repo.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/trades_intraday.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/trades_monthly.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bc/vna.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/bday.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/conftest.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/data_cache.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/date_converter.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/fwd.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/holidays/__init__.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/holidays/br_holidays_new.txt +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/holidays/br_holidays_old.txt +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/holidays/brholidays.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/ibge/__init__.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/ibge/ipca.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/interpolator.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/py.typed +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/retry.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/tn/lft.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/tn/ltn.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/tn/ntnb.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/tn/ntnc.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/tn/ntnf.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/tn/pre.py +0 -0
- {pyield-0.36.0 → pyield-0.36.2}/pyield/tn/tools.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.36.2"
|
|
@@ -60,6 +60,7 @@ def _fetch_url_tables(target_date: pd.Timestamp) -> pd.DataFrame:
|
|
|
60
60
|
decimal=",",
|
|
61
61
|
displayed_only=True,
|
|
62
62
|
dtype_backend="numpy_nullable",
|
|
63
|
+
na_values="--",
|
|
63
64
|
)
|
|
64
65
|
|
|
65
66
|
df = (
|
|
@@ -95,9 +96,15 @@ def _fetch_url_tables(target_date: pd.Timestamp) -> pd.DataFrame:
|
|
|
95
96
|
def _process_df(df: pd.DataFrame) -> pd.DataFrame:
|
|
96
97
|
df = df.rename(columns=COLUMN_MAPPING)[COLUMN_MAPPING.values()]
|
|
97
98
|
df["Maturity"] = pd.to_datetime(df["Maturity"], format="%d/%m/%Y")
|
|
98
|
-
|
|
99
|
+
|
|
99
100
|
for col in ["MarketQuantity", "MarketValue", "QuantityVariation"]:
|
|
100
|
-
|
|
101
|
+
# Fallback to string conversion in case conversion failed during read_csv
|
|
102
|
+
if df[col].dtype == "string" or df[col].dtype == "object":
|
|
103
|
+
df[col] = df[col].str.replace(".", "", regex=False).replace(",", ".")
|
|
104
|
+
df[col] = pd.to_numeric(df[col], errors="coerce")
|
|
105
|
+
|
|
106
|
+
# Remove the thousands unit from numeric columns
|
|
107
|
+
df[col] *= (1000 * df[col]).astype("Int64")
|
|
101
108
|
|
|
102
109
|
return df
|
|
103
110
|
|
|
@@ -14,6 +14,7 @@ import requests
|
|
|
14
14
|
|
|
15
15
|
from pyield import bday
|
|
16
16
|
from pyield import date_converter as dc
|
|
17
|
+
from pyield.bc import ptax
|
|
17
18
|
from pyield.date_converter import DateScalar
|
|
18
19
|
from pyield.retry import default_retry
|
|
19
20
|
from pyield.tn.ntnb import duration as duration_b
|
|
@@ -176,7 +177,7 @@ def _add_dv01(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
176
177
|
df["DV01SR"] = dv01 * df["AcceptedQuantitySR"]
|
|
177
178
|
|
|
178
179
|
for col in ["DV01", "DV01FR", "DV01SR"]:
|
|
179
|
-
#
|
|
180
|
+
# Definrir DV01 nulos do leilão como 0
|
|
180
181
|
df[col] = df[col].fillna(0).round(2)
|
|
181
182
|
|
|
182
183
|
# Forçar 0 nas LFT, pois não há DV01
|
|
@@ -185,6 +186,24 @@ def _add_dv01(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
185
186
|
return df
|
|
186
187
|
|
|
187
188
|
|
|
189
|
+
def _get_ptax_df(start_date: pd.Timestamp | None = None) -> pd.DataFrame:
|
|
190
|
+
# A série de leilões começa em 2007
|
|
191
|
+
df = ptax.ptax_series(start=start_date)[["Date", "MidRate"]]
|
|
192
|
+
df = df.rename(columns={"MidRate": "PTAX"})
|
|
193
|
+
return df
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _add_usd_dv01(df: pd.DataFrame) -> pd.DataFrame:
|
|
197
|
+
ptax_start_date = df["Date"].min()
|
|
198
|
+
df_ptax = _get_ptax_df(start_date=ptax_start_date)
|
|
199
|
+
df = pd.merge_asof(left=df, right=df_ptax)
|
|
200
|
+
dv01_cols = [c for c in df.columns if c.startswith("DV01")]
|
|
201
|
+
for col in dv01_cols:
|
|
202
|
+
df[f"{col}USD"] = df[col] / df["PTAX"]
|
|
203
|
+
|
|
204
|
+
return df.drop(columns=["PTAX"])
|
|
205
|
+
|
|
206
|
+
|
|
188
207
|
def _add_avg_maturity(df: pd.DataFrame) -> pd.DataFrame:
|
|
189
208
|
# Na metodolgia do Tesouro Nacional, a maturidade média é a mesma que a duração
|
|
190
209
|
df["AvgMaturity"] = df["Duration"]
|
|
@@ -221,6 +240,9 @@ def _sort_and_reorder_columns(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
221
240
|
"DV01",
|
|
222
241
|
"DV01FR",
|
|
223
242
|
"DV01SR",
|
|
243
|
+
"DV01USD",
|
|
244
|
+
"DV01FRUSD",
|
|
245
|
+
"DV01SRUSD",
|
|
224
246
|
"AvgPrice",
|
|
225
247
|
"CutPrice",
|
|
226
248
|
"AvgRate",
|
|
@@ -242,6 +264,7 @@ def _fetch_df_from_url(url: str) -> pd.DataFrame:
|
|
|
242
264
|
df = _process_df(df)
|
|
243
265
|
df = _add_duration(df)
|
|
244
266
|
df = _add_dv01(df)
|
|
267
|
+
df = _add_usd_dv01(df)
|
|
245
268
|
df = _add_avg_maturity(df)
|
|
246
269
|
df = _sort_and_reorder_columns(df)
|
|
247
270
|
return df
|
|
@@ -304,38 +327,57 @@ def auctions(
|
|
|
304
327
|
especificados. Em caso de erro ao buscar os dados, um DataFrame vazio
|
|
305
328
|
é retornado e uma mensagem de erro é registrada no log.
|
|
306
329
|
|
|
330
|
+
Examples:
|
|
331
|
+
>>> import pandas as pd
|
|
332
|
+
>>> from pyield import bc
|
|
333
|
+
>>> df = bc.auctions(start="03-06-2025", end="03-06-2025")
|
|
334
|
+
>>> df
|
|
335
|
+
Date Settlement AuctionType ... CutPrice AvgRate CutRate
|
|
336
|
+
0 2025-06-03 2025-06-04 Venda ... 16653.010815 0.000589 0.000589
|
|
337
|
+
1 2025-06-03 2025-06-04 Venda ... 16572.063672 0.00109 0.00109
|
|
338
|
+
2 2025-06-03 2025-06-04 Venda ... 4314.142451 0.07569 0.07569
|
|
339
|
+
3 2025-06-03 2025-06-04 Venda ... 4140.47255 0.07312 0.07312
|
|
340
|
+
4 2025-06-03 2025-06-04 Venda ... 3960.619508 0.07157 0.07157
|
|
341
|
+
...
|
|
342
|
+
|
|
307
343
|
Notes:
|
|
308
344
|
FR = First Round (Primeira Rodada)
|
|
345
|
+
|
|
309
346
|
SR = Second Round (Segunda Rodada)
|
|
310
347
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
348
|
+
DataFrame Columns:
|
|
349
|
+
- Date: Data do leilão.
|
|
350
|
+
- Settlement: Data de liquidação do leilão.
|
|
351
|
+
- AuctionType: Tipo de leilão (ex: "Sell" ou "Buy").
|
|
352
|
+
- Ordinance: Edital normativo associado ao leilão.
|
|
353
|
+
- Buyer: Categoria do comprador (ex: "TodoMercado", "SomenteDealerApto").
|
|
354
|
+
- BondType: Categoria do título (ex: "LTN", "LFT", "NTN-B", "NTN-F").
|
|
355
|
+
- SelicCode: Código do título no sistema Selic.
|
|
356
|
+
- Maturity: Data de vencimento do título.
|
|
357
|
+
- DV01: Valor do DV01 total do leilão em R$.
|
|
358
|
+
- DV01FR: DV01 da Primeira Rodada (FR) em R$.
|
|
359
|
+
- DV01SR: DV01 da Segunda Rodada (SR) em R$.
|
|
360
|
+
- DV01USD: DV01 total do leilão em dólares (USD).
|
|
361
|
+
- DV01FRUSD: DV01 da Primeira Rodada (FR) em dólares (USD).
|
|
362
|
+
- DV01SRUSD: DV01 da Segunda Rodada (SR) em dólares (USD).
|
|
363
|
+
- AvgMaturity: Maturidade média do título (em anos).
|
|
364
|
+
- Value: Valor total do leilão em R$ (FR + SR).
|
|
365
|
+
- ValueFR: Valor da primeira rodada (FR) do leilão em R$.
|
|
366
|
+
- ValueSR: Valor da segunda rodada (SR) em R$.
|
|
367
|
+
- OfferedQuantity: Quantidade total ofertada no leilão (FR + SR).
|
|
368
|
+
- OfferedQuantityFR: Quantidade ofertada na primeira rodada (FR).
|
|
369
|
+
- OfferedQuantitySR: Quantidade ofertada na segunda rodada (SR).
|
|
370
|
+
- AcceptedQuantity: Quantidade total aceita no leilão (FR + SR).
|
|
371
|
+
- AcceptedQuantityFR: Quantidade aceita na primeira rodada (FR).
|
|
372
|
+
- AcceptedQuantitySR: Quantidade aceita na segunda rodada (SR).
|
|
373
|
+
- AvgPrice: Preço médio no leilão.
|
|
374
|
+
- CutPrice: Preço de corte.
|
|
375
|
+
- AvgRate: Taxa de juros média.
|
|
376
|
+
- CutRate: Taxa de corte.
|
|
377
|
+
- BDToMat: Dias úteis entre a data de liquidação da 1R e a data de
|
|
378
|
+
vencimento do título.
|
|
379
|
+
- Duration: Duration (Duração) calculada com base na data de
|
|
380
|
+
liquidação da 1R e na data de vencimento do título.
|
|
339
381
|
"""
|
|
340
382
|
url = BASE_API_URL
|
|
341
383
|
if start:
|
|
@@ -351,6 +393,7 @@ def auctions(
|
|
|
351
393
|
# Mapeamento do auction_type para o valor esperado pela API
|
|
352
394
|
auction_type_mapping = {"sell": "Venda", "buy": "Compra"}
|
|
353
395
|
if auction_type:
|
|
396
|
+
auction_type = str(auction_type).lower()
|
|
354
397
|
auction_type_api_value = auction_type_mapping[auction_type]
|
|
355
398
|
# Adiciona o parâmetro tipoOferta à URL se auction_type for fornecido
|
|
356
399
|
url += f"&@tipoOferta='{auction_type_api_value}'"
|
|
@@ -9,12 +9,12 @@ logger = logging.getLogger(__name__)
|
|
|
9
9
|
|
|
10
10
|
TIMEZONE_BZ = ZoneInfo("America/Sao_Paulo")
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
"BENCHMARK": "Benchmark",
|
|
14
|
-
"VENCIMENTO": "MaturityDate",
|
|
15
|
-
"TÍTULO": "BondType",
|
|
12
|
+
COLUMN_MAPPING = {
|
|
16
13
|
"INÍCIO": "StartDate",
|
|
17
14
|
"TERMINO": "EndDate",
|
|
15
|
+
"TÍTULO": "BondType",
|
|
16
|
+
"VENCIMENTO": "MaturityDate",
|
|
17
|
+
"BENCHMARK": "Benchmark",
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
|
|
@@ -61,12 +61,12 @@ def benchmarks(include_history: bool = False) -> pd.DataFrame:
|
|
|
61
61
|
>>> # Get historical benchmarks
|
|
62
62
|
>>> df_history = tn.benchmarks(include_history=True)
|
|
63
63
|
>>> df_history.head()
|
|
64
|
-
|
|
65
|
-
0
|
|
66
|
-
1
|
|
67
|
-
2
|
|
68
|
-
3
|
|
69
|
-
4
|
|
64
|
+
StartDate EndDate BondType MaturityDate Benchmark
|
|
65
|
+
0 2014-01-01 2014-06-30 LFT 2020-03-01 LFT 6 anos
|
|
66
|
+
1 2014-01-01 2014-06-01 LTN 2014-10-01 LTN 6 meses
|
|
67
|
+
2 2014-01-01 2014-06-30 LTN 2015-04-01 LTN 12 meses
|
|
68
|
+
3 2014-01-01 2014-06-30 LTN 2016-04-01 LTN 24 meses
|
|
69
|
+
4 2014-01-01 2014-06-30 LTN 2018-01-01 LTN 48 meses
|
|
70
70
|
"""
|
|
71
71
|
session = requests.Session()
|
|
72
72
|
include_history_param_value = "S" if include_history else "N"
|
|
@@ -127,4 +127,10 @@ def benchmarks(include_history: bool = False) -> pd.DataFrame:
|
|
|
127
127
|
"No current benchmark data found after filtering by active period."
|
|
128
128
|
)
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
column_order = [c for c in COLUMN_MAPPING if c in df.columns]
|
|
131
|
+
return (
|
|
132
|
+
df[column_order]
|
|
133
|
+
.rename(columns=COLUMN_MAPPING)
|
|
134
|
+
.sort_values(["StartDate", "BondType", "MaturityDate"])
|
|
135
|
+
.reset_index(drop=True)
|
|
136
|
+
)
|
|
@@ -15,7 +15,7 @@ classifiers = [
|
|
|
15
15
|
]
|
|
16
16
|
dependencies = [
|
|
17
17
|
"pandas[html, parquet]>=2.0.0",
|
|
18
|
-
"numpy>=2.0.0",
|
|
18
|
+
"numpy>=2.0.0",
|
|
19
19
|
"requests>=2.31.0",
|
|
20
20
|
"tenacity>=9.0.0",
|
|
21
21
|
]
|
|
@@ -32,8 +32,8 @@ dev = [
|
|
|
32
32
|
"mkdocs",
|
|
33
33
|
"mkdocs-material",
|
|
34
34
|
"mkdocstrings[python]",
|
|
35
|
-
"mkdocs-autorefs",
|
|
36
|
-
"types-requests",
|
|
35
|
+
"mkdocs-autorefs",
|
|
36
|
+
"types-requests",
|
|
37
37
|
"pandas-stubs",
|
|
38
38
|
"lxml-stubs",
|
|
39
39
|
"ruff",
|
|
@@ -50,19 +50,4 @@ path = "pyield/__about__.py"
|
|
|
50
50
|
only-include = ["pyield"]
|
|
51
51
|
|
|
52
52
|
[tool.uv]
|
|
53
|
-
package = true
|
|
54
|
-
|
|
55
|
-
[tool.ruff]
|
|
56
|
-
line-length = 88
|
|
57
|
-
indent-width = 4
|
|
58
|
-
target-version = "py312"
|
|
59
|
-
extend-include = ["*.ipynb"]
|
|
60
|
-
|
|
61
|
-
[tool.ruff.lint]
|
|
62
|
-
preview = true
|
|
63
|
-
select = ["I", "F", "E", "W", "PL", "PT"]
|
|
64
|
-
|
|
65
|
-
[tool.ruff.format]
|
|
66
|
-
docstring-code-format = true
|
|
67
|
-
docstring-code-line-length = 88
|
|
68
|
-
|
|
53
|
+
package = true
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.36.0"
|
|
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
|