PYield 0.3.2__tar.gz → 0.3.4__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.3.2 → pyield-0.3.4}/PKG-INFO +1 -1
- pyield-0.3.4/pyield/__about__.py +1 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/__init__.py +1 -0
- pyield-0.3.4/pyield/anbima.py +155 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyproject.toml +1 -1
- pyield-0.3.2/pyield/__about__.py +0 -1
- {pyield-0.3.2 → pyield-0.3.4}/LICENSE +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/README.md +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/br_calendar.py +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/br_holidays.py +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/br_holidays_new.txt +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/br_holidays_old.txt +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/di_futures.py +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/di_web.py +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/pyield/di_xml.py +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/tests/__init__.py +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/tests/test_br_calendar.py +0 -0
- {pyield-0.3.2 → pyield-0.3.4}/tests/test_di.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.4"
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from urllib.error import HTTPError
|
|
3
|
+
|
|
4
|
+
from . import di_futures as di
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def process_reference_date(
|
|
8
|
+
reference_date: str | pd.Timestamp | None = None,
|
|
9
|
+
) -> pd.Timestamp:
|
|
10
|
+
if reference_date:
|
|
11
|
+
# Force reference_date to be a pd.Timestamp
|
|
12
|
+
reference_date = pd.Timestamp(reference_date)
|
|
13
|
+
else: # If no reference_date is given, use yesterday's date
|
|
14
|
+
today = pd.Timestamp.today().date()
|
|
15
|
+
yesterday = today - pd.Timedelta(days=1)
|
|
16
|
+
reference_date = yesterday
|
|
17
|
+
|
|
18
|
+
return reference_date
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_raw_data(reference_date: pd.Timestamp, anbima_member: bool) -> pd.DataFrame:
|
|
22
|
+
"""
|
|
23
|
+
Fetch indicative rates from ANBIMA for a specific date.
|
|
24
|
+
|
|
25
|
+
Parameters:
|
|
26
|
+
- reference_date: pd.Timestamp for which to fetch the indicative rates.
|
|
27
|
+
If None, fetches yesterday's rates.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
- A pandas DataFrame with the indicative rates for the given date.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
# Example URL: https://www.anbima.com.br/informacoes/merc-sec/arqs/ms231128.txt
|
|
34
|
+
url_date = reference_date.strftime("%y%m%d")
|
|
35
|
+
if anbima_member:
|
|
36
|
+
url = f"http://www.anbima.associados.rtm/merc_sec/arqs/ms{url_date}.txt"
|
|
37
|
+
else:
|
|
38
|
+
url = f"https://www.anbima.com.br/informacoes/merc-sec/arqs/ms{url_date}.txt"
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
df = pd.read_csv(
|
|
42
|
+
url,
|
|
43
|
+
sep="@",
|
|
44
|
+
encoding="latin-1",
|
|
45
|
+
skiprows=2,
|
|
46
|
+
decimal=",",
|
|
47
|
+
thousands=".",
|
|
48
|
+
dtype_backend="numpy_nullable",
|
|
49
|
+
)
|
|
50
|
+
except HTTPError:
|
|
51
|
+
error_date = reference_date.strftime("%d-%m-%Y")
|
|
52
|
+
raise ValueError(f"Failed to get ANBIMA rates for {error_date}")
|
|
53
|
+
|
|
54
|
+
return df
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def process_raw_data(df: pd.DataFrame) -> pd.DataFrame:
|
|
58
|
+
# Filter selected columns and rename them
|
|
59
|
+
selected_columns_dict = {
|
|
60
|
+
"Titulo": "BondType",
|
|
61
|
+
"Data Referencia": "ReferenceDate",
|
|
62
|
+
# "Codigo SELIC": "SelicCode",
|
|
63
|
+
# "Data Base/Emissao": "IssueBaseDate",
|
|
64
|
+
"Data Vencimento": "MaturityDate",
|
|
65
|
+
"Tx. Compra": "BidRate",
|
|
66
|
+
"Tx. Venda": "AskRate",
|
|
67
|
+
"Tx. Indicativas": "IndicativeRate",
|
|
68
|
+
"PU": "Price",
|
|
69
|
+
# "Desvio padrao": "StdDev",
|
|
70
|
+
# "Interv. Ind. Inf. (D0)",
|
|
71
|
+
# "Interv. Ind. Sup. (D0)",
|
|
72
|
+
# "Interv. Ind. Inf. (D+1)",
|
|
73
|
+
# "Interv. Ind. Sup. (D+1)",
|
|
74
|
+
# "Criterio": "Criteria",
|
|
75
|
+
}
|
|
76
|
+
select_columns = list(selected_columns_dict.keys())
|
|
77
|
+
df = df[select_columns].copy()
|
|
78
|
+
df.rename(columns=selected_columns_dict, inplace=True)
|
|
79
|
+
|
|
80
|
+
# Remove percentage from rates
|
|
81
|
+
rate_cols = ["BidRate", "AskRate", "IndicativeRate"]
|
|
82
|
+
df[rate_cols] = df[rate_cols] / 100
|
|
83
|
+
|
|
84
|
+
df["ReferenceDate"] = pd.to_datetime(df["ReferenceDate"], format="%Y%m%d")
|
|
85
|
+
df["MaturityDate"] = pd.to_datetime(df["MaturityDate"], format="%Y%m%d")
|
|
86
|
+
|
|
87
|
+
return df.sort_values(["BondType", "MaturityDate"], ignore_index=True)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def get_anbima_rates(
|
|
91
|
+
reference_date: str | pd.Timestamp | None = None,
|
|
92
|
+
return_raw=False,
|
|
93
|
+
anbima_member=False,
|
|
94
|
+
) -> pd.DataFrame:
|
|
95
|
+
"""
|
|
96
|
+
Fetch indicative rates from ANBIMA for a specific date.
|
|
97
|
+
|
|
98
|
+
Parameters:
|
|
99
|
+
- reference_date: pd.Timestamp for which to fetch the indicative rates.
|
|
100
|
+
If None, fetches yesterday's rates.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
- A pandas DataFrame with the indicative rates for the given date.
|
|
104
|
+
"""
|
|
105
|
+
reference_date = process_reference_date(reference_date)
|
|
106
|
+
df = get_raw_data(reference_date, anbima_member)
|
|
107
|
+
|
|
108
|
+
if return_raw:
|
|
109
|
+
return df
|
|
110
|
+
else:
|
|
111
|
+
return process_raw_data(df)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_anbima_di_spreads(
|
|
115
|
+
reference_date: str | pd.Timestamp | None = None,
|
|
116
|
+
anbima_member=False,
|
|
117
|
+
) -> pd.DataFrame:
|
|
118
|
+
"""
|
|
119
|
+
Calcula o prêmio (spread) com relação ao DI nas taxas indicativas da ANBIMA para os títulos LTN e NTN-F.
|
|
120
|
+
A coluna DISpread contém o prêmio em bps.
|
|
121
|
+
|
|
122
|
+
Parâmetros:
|
|
123
|
+
-----------
|
|
124
|
+
data_consulta : pd.Timestamp
|
|
125
|
+
A data de referência para a consulta das taxas indicativas da ANBIMA.
|
|
126
|
+
"""
|
|
127
|
+
reference_date = process_reference_date(reference_date)
|
|
128
|
+
|
|
129
|
+
df_di = di.get_di(reference_date)[["ExpirationDate", "SettlementRate"]]
|
|
130
|
+
|
|
131
|
+
df_di.rename(columns={"ExpirationDate": "MaturityDate"}, inplace=True)
|
|
132
|
+
|
|
133
|
+
# Ajustar o vencimento para o primeiro dia do mês para concidir com o formato dos títulos
|
|
134
|
+
df_di["MaturityDate"] = df_di["MaturityDate"].dt.to_period("M").dt.to_timestamp()
|
|
135
|
+
|
|
136
|
+
df_anb = get_anbima_rates(
|
|
137
|
+
reference_date=reference_date, anbima_member=anbima_member
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Filtrar apenas os títulos LTN e NTN-F
|
|
141
|
+
df_anb.query("BondType in ['LTN', 'NTN-F']", inplace=True)
|
|
142
|
+
|
|
143
|
+
# Unir os dois DataFrames
|
|
144
|
+
df = pd.merge(df_anb, df_di, how="left", on="MaturityDate")
|
|
145
|
+
|
|
146
|
+
# Calcular o prêmio implícito na taxa da ANBIMA
|
|
147
|
+
df["DISpread"] = df["IndicativeRate"] - df["SettlementRate"]
|
|
148
|
+
df.drop(columns="SettlementRate", inplace=True)
|
|
149
|
+
|
|
150
|
+
# Converter o prêmio para bps e arredondar para 2 casas decimais
|
|
151
|
+
df["DISpread"] = (10_000 * df["DISpread"]).round(2)
|
|
152
|
+
|
|
153
|
+
select_columns = ["BondType", "ReferenceDate", "MaturityDate", "DISpread"]
|
|
154
|
+
df = df[select_columns]
|
|
155
|
+
return df.sort_values(["BondType", "MaturityDate"], ignore_index=True)
|
pyield-0.3.2/pyield/__about__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.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
|