PYield 0.35.1__tar.gz → 0.35.2__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.35.1 → pyield-0.35.2}/PKG-INFO +1 -1
- pyield-0.35.2/pyield/__about__.py +1 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/di1.py +50 -4
- {pyield-0.35.1 → pyield-0.35.2}/pyield/tpf/ltn.py +3 -1
- {pyield-0.35.1 → pyield-0.35.2}/pyield/tpf/ntnf.py +7 -6
- {pyield-0.35.1 → pyield-0.35.2}/pyield/tpf/tools.py +0 -3
- pyield-0.35.1/pyield/__about__.py +0 -1
- {pyield-0.35.1 → pyield-0.35.2}/.gitignore +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/LICENSE +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/README.md +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/anbima/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/anbima/ettj.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/anbima/ima.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/anbima/imaq.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/anbima/ipca.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/anbima/tpf.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/di_over.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/futures/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/futures/common.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/futures/historical.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/futures/intraday.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/b3/futures/xml.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/auction.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/bcdata.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/ptax.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/repo.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/trades_intraday.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/trades_monthly.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bc/vna.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/bday.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/conftest.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/data_cache.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/date_converter.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/fwd.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/holidays/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/holidays/br_holidays_new.txt +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/holidays/br_holidays_old.txt +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/holidays/brholidays.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/ibge/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/ibge/ipca.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/interpolator.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/py.typed +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/retry.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/tpf/__init__.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/tpf/lft.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/tpf/ntnb.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyield/tpf/ntnc.py +0 -0
- {pyield-0.35.1 → pyield-0.35.2}/pyproject.toml +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.35.2"
|
|
@@ -55,7 +55,6 @@ def data(
|
|
|
55
55
|
3 2024-10-16 2025-02-01 DI1G25 74 279491
|
|
56
56
|
4 2024-10-16 2025-03-01 DI1H25 94 344056
|
|
57
57
|
"""
|
|
58
|
-
|
|
59
58
|
dates = dc.convert_input_dates(dates)
|
|
60
59
|
# Force dates to be a Series for consistency
|
|
61
60
|
dates = pd.Series(dates) if isinstance(dates, pd.Timestamp) else dates
|
|
@@ -95,7 +94,9 @@ def data(
|
|
|
95
94
|
df_pre = df_pre.rename(
|
|
96
95
|
columns={"ReferenceDate": "TradeDate", "MaturityDate": "ExpirationDate"}
|
|
97
96
|
)
|
|
98
|
-
|
|
97
|
+
# merge_asof will be used to filter the most recent LTN and NTN-F
|
|
98
|
+
# maturities for the given trade date. Therefore, the intraday data
|
|
99
|
+
# will use LTN and NTN-F maturities from the previous day.
|
|
99
100
|
df = pd.merge_asof(
|
|
100
101
|
df, df_pre, on="TradeDate", by="ExpirationDate", direction="backward"
|
|
101
102
|
)
|
|
@@ -150,7 +151,7 @@ def interpolate_rates(
|
|
|
150
151
|
"""
|
|
151
152
|
Interpolates DI rates for specified trade dates and expiration dates.
|
|
152
153
|
|
|
153
|
-
Calculates interpolated DI rates using the flat-forward method for given
|
|
154
|
+
Calculates interpolated DI rates using the **flat-forward** method for given
|
|
154
155
|
sets of trade dates and expiration dates. This function is well-suited
|
|
155
156
|
for vectorized calculations across multiple date pairs.
|
|
156
157
|
|
|
@@ -175,6 +176,52 @@ def interpolate_rates(
|
|
|
175
176
|
Raises:
|
|
176
177
|
ValueError: If `dates` and `expirations` are both array-like but have
|
|
177
178
|
different lengths.
|
|
179
|
+
|
|
180
|
+
Examples:
|
|
181
|
+
>>> from pyield import di1
|
|
182
|
+
>>> # Note: by default, pandas shows floats with 6 decimal places
|
|
183
|
+
>>> # Interpolate rates for multiple trade and expiration dates
|
|
184
|
+
>>> # There is a contract with expiration 01-01-2027 in 08-05-2025
|
|
185
|
+
>>> # The rate is not interpolated (settlement rate is used)
|
|
186
|
+
>>> # There is no contract with expiration 25-11-2027 in 09-05-2025
|
|
187
|
+
>>> # The rate is interpolated (flat-forward method)
|
|
188
|
+
>>> # There is no data for trade date 10-05-2025 (Saturday) -> NaN
|
|
189
|
+
>>> # Note: 0.13461282461562996 is shown as 0.134613
|
|
190
|
+
>>> di1.interpolate_rates(
|
|
191
|
+
... dates=["08-05-2025", "09-05-2025", "10-05-2025"],
|
|
192
|
+
... expirations=["01-01-2027", "25-11-2027", "01-01-2030"],
|
|
193
|
+
... )
|
|
194
|
+
0 0.13972
|
|
195
|
+
1 0.134613
|
|
196
|
+
2 <NA>
|
|
197
|
+
dtype: Float64
|
|
198
|
+
|
|
199
|
+
>>> # Interpolate rates for a single trade date and multiple expiration dates
|
|
200
|
+
>>> # There is no DI Contract in 09-05-2025 with expiration 01-01-2050
|
|
201
|
+
>>> # The longest available contract is used to extrapolate the rate
|
|
202
|
+
>>> # Note: extrapolation is allowed by default
|
|
203
|
+
>>> di1.interpolate_rates(
|
|
204
|
+
... dates="25-04-2025",
|
|
205
|
+
... expirations=["01-01-2027", "01-01-2050"],
|
|
206
|
+
... )
|
|
207
|
+
0 0.13901
|
|
208
|
+
1 0.13881
|
|
209
|
+
dtype: Float64
|
|
210
|
+
|
|
211
|
+
>>> # With extrapolation set to False, the second rate will be NaN
|
|
212
|
+
>>> # Note: 0.13576348733268917 is shown as 0.135763
|
|
213
|
+
>>> di1.interpolate_rates(
|
|
214
|
+
... dates="25-04-2025",
|
|
215
|
+
... expirations=["01-11-2027", "01-01-2050"],
|
|
216
|
+
... extrapolate=False,
|
|
217
|
+
... )
|
|
218
|
+
0 0.135763
|
|
219
|
+
1 <NA>
|
|
220
|
+
dtype: Float64
|
|
221
|
+
|
|
222
|
+
Notes:
|
|
223
|
+
- All available settlement rates are used for the flat-forward interpolation.
|
|
224
|
+
- The function handles broadcasting of scalar and array-like inputs.
|
|
178
225
|
"""
|
|
179
226
|
# Convert input dates to a consistent format
|
|
180
227
|
dates = dc.convert_input_dates(dates)
|
|
@@ -280,7 +327,6 @@ def interpolate_rate(
|
|
|
280
327
|
>>> di1.interpolate_rate("25-04-2025", "01-01-2050", extrapolate=True)
|
|
281
328
|
0.13881
|
|
282
329
|
"""
|
|
283
|
-
|
|
284
330
|
expiration = dc.convert_input_dates(expiration)
|
|
285
331
|
if not date:
|
|
286
332
|
return float("NaN")
|
|
@@ -136,7 +136,9 @@ def di_spreads(date: DateScalar) -> pd.DataFrame:
|
|
|
136
136
|
|
|
137
137
|
Examples:
|
|
138
138
|
>>> from pyield import ltn
|
|
139
|
-
>>> ltn.di_spreads("22-08-2024")
|
|
139
|
+
>>> spreads = ltn.di_spreads("22-08-2024")
|
|
140
|
+
>>> spreads["DISpread"] = spreads["DISpread"] * 10000 # Convert to bps
|
|
141
|
+
>>> spreads
|
|
140
142
|
MaturityDate DISpread
|
|
141
143
|
0 2024-10-01 -3.06
|
|
142
144
|
1 2025-01-01 -9.95
|
|
@@ -344,7 +344,9 @@ def di_spreads(date: DateScalar) -> pd.DataFrame:
|
|
|
344
344
|
|
|
345
345
|
Examples:
|
|
346
346
|
>>> from pyield import ntnf
|
|
347
|
-
>>> ntnf.di_spreads("23-08-2024")
|
|
347
|
+
>>> df_spreads = ntnf.di_spreads("23-08-2024")
|
|
348
|
+
>>> df_spreads["DISpread"] = df_spreads["DISpread"] * 10_000 # Convert to bps
|
|
349
|
+
>>> df_spreads
|
|
348
350
|
MaturityDate DISpread
|
|
349
351
|
0 2025-01-01 -5.38
|
|
350
352
|
1 2027-01-01 4.39
|
|
@@ -444,19 +446,20 @@ def di_net_spread( # noqa
|
|
|
444
446
|
None. A good initial guess is the DI gross spread for the bond.
|
|
445
447
|
|
|
446
448
|
Returns:
|
|
447
|
-
float: The net DI spread in
|
|
449
|
+
float: The net DI spread in decimal format (e.g., 0.0012 for 12 bps).
|
|
448
450
|
|
|
449
451
|
Examples:
|
|
450
452
|
# Obs: only some of the DI rates will be used in the example.
|
|
451
453
|
>>> exp_dates = pd.to_datetime(["2025-01-01", "2030-01-01", "2035-01-01"])
|
|
452
454
|
>>> di_rates = pd.Series([0.10823, 0.11594, 0.11531])
|
|
453
|
-
>>> di_net_spread(
|
|
455
|
+
>>> spread = di_net_spread(
|
|
454
456
|
... settlement="23-08-2024",
|
|
455
457
|
... ntnf_maturity="01-01-2035",
|
|
456
458
|
... ntnf_rate=0.116586,
|
|
457
459
|
... di_expirations=exp_dates,
|
|
458
460
|
... di_rates=di_rates,
|
|
459
461
|
... )
|
|
462
|
+
>>> round(spread * 10_000, 2) # Convert to bps for display
|
|
460
463
|
12.13
|
|
461
464
|
"""
|
|
462
465
|
# Create an interpolator for the DI rates using the flat-forward method
|
|
@@ -489,9 +492,7 @@ def di_net_spread( # noqa
|
|
|
489
492
|
return (bond_cash_flows / (1 + di_interp + p) ** byears).sum() - bond_price
|
|
490
493
|
|
|
491
494
|
# Solve for the spread that zeroes the price difference using the bisection method
|
|
492
|
-
|
|
493
|
-
# Convert the solution to basis points (bps) and round to two decimal places
|
|
494
|
-
return round((p_solution * 10_000), 2)
|
|
495
|
+
return _solve_spread(price_difference, initial_guess)
|
|
495
496
|
|
|
496
497
|
|
|
497
498
|
def premium(
|
|
@@ -97,9 +97,6 @@ def pre_spreads(date: DateScalar) -> pd.DataFrame:
|
|
|
97
97
|
# Calculate the DI spread as the difference between indicative and settlement rates
|
|
98
98
|
df_spreads["DISpread"] = df_spreads["IndicativeRate"] - df_spreads["SettlementRate"]
|
|
99
99
|
|
|
100
|
-
# Convert spread to basis points for clarity
|
|
101
|
-
df_spreads["DISpread"] = (10_000 * df_spreads["DISpread"]).round(2)
|
|
102
|
-
|
|
103
100
|
# Prepare and return the final sorted DataFrame
|
|
104
101
|
df_spreads = df_spreads.sort_values(["BondType", "MaturityDate"], ignore_index=True)
|
|
105
102
|
return df_spreads[["BondType", "MaturityDate", "DISpread"]].copy()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.35.1"
|
|
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
|
|
File without changes
|
|
File without changes
|