PYield 0.3.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PYield
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A Python library for analysis of fixed income instruments in Brazil
5
5
  Keywords: fixed-income, brazil, finance, analysis, bonds
6
6
  Author-Email: Carlos Carvalho <cr.cj@outlook.com>
@@ -0,0 +1 @@
1
+ __version__ = "0.3.4"
@@ -1,4 +1,4 @@
1
1
  from .__about__ import __version__ # noqa: F401
2
2
  from .di_futures import get_di, read_di # noqa: F401
3
3
  from .br_calendar import count_bdays, generate_bdays, offset_bdays # noqa: F401
4
- from .anbima import get_anbima_rates # noqa: F401
4
+ from .anbima import get_anbima_rates, get_anbima_di_spreads # noqa: F401
@@ -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)
@@ -31,7 +31,7 @@ dependencies = [
31
31
  "lxml",
32
32
  ]
33
33
  dynamic = []
34
- version = "0.3.3"
34
+ version = "0.3.4"
35
35
 
36
36
  [project.license]
37
37
  file = "LICENSE"
@@ -1 +0,0 @@
1
- __version__ = "0.3.3"
@@ -1,48 +0,0 @@
1
- import pandas as pd
2
- from urllib.error import HTTPError
3
-
4
-
5
- def get_anbima_rates(reference_date: str | pd.Timestamp | None = None) -> pd.DataFrame:
6
- """
7
- Fetch indicative rates from ANBIMA for a specific date.
8
-
9
- Parameters:
10
- - reference_date: pd.Timestamp for which to fetch the indicative rates.
11
- If None, fetches yesterday's rates.
12
-
13
- Returns:
14
- - A pandas DataFrame with the indicative rates for the given date.
15
- """
16
- if reference_date:
17
- # Force reference_date to be a pd.Timestamp
18
- reference_date = pd.Timestamp(reference_date)
19
- else: # If no reference_date is given, use yesterday's date
20
- today = pd.Timestamp.today().date()
21
- yesterday = today - pd.Timedelta(days=1)
22
- reference_date = yesterday
23
-
24
- # Example URL: https://www.anbima.com.br/informacoes/merc-sec/arqs/ms231128.txt
25
- url_date = reference_date.strftime("%y%m%d")
26
- url = f"https://www.anbima.com.br/informacoes/merc-sec/arqs/ms{url_date}.txt"
27
-
28
- try:
29
- df = pd.read_csv(
30
- url, sep="@", encoding="latin1", skiprows=2, decimal=",", thousands="."
31
- )
32
- except HTTPError:
33
- error_date = reference_date.strftime("%d/%m/%Y")
34
- raise ValueError(f"Failed to get ANBIMA rates for {error_date}")
35
-
36
- # Filter selected columns and rename them
37
- selected_columns_dict = {
38
- "Titulo": "BondType",
39
- "Data Vencimento": "MaturityDate",
40
- "Tx. Indicativas": "IndicativeRate",
41
- }
42
- df = df[list(selected_columns_dict.keys())]
43
- df.rename(columns=selected_columns_dict, inplace=True)
44
-
45
- df["MaturityDate"] = pd.to_datetime(df["MaturityDate"], format="%Y%m%d")
46
- df.insert(0, "ReferenceDate", reference_date)
47
-
48
- return df.sort_values(["BondType", "MaturityDate"], ignore_index=True)
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