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.
- {pyield-0.32.7 → pyield-0.32.8}/PKG-INFO +1 -1
- pyield-0.32.8/pyield/__about__.py +1 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/historical.py +1 -1
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/intraday.py +3 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/xml.py +2 -1
- {pyield-0.32.7 → pyield-0.32.8}/pyield/fwd.py +37 -31
- {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ltn.py +3 -3
- pyield-0.32.7/pyield/__about__.py +0 -1
- {pyield-0.32.7 → pyield-0.32.8}/.gitignore +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/LICENSE +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/README.md +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/ettj.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/ima.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/imaq.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/ipca.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/anbima/tpf.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/di.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/di_over.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/b3/futures/common.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/auction.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/bcdata.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/ptax.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/repo.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/trade.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bc/vna.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/bday.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/conftest.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/data_cache.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/date_converter.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/br_holidays_new.txt +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/br_holidays_old.txt +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/holidays/brholidays.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/ibge/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/ibge/ipca.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/interpolator.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/py.typed +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/retry.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/__init__.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/lft.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ntnb.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ntnc.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/ntnf.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyield/tpf/tools.py +0 -0
- {pyield-0.32.7 → pyield-0.32.8}/pyproject.toml +0 -0
|
@@ -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"
|
|
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"
|
|
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
|
|
13
|
+
fwdₖ = fwdⱼ→ₖ (a taxa a termo de j para k)
|
|
14
14
|
|
|
15
15
|
A fórmula utilizada é:
|
|
16
|
-
fwd
|
|
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
|
|
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
|
-
|
|
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
|
|
29
|
-
- r
|
|
30
|
-
- t
|
|
31
|
-
- t
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if
|
|
72
|
-
|
|
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({"
|
|
76
|
-
df["
|
|
83
|
+
df = pd.DataFrame({"duk": bdays, "rk": rates})
|
|
84
|
+
df["tk"] = df["duk"] / 252
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
|
|
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", "
|
|
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["
|
|
89
|
-
df["
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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, "
|
|
110
|
+
df.loc[first_indices, "fwd"] = df.loc[first_indices, "rk"]
|
|
103
111
|
|
|
104
|
-
# Return the forward rates as a Series
|
|
105
|
-
|
|
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
|
-
|
|
183
|
-
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|