PYield 0.32.2__tar.gz → 0.32.3__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 (51) hide show
  1. {pyield-0.32.2 → pyield-0.32.3}/PKG-INFO +1 -1
  2. pyield-0.32.3/pyield/__about__.py +1 -0
  3. {pyield-0.32.2 → pyield-0.32.3}/pyield/__init__.py +2 -1
  4. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/di.py +4 -5
  5. pyield-0.32.3/pyield/fwd.py +120 -0
  6. pyield-0.32.2/pyield/__about__.py +0 -1
  7. pyield-0.32.2/pyield/forward.py +0 -56
  8. {pyield-0.32.2 → pyield-0.32.3}/.gitignore +0 -0
  9. {pyield-0.32.2 → pyield-0.32.3}/LICENSE +0 -0
  10. {pyield-0.32.2 → pyield-0.32.3}/README.md +0 -0
  11. {pyield-0.32.2 → pyield-0.32.3}/pyield/anbima/__init__.py +0 -0
  12. {pyield-0.32.2 → pyield-0.32.3}/pyield/anbima/ettj.py +0 -0
  13. {pyield-0.32.2 → pyield-0.32.3}/pyield/anbima/ima.py +0 -0
  14. {pyield-0.32.2 → pyield-0.32.3}/pyield/anbima/imaq.py +0 -0
  15. {pyield-0.32.2 → pyield-0.32.3}/pyield/anbima/ipca.py +0 -0
  16. {pyield-0.32.2 → pyield-0.32.3}/pyield/anbima/tpf.py +0 -0
  17. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/__init__.py +0 -0
  18. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/di_over.py +0 -0
  19. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/futures/__init__.py +0 -0
  20. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/futures/common.py +0 -0
  21. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/futures/historical.py +0 -0
  22. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/futures/intraday.py +0 -0
  23. {pyield-0.32.2 → pyield-0.32.3}/pyield/b3/futures/xml.py +0 -0
  24. {pyield-0.32.2 → pyield-0.32.3}/pyield/bc/__init__.py +0 -0
  25. {pyield-0.32.2 → pyield-0.32.3}/pyield/bc/auction.py +0 -0
  26. {pyield-0.32.2 → pyield-0.32.3}/pyield/bc/bcdata.py +0 -0
  27. {pyield-0.32.2 → pyield-0.32.3}/pyield/bc/ptax.py +0 -0
  28. {pyield-0.32.2 → pyield-0.32.3}/pyield/bc/repo.py +0 -0
  29. {pyield-0.32.2 → pyield-0.32.3}/pyield/bc/trade.py +0 -0
  30. {pyield-0.32.2 → pyield-0.32.3}/pyield/bc/vna.py +0 -0
  31. {pyield-0.32.2 → pyield-0.32.3}/pyield/bday.py +0 -0
  32. {pyield-0.32.2 → pyield-0.32.3}/pyield/conftest.py +0 -0
  33. {pyield-0.32.2 → pyield-0.32.3}/pyield/data_cache.py +0 -0
  34. {pyield-0.32.2 → pyield-0.32.3}/pyield/date_converter.py +0 -0
  35. {pyield-0.32.2 → pyield-0.32.3}/pyield/holidays/__init__.py +0 -0
  36. {pyield-0.32.2 → pyield-0.32.3}/pyield/holidays/br_holidays_new.txt +0 -0
  37. {pyield-0.32.2 → pyield-0.32.3}/pyield/holidays/br_holidays_old.txt +0 -0
  38. {pyield-0.32.2 → pyield-0.32.3}/pyield/holidays/brholidays.py +0 -0
  39. {pyield-0.32.2 → pyield-0.32.3}/pyield/ibge/__init__.py +0 -0
  40. {pyield-0.32.2 → pyield-0.32.3}/pyield/ibge/ipca.py +0 -0
  41. {pyield-0.32.2 → pyield-0.32.3}/pyield/interpolator.py +0 -0
  42. {pyield-0.32.2 → pyield-0.32.3}/pyield/py.typed +0 -0
  43. {pyield-0.32.2 → pyield-0.32.3}/pyield/retry.py +0 -0
  44. {pyield-0.32.2 → pyield-0.32.3}/pyield/tpf/__init__.py +0 -0
  45. {pyield-0.32.2 → pyield-0.32.3}/pyield/tpf/lft.py +0 -0
  46. {pyield-0.32.2 → pyield-0.32.3}/pyield/tpf/ltn.py +0 -0
  47. {pyield-0.32.2 → pyield-0.32.3}/pyield/tpf/ntnb.py +0 -0
  48. {pyield-0.32.2 → pyield-0.32.3}/pyield/tpf/ntnc.py +0 -0
  49. {pyield-0.32.2 → pyield-0.32.3}/pyield/tpf/ntnf.py +0 -0
  50. {pyield-0.32.2 → pyield-0.32.3}/pyield/tpf/tools.py +0 -0
  51. {pyield-0.32.2 → pyield-0.32.3}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PYield
3
- Version: 0.32.2
3
+ Version: 0.32.3
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.3"
@@ -4,7 +4,7 @@ from pyield import anbima, b3, bc, bday, ibge
4
4
  from pyield.__about__ import __version__
5
5
  from pyield.b3 import futures
6
6
  from pyield.b3.di import DIFutures
7
- from pyield.forward import forwards
7
+ from pyield.fwd import forward, forwards
8
8
  from pyield.interpolator import Interpolator
9
9
  from pyield.tpf import lft, ltn, ntnb, ntnc, ntnf
10
10
 
@@ -14,6 +14,7 @@ __all__ = [
14
14
  "bday",
15
15
  "DIFutures",
16
16
  "forwards",
17
+ "forward",
17
18
  "futures",
18
19
  "ibge",
19
20
  "Interpolator",
@@ -5,8 +5,7 @@ from zoneinfo import ZoneInfo
5
5
  import pandas as pd
6
6
 
7
7
  import pyield.date_converter as dc
8
- import pyield.forward as fw
9
- from pyield import b3, bday, interpolator
8
+ from pyield import b3, bday, fwd, interpolator
10
9
  from pyield.data_cache import get_cached_dataset
11
10
  from pyield.date_converter import DateArray, DateScalar
12
11
 
@@ -206,9 +205,9 @@ class DIFutures:
206
205
  if df.empty:
207
206
  return pd.DataFrame()
208
207
 
209
- df["ForwardRate"] = fw.forwards(
210
- business_days=bday.count(df["TradeDate"], df["ExpirationDate"]),
211
- zero_rates=df["SettlementRate"],
208
+ df["ForwardRate"] = fwd.forwards(
209
+ bdays=bday.count(df["TradeDate"], df["ExpirationDate"]),
210
+ rates=df["SettlementRate"],
212
211
  groupby_dates=df["TradeDate"],
213
212
  )
214
213
 
@@ -0,0 +1,120 @@
1
+ import pandas as pd
2
+
3
+
4
+ def forwards(
5
+ bdays: pd.Series,
6
+ rates: pd.Series,
7
+ groupby_dates: pd.Series | None = None,
8
+ ) -> pd.Series:
9
+ """
10
+ Calculates forward rates from zero rates using the formula:
11
+ f₁→₂ = ((1 + r₂)^(du₂/252) / (1 + r₁)^(du₁/252))^(252/(du₂ - du₁)) - 1
12
+
13
+ Since du/252 = t, the formula can be simplified to:
14
+ f₁→₂ = ((1 + r₂)^t₂ / (1 + r₁)^t₁)^(1/(t₂ - t₁)) - 1
15
+
16
+ where:
17
+ - r₁ is the zero rate for the previous period
18
+ - r₂ is the zero rate for the current period
19
+ - t₁ is the time in years for the previous period
20
+ - t₂ is the time in years for the current period
21
+
22
+ The first forward rate is set to the corresponding zero rate.
23
+ This function can also handle grouping of the input data based on the
24
+ `groupby_dates` parameter. If provided, the calculations will be performed
25
+ separately for each group, allowing for different forward rate calculations
26
+ based on the grouping criteria.
27
+
28
+ Args:
29
+ bdays (pd.Series): Number of business days for each zero rate.
30
+ rates (pd.Series): Zero rates corresponding to the business days.
31
+ groupby_dates (pd.Series | None, optional): Optional grouping criteria to
32
+ segment calculations. If not provided, calculations will not be grouped.
33
+
34
+ Returns:
35
+ pd.Series: Series of calculated forward rates with the first rate set to the
36
+ corresponding zero rate.
37
+ """
38
+ # Reset Series indexes to avoid misalignment issues during calculations
39
+ bdays = bdays.reset_index(drop=True)
40
+ rates = rates.reset_index(drop=True)
41
+ if groupby_dates is not None:
42
+ groupby_dates = groupby_dates.reset_index(drop=True)
43
+
44
+ # Create a DataFrame to work with the given series
45
+ df = pd.DataFrame({"du2": bdays, "r2": rates})
46
+ df["t2"] = df["du2"] / 252
47
+
48
+ # If no groupby_dates is provided, create a dummy column to group the DataFrame
49
+ if groupby_dates is not None:
50
+ df["groupby_date"] = groupby_dates
51
+ else:
52
+ df["groupby_date"] = 0 # Dummy value to group the DataFrame
53
+
54
+ # Sort by the groupby_dates and bd columns to ensure proper chronological order
55
+ df.sort_values(by=["groupby_date", "t2"], inplace=True)
56
+
57
+ # GetCalculate the next zero rate and business day for each group
58
+ df["r1"] = df.groupby("groupby_date")["r2"].shift(1)
59
+ df["t1"] = df.groupby("groupby_date")["t2"].shift(1)
60
+
61
+ # Calculate the formula components
62
+ factor_r2 = (1 + df["r2"]) ** df["t2"] # (1 + r₂)^t₂
63
+ factor_r1 = (1 + df["r1"]) ** df["t1"] # (1 + r₁)^t₁
64
+ time_exp = 1 / (df["t2"] - df["t1"]) # 1/(t₂ - t₁)
65
+
66
+ # f₁→₂ = ((1 + r₂)^t₂ / (1 + r₁)^t₁)^(1/(t₂ - t₁)) - 1
67
+ df["f1_2"] = (factor_r2 / factor_r1) ** time_exp - 1
68
+
69
+ # Identifify the first index of each group of dates
70
+ first_indices = df.groupby("groupby_date").head(1).index
71
+ # Set the first forward rate of each group to the zero rate
72
+ df.loc[first_indices, "f1_2"] = df.loc[first_indices, "r2"]
73
+
74
+ # Return the forward rates as a Series converting to Float64 to handle NaN values
75
+ return df["f1_2"].astype("Float64")
76
+
77
+
78
+ def forward(
79
+ bday1: int,
80
+ bday2: int,
81
+ rate1: float,
82
+ rate2: float,
83
+ ) -> float:
84
+ """
85
+ Calculates the forward rate between two business days using the formula:
86
+ f₁→₂ = ((1 + r₂)^(du₂/252) / (1 + r₁)^(du₁/252))^(252/(du₂ - du₁)) - 1
87
+
88
+ where:
89
+ - r₁ is the zero rate for the previous period
90
+ - r₂ is the zero rate for the current period
91
+ - du₁ is the number of business days until the first date
92
+ - du₂ is the number of business days until the second date
93
+
94
+ Args:
95
+ bday1 (int): Number of business days until the first date.
96
+ bday2 (int): Number of business days until the second date.
97
+ rate1 (float): Zero rate for the first date.
98
+ rate2 (float): Zero rate for the second date.
99
+
100
+ Returns:
101
+ float: The calculated forward rate.
102
+
103
+ Example:
104
+ >>> forward(10, 20, 0.05, 0.06)
105
+ 0.0700952380952371
106
+ """
107
+ if pd.isna(rate1) or pd.isna(rate2) or pd.isna(bday1) or pd.isna(bday2):
108
+ # If any of the inputs are NaN, return NaN
109
+ return float("nan")
110
+
111
+ # Handle the case where the two dates are the same
112
+ if bday1 == bday2:
113
+ return float("nan")
114
+
115
+ # Convert business days to business years
116
+ t1 = bday1 / 252
117
+ t2 = bday2 / 252
118
+
119
+ # f₁→₂ = ((1 + r₂)^t₂ / (1 + r₁)^t₁)^(1/(t₂ - t₁)) - 1
120
+ return ((1 + rate2) ** t2 / (1 + rate1) ** t1) ** (1 / (t2 - t1)) - 1
@@ -1 +0,0 @@
1
- __version__ = "0.32.2"
@@ -1,56 +0,0 @@
1
- import pandas as pd
2
-
3
-
4
- def forwards(
5
- business_days: pd.Series,
6
- zero_rates: pd.Series,
7
- groupby_dates: pd.Series | None = None,
8
- ) -> pd.Series:
9
- """Calculates forward rates from zero rates.
10
-
11
- Args:
12
- business_days (pd.Series): Number of business days for each zero rate.
13
- zero_rates (pd.Series): Zero rates corresponding to the business days.
14
- groupby_dates (pd.Series | None, optional): Optional grouping criteria to
15
- segment calculations. If not provided, calculations will not be grouped.
16
-
17
- Returns:
18
- pd.Series: Series of calculated forward rates with the first rate set to the
19
- corresponding zero rate.
20
- """
21
- # Reset Series indexes to avoid misalignment issues during calculations
22
- business_days = business_days.reset_index(drop=True)
23
- zero_rates = zero_rates.reset_index(drop=True)
24
- if groupby_dates is not None:
25
- groupby_dates = groupby_dates.reset_index(drop=True)
26
-
27
- # Create a DataFrame to work with the given series
28
- df = pd.DataFrame({"bd": business_days, "zero_rate": zero_rates})
29
-
30
- # If no groupby_dates is provided, create a dummy column to group the DataFrame
31
- if groupby_dates is not None:
32
- df["groupby_date"] = groupby_dates
33
- else:
34
- df["groupby_date"] = 0 # Dummy value to group the DataFrame
35
-
36
- # Sort by the groupby_dates and bd columns to ensure proper chronological order
37
- df.sort_values(by=["groupby_date", "bd"], inplace=True)
38
-
39
- # Calculate the next zero rate and business day for each group
40
- df["next_rate"] = df.groupby("groupby_date")["zero_rate"].shift(1)
41
- df["next_bday"] = df.groupby("groupby_date")["bd"].shift(1)
42
-
43
- # Calculate the forward rates using the formula
44
- factor1 = (1 + df["next_rate"]) ** (df["next_bday"] / 252)
45
- factor2 = (1 + df["zero_rate"]) ** (df["bd"] / 252)
46
- factor3 = 252 / (df["next_bday"] - df["bd"])
47
- df["fwd_rate"] = (factor1 / factor2) ** factor3 - 1
48
-
49
- # Identifify the first index of each group of dates
50
- first_indices = df.groupby("groupby_date").head(1).index
51
- # Set the first forward rate of each group to the zero rate
52
- df.loc[first_indices, "fwd_rate"] = df.loc[first_indices, "zero_rate"]
53
-
54
- df["fwd_rate"] = df["fwd_rate"].astype("Float64")
55
-
56
- return df["fwd_rate"]
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