PYield 0.32.7__tar.gz → 0.32.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.
Files changed (50) hide show
  1. {pyield-0.32.7 → pyield-0.32.8}/PKG-INFO +1 -1
  2. pyield-0.32.8/pyield/__about__.py +1 -0
  3. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/historical.py +1 -1
  4. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/intraday.py +3 -0
  5. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/xml.py +2 -1
  6. {pyield-0.32.7 → pyield-0.32.8}/pyield/fwd.py +37 -31
  7. {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ltn.py +3 -3
  8. pyield-0.32.7/pyield/__about__.py +0 -1
  9. {pyield-0.32.7 → pyield-0.32.8}/.gitignore +0 -0
  10. {pyield-0.32.7 → pyield-0.32.8}/LICENSE +0 -0
  11. {pyield-0.32.7 → pyield-0.32.8}/README.md +0 -0
  12. {pyield-0.32.7 → pyield-0.32.8}/pyield/__init__.py +0 -0
  13. {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/__init__.py +0 -0
  14. {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/ettj.py +0 -0
  15. {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/ima.py +0 -0
  16. {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/imaq.py +0 -0
  17. {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/ipca.py +0 -0
  18. {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/tpf.py +0 -0
  19. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/__init__.py +0 -0
  20. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/di.py +0 -0
  21. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/di_over.py +0 -0
  22. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/__init__.py +0 -0
  23. {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/common.py +0 -0
  24. {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/__init__.py +0 -0
  25. {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/auction.py +0 -0
  26. {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/bcdata.py +0 -0
  27. {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/ptax.py +0 -0
  28. {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/repo.py +0 -0
  29. {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/trade.py +0 -0
  30. {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/vna.py +0 -0
  31. {pyield-0.32.7 → pyield-0.32.8}/pyield/bday.py +0 -0
  32. {pyield-0.32.7 → pyield-0.32.8}/pyield/conftest.py +0 -0
  33. {pyield-0.32.7 → pyield-0.32.8}/pyield/data_cache.py +0 -0
  34. {pyield-0.32.7 → pyield-0.32.8}/pyield/date_converter.py +0 -0
  35. {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/__init__.py +0 -0
  36. {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/br_holidays_new.txt +0 -0
  37. {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/br_holidays_old.txt +0 -0
  38. {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/brholidays.py +0 -0
  39. {pyield-0.32.7 → pyield-0.32.8}/pyield/ibge/__init__.py +0 -0
  40. {pyield-0.32.7 → pyield-0.32.8}/pyield/ibge/ipca.py +0 -0
  41. {pyield-0.32.7 → pyield-0.32.8}/pyield/interpolator.py +0 -0
  42. {pyield-0.32.7 → pyield-0.32.8}/pyield/py.typed +0 -0
  43. {pyield-0.32.7 → pyield-0.32.8}/pyield/retry.py +0 -0
  44. {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/__init__.py +0 -0
  45. {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/lft.py +0 -0
  46. {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ntnb.py +0 -0
  47. {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ntnc.py +0 -0
  48. {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ntnf.py +0 -0
  49. {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/tools.py +0 -0
  50. {pyield-0.32.7 → pyield-0.32.8}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PYield
3
- Version: 0.32.7
3
+ Version: 0.32.8
4
4
  Summary: A Python library for analysis of fixed income instruments in Brazil
5
5
  Project-URL: Source, https://github.com/crdcj/PYield
6
6
  Author-email: Carlos Carvalho <cr.cj@outlook.com>
@@ -0,0 +1 @@
1
+ __version__ = "0.32.8"
@@ -204,7 +204,7 @@ def process_df(
204
204
  df["BDaysToExp"] = bday.count(date, df["ExpirationDate"])
205
205
 
206
206
  # Remove expired contracts
207
- df.query("DaysToExp > 0", inplace=True)
207
+ df = df.query("DaysToExp > 0").reset_index(drop=True)
208
208
 
209
209
  # Columns where 0 means NaN
210
210
  cols_with_nan = [col for col in df.columns if "Rate" in col]
@@ -123,6 +123,9 @@ def _process_df(raw_df: pd.DataFrame, contract_code: str) -> pd.DataFrame:
123
123
  # Convert to nullable integer, since it is the default type in the library
124
124
  df["DaysToExp"] = df["DaysToExp"].astype("Int64")
125
125
 
126
+ # Remove expired contracts
127
+ df = df.query("DaysToExp >= 0").reset_index(drop=True)
128
+
126
129
  # The "FinancialVolume" column is in BRL, so we need to round it to cents
127
130
  df["FinancialVolume"] = df["FinancialVolume"].round(2)
128
131
 
@@ -205,8 +205,9 @@ def _process_df(df_raw: pd.DataFrame) -> pd.DataFrame:
205
205
  df["DaysToExp"] = (df["ExpirationDate"] - df["TradeDate"]).dt.days
206
206
  # Convert to nullable integer, since it is the default type in the library
207
207
  df["DaysToExp"] = df["DaysToExp"].astype("Int64")
208
+
208
209
  # Remove expired contracts
209
- df.query("DaysToExp > 0", inplace=True)
210
+ df = df.query("DaysToExp > 0").reset_index(drop=True)
210
211
 
211
212
  df["BDaysToExp"] = bday.count(df["TradeDate"], df["ExpirationDate"])
212
213
 
@@ -10,25 +10,25 @@ def forwards(
10
10
  Calcula taxas a termo (forward rates) a partir de taxas zero (spot rates).
11
11
 
12
12
  A taxa a termo no vértice 'n' é definida como:
13
- fwdₙ = fwdₙ₋₁→ₙ (a taxa a termo de n-1 para n)
13
+ fwdₖ = fwdⱼ→ₖ (a taxa a termo de j para k)
14
14
 
15
15
  A fórmula utilizada é:
16
- fwdₙ = ((1 + rₙ)^(duₙ/252) / (1 + rₙ₋₁)^(duₙ₋₁/252))^(252/(duₙ - duₙ₋₁)) - 1
16
+ fwdₖ = ((1 + rₖ)^(duₖ/252) / (1 + rⱼ)^(duⱼ/252))^(252/(duₖ - duⱼ)) - 1
17
17
 
18
18
  Como du/252 = t (tempo em anos úteis), a fórmula pode ser simplificada para:
19
19
 
20
- fwdₙ = ((1 + rₙ)^tₙ / (1 + rₙ₋₁)^tₙ₋₁)^(1/(tₙ - tₙ₋₁)) - 1
20
+ fwdₖ = ((1 + rₖ)^tₖ / (1 + rⱼ)^tⱼ)^(1/(tₖ - tⱼ)) - 1
21
21
 
22
22
  Em LaTeX, a fórmula é representada como:
23
23
  $$
24
- fwd_{n} = \left( \frac{(1 + r_n)^{t_n}}{(1 + r_{n-1})^{t_{n-1}}} \right)^{\frac{1}{t_n - t_{n-1}}} - 1
24
+ fwd_k = \left( \frac{(1 + r_k)^{t_k}}{(1 + r_j)^{t_j}} \right)^{\frac{1}{t_k - t_j}} - 1
25
25
  $$
26
26
 
27
27
  Onde:
28
- - rₙ₋₁ é a taxa zero para o vértice anterior.
29
- - rₙ é a taxa zero para o vértice atual.
30
- - tₙ₋₁ é o prazo em anos para o vértice anterior (calculado como duₙ₋₁/252).
31
- - tₙ é o prazo em anos para o vértice atual (calculado como duₙ/252).
28
+ - rⱼ é a taxa zero para o vértice anterior.
29
+ - rₖ é a taxa zero para o vértice atual.
30
+ - tⱼ é o prazo em anos para o vértice anterior (calculado como duⱼ/252).
31
+ - tₖ é o prazo em anos para o vértice atual (calculado como duₖ/252).
32
32
  - A constante 252 representa o número de dias úteis no ano.
33
33
 
34
34
  A primeira taxa a termo de cada grupo é definida como a
@@ -56,6 +56,10 @@ def forwards(
56
56
  pd.Series: Série contendo as taxas a termo calculadas (tipo Float64).
57
57
  A primeira taxa de cada grupo corresponde à taxa zero inicial.
58
58
 
59
+ Raises:
60
+ ValueError: Se os índices de `bdays` e `rates` não forem iguais.
61
+ ValueError: Se `groupby_dates` não for None e não tiver o mesmo tamanho
62
+
59
63
  Examples:
60
64
  >>> bdays = pd.Series([10, 20, 30])
61
65
  >>> rates = pd.Series([0.05, 0.06, 0.07])
@@ -64,47 +68,49 @@ def forwards(
64
68
  1 0.070095
65
69
  2 0.090284
66
70
  dtype: Float64
71
+
72
+ Note:
73
+ A função retorna uma série com o mesmo índice que `bdays` e `rates`.
67
74
  """ # noqa: E501
68
- # Reset Series indexes to avoid misalignment issues during calculations
69
- bdays = bdays.reset_index(drop=True).astype("Int64")
70
- rates = rates.reset_index(drop=True).astype("Float64")
71
- if groupby_dates is not None:
72
- groupby_dates = groupby_dates.reset_index(drop=True)
75
+ bdays = bdays.astype("Int64")
76
+ rates = rates.astype("Float64")
77
+
78
+ # Check if indexes are the same
79
+ if not bdays.index.equals(rates.index):
80
+ raise ValueError("The indexes of bdays and rates must be the same.")
73
81
 
74
82
  # Create a DataFrame to work with the given series
75
- df = pd.DataFrame({"du2": bdays, "r2": rates})
76
- df["t2"] = df["du2"] / 252
83
+ df = pd.DataFrame({"duk": bdays, "rk": rates})
84
+ df["tk"] = df["duk"] / 252
77
85
 
78
- # If no groupby_dates is provided, create a dummy column to group the DataFrame
79
- if groupby_dates is not None:
86
+ if isinstance(groupby_dates, pd.Series):
87
+ if not groupby_dates.index.equals(bdays.index):
88
+ raise ValueError("groupby_dates index must be the same as bdays and rates.")
80
89
  df["groupby_date"] = groupby_dates
81
90
  else:
82
91
  df["groupby_date"] = 0 # Dummy value to group the DataFrame
83
92
 
84
93
  # Sort by the groupby_dates and t2 columns to ensure proper chronological order
85
- df.sort_values(by=["groupby_date", "t2"], inplace=True)
94
+ df.sort_values(by=["groupby_date", "tk"], inplace=True)
86
95
 
87
96
  # Calculate the next zero rate and business day for each group
88
- df["r1"] = df.groupby("groupby_date")["r2"].shift(1)
89
- df["t1"] = df.groupby("groupby_date")["t2"].shift(1)
97
+ df["rj"] = df.groupby("groupby_date")["rk"].shift(1)
98
+ df["tj"] = df.groupby("groupby_date")["tk"].shift(1)
90
99
 
91
100
  # Calculate the formula components
92
- factor_r2 = (1 + df["r2"]) ** df["t2"] # (1 + r₂)^t₂
93
- factor_r1 = (1 + df["r1"]) ** df["t1"] # (1 + r₁)^t₁
94
- time_exp = 1 / (df["t2"] - df["t1"]) # 1/(t₂ - t₁)
95
-
96
- # f₁→₂ = ((1 + r₂)^t₂ / (1 + r₁)^t₁)^(1/(t₂ - t₁)) - 1
97
- df["f1_2"] = (factor_r2 / factor_r1) ** time_exp - 1
101
+ # fₖ = fⱼ→ₖ = ((1 + rₖ)^tₖ / (1 + rⱼ)^tⱼ) ^ (1/(tₖ - tⱼ)) - 1
102
+ factor_rk = (1 + df["rk"]) ** df["tk"] # (1 + rₖ)^tₖ
103
+ factor_rj = (1 + df["rj"]) ** df["tj"] # (1 + rⱼ)^tⱼ
104
+ time_factor = 1 / (df["tk"] - df["tj"]) # 1/(tₖ - tⱼ)
105
+ df["fwd"] = (factor_rk / factor_rj) ** time_factor - 1
98
106
 
99
107
  # Identifify the first index of each group of dates
100
108
  first_indices = df.groupby("groupby_date").head(1).index
101
109
  # Set the first forward rate of each group to the zero rate
102
- df.loc[first_indices, "f1_2"] = df.loc[first_indices, "r2"]
110
+ df.loc[first_indices, "fwd"] = df.loc[first_indices, "rk"]
103
111
 
104
- # Return the forward rates as a Series
105
- f1_2 = df["f1_2"]
106
- f1_2.name = None
107
- return f1_2
112
+ # Return the forward rates as a Series with no name
113
+ return df.loc[:, "fwd"]
108
114
 
109
115
 
110
116
  def forward(
@@ -179,11 +179,11 @@ def premium(ltn_rate: float, di_rate: float) -> float:
179
179
  1.0120718007994287
180
180
  """
181
181
  # Cálculo das taxas diárias
182
- ltn_factor = (1 + ltn_rate) ** (1 / 252)
183
- di_factor = (1 + di_rate) ** (1 / 252)
182
+ ltn_daily_rate = (1 + ltn_rate) ** (1 / 252) - 1
183
+ di_daily_rate = (1 + di_rate) ** (1 / 252) - 1
184
184
 
185
185
  # Retorno do cálculo do prêmio
186
- return (ltn_factor - 1) / (di_factor - 1)
186
+ return ltn_daily_rate / di_daily_rate
187
187
 
188
188
 
189
189
  def historical_premium(
@@ -1 +0,0 @@
1
- __version__ = "0.32.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