|
From: Quant <qua...@gm...> - 2023-11-27 09:48:54
|
Thanks Aleksis, changed the following parts and the Code worked without
errors:
(i) bondEngine =
ql.DiscountingBondEngine(ql.YieldTermStructureHandle(curve)) - added
ql.YieldTermStructureHandle()
(ii) bondYield = bond.bondYield(day_count, ql.Compounded, ql.Annual) -
added parameters day_count, ql.Compounded, ql.Annual
Regards,
On Mon, Nov 27, 2023 at 11:09 AM Aleksis Ali Raza <
ale...@go...> wrote:
> i think you’re just missing a ql.YieldTermStuctureHandle() call on ur
> constructed curve. you can add that but then u’ll need to alter the dt in
> dates call to refer to the unhandled curve, and also specify some
> parameters in the bondyield call. Then the error will go away.
>
> your code should run fine even without it.
>
> On Nov 27, 2023, at 8:38 AM, Quant <qua...@gm...> wrote:
>
> Hi QuantLib Users,
>
> I have data containing Bond information and I managed to use this
> information to bootstrap the zero curve. To check if my zero curve is
> correct, I would like to reprice the Bonds using the bootstrapped curve
> (using the zero curve) to get back to the quoted prices of the Bonds. I am
> getting the following errors on the repricing part and if anyone can help I
> would appreciate;
>
> Traceback (most recent call last):
> File "/Users/Library/CloudStorage/OneDrive-Personal/QuantLib Software/Valuations/IRS using Bond Bootstrapping/IRS using Bond Bootstrapping 2.py", line 369, in <module>
> bondEngine = ql.DiscountingBondEngine(curve)
> File "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line 25290, in __init__
> _QuantLib.DiscountingBondEngine_swiginit(self, _QuantLib.new_DiscountingBondEngine(discountCurve))
> TypeError: in method 'new_DiscountingBondEngine', argument 1 of type 'Handle< YieldTermStructure > const &'
>
>
> Find below the code that I am running;
>
> # Importing Libraries:# The code imports necessary libraries:# pandas for data manipulation, matplotlib.pyplot for plotting, and QuantLib (ql) for quantitative finance calculations.import pandas as pdimport matplotlib.pyplot as plt# Use the QuantLib or ORE Librariesimport QuantLib as ql
> # Setting Evaluation Date:# Sets the evaluation date
> today = ql.Date(21, ql.November, 2023)
> ql.Settings.instance().evaluationDate = today
> # Calendar and Day Count:# Creates a calendar object and specifies the day-count convention (Actual/365 Fixed)
> calendar = ql.NullCalendar()
> day_count = ql.Actual365Fixed()
> # Settlement Days:
> zero_coupon_settlement_days = 4
> coupon_bond_settlement_days = 3
> # Face Value
> faceAmount = 100
>
> data = [
> ('11-09-2023', '11-12-2023', 0, 99.524, zero_coupon_settlement_days),
> ('11-09-2023', '11-03-2024', 0, 96.539, zero_coupon_settlement_days),
> ('11-09-2023', '10-06-2024', 0, 93.552, zero_coupon_settlement_days),
> ('11-09-2023', '09-09-2024', 0, 89.510, zero_coupon_settlement_days),
> ('22-08-2022', '22-08-2024', 9.0, 96.406933, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2025', 10.0, 88.567570, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2027', 11.0, 71.363073, coupon_bond_settlement_days),
> ('22-08-2022', '22-08-2029', 12.0, 62.911623, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2032', 13.0, 55.976845, coupon_bond_settlement_days),
> ('22-08-2022', '22-08-2037', 14.0, 52.656596, coupon_bond_settlement_days)]
>
> helpers = []
> for issue_date, maturity, coupon, price, settlement_days in data:
> price = ql.QuoteHandle(ql.SimpleQuote(price))
> issue_date = ql.Date(issue_date, '%d-%m-%Y')
> maturity = ql.Date(maturity, '%d-%m-%Y')
> schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
> helper = ql.FixedRateBondHelper(price, settlement_days, faceAmount, schedule, [coupon / 100], day_count,
> False)
> helpers.append(helper)
>
> curve = ql.PiecewiseCubicZero(today, helpers, day_count)
> # Enable Extrapolation:# This line enables extrapolation for the yield curve.# Extrapolation allows the curve to provide interest rates or rates beyond the observed data points,# which can be useful for pricing or risk management purposes.
> curve.enableExtrapolation()
> # Zero Rate and Discount Rate Calculation:# Calculates and prints the zero rate and discount rate at a specific# future date (May 28, 2048) using the constructed yield curve.
> date = ql.Date(28, ql.May, 2024)
> zero_rate = curve.zeroRate(date, day_count, ql.Annual).rate()
> forward_rate = curve.forwardRate(date, date + ql.Period(1, ql.Years), day_count, ql.Annual).rate()
> discount_rate = curve.discount(date)print("Zero rate as at 28.05.2048: " + str(round(zero_rate*100, 4)) + str("%"))print("Forward rate as at 28.05.2048: " + str(round(forward_rate*100, 4)) + str("%"))print("Discount factor as at 28.05.2048: " + str(round(discount_rate, 4)))
> # Print the Zero Rates, Forward Rates and Discount Factors at node dates# print(pd.DataFrame(curve.nodes()))
> node_data = {'Date': [],
> 'Zero Rates': [],
> 'Forward Rates': [],
> 'Discount Factors': []}
> for dt in curve.dates():
> node_data['Date'].append(dt)
> node_data['Zero Rates'].append(curve.zeroRate(dt, day_count, ql.Annual).rate())
> node_data['Forward Rates'].append(curve.forwardRate(dt, dt + ql.Period(1, ql.Years), day_count, ql.Annual).rate())
> node_data['Discount Factors'].append(curve.discount(dt))
>
> node_dataframe = pd.DataFrame(node_data)
> print(node_dataframe)
>
> node_dataframe.to_excel('NodeRates.xlsx')
> # Printing Daily Zero Rates:# Prints the daily zero rates# It calculates and prints the zero rates for each year using the constructed yield curve.
> maturity_date = calendar.advance(today, ql.Period(1, ql.Years))
> current_date = todaywhile current_date <= maturity_date:
> zero_rate = curve.zeroRate(current_date, day_count, ql.Annual).rate()
> print(f"Date: {current_date}, Zero Rate: {zero_rate}")
> current_date = calendar.advance(current_date, ql.Period(1, ql.Years))
> # Creating Curve Data for Plotting:# Creates lists of curve dates, zero rates, and forward rates for plotting.# It calculates both zero rates and forward rates for each year up to 15 years from the current date.
> curve_dates = [today + ql.Period(i, ql.Years)
> for i in range(15)]
> curve_zero_rates = [curve.zeroRate(date, day_count, ql.Annual).rate()
> for date in curve_dates]
> # Converting ql.Date to Numerical Values: (years from today)# Converts the curve dates (ql.Date objects) to numerical values representing years from the current# date. This is done to prepare the data for plotting on the x-axis.
> numeric_dates = [(date - today) / 365 for date in curve_dates]
> # Plotting:# Creates a plot showing the zero rates and forward rates over time.# The x-axis represents the years from the current date, and the y-axis represents the interest rates.# The plot displays two lines: one for zero rates (blue) and another for forward rates (red).# The plot is labeled, grid lines are added, and the visualization is displayed using
> plt.figure(figsize=(10, 6))
> plt.plot(numeric_dates, curve_zero_rates, marker='', linestyle='-', color='b', label='Zero Rates')
> plt.title('Zero Rates')
> plt.xlabel('Years from Today')
> plt.ylabel('Rate')
> plt.legend()
> plt.grid(True)
> plt.xticks(rotation=0)
> plt.tight_layout()
>
> plt.show()
>
> tenors = ['3M', '6M', '9M', '1Y', '2Y', '3Y', '5Y', '7Y', '10Y', '15Y']
> # Print the Zero Rates, Forward Rates, and Discount Factors at Instrument maturity dates
> node_data = {'Maturity Date': [],
> 'Tenors': [],
> 'Zero Rates': [],
> 'Forward Rates': [],
> 'Discount Factors': []}
> for tenor in tenors:
> maturity_date = calendar.advance(today, ql.Period(tenor), ql.ModifiedFollowing) # Calculate the maturity date
> node_data['Maturity Date'].append(maturity_date)
> node_data['Tenors'].append(tenor)
> node_data['Zero Rates'].append(curve.zeroRate(maturity_date, day_count, ql.Annual).rate())
> node_data['Forward Rates'].append(curve.forwardRate(maturity_date, maturity_date + ql.Period(0, ql.Years), day_count, ql.Annual).rate())
> node_data['Discount Factors'].append(curve.discount(maturity_date))
>
> node_dataframe = pd.DataFrame(node_data)
> print(node_dataframe)
>
> node_dataframe.to_excel('NodeRates.xlsx')
> # Create a DataFrame to store bond results
> bond_results = {'Issue Date': [],
> 'Maturity Date': [],
> 'Coupon Rate': [],
> 'Price': [],
> 'Settlement Days': [],
> 'Yield': [],
> 'Clean Price': [],
> 'Dirty Price': []}
> # Calculate bond prices and yieldsfor issue_date, maturity, coupon, price, settlement_days in data:
> price = ql.QuoteHandle(ql.SimpleQuote(price))
> issue_date = ql.Date(issue_date, '%d-%m-%Y')
> maturity = ql.Date(maturity, '%d-%m-%Y')
> schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
> bondEngine = ql.DiscountingBondEngine(curve)
> bond = ql.FixedRateBond(settlement_days, faceAmount, schedule, [coupon / 100], day_count)
> bond.setPricingEngine(bondEngine)
>
> # Calculate bond yield, clean price, and dirty price
> bondYield = bond.bondYield()
> bondCleanPrice = bond.cleanPrice()
> bondDirtyPrice = bond.dirtyPrice()
>
> # Append the results to the DataFrame
> bond_results['Issue Date'].append(issue_date)
> bond_results['Maturity Date'].append(maturity)
> bond_results['Coupon Rate'].append(coupon)
> bond_results['Price'].append(price.value())
> bond_results['Settlement Days'].append(settlement_days)
> bond_results['Yield'].append(bondYield)
> bond_results['Clean Price'].append(bondCleanPrice)
> bond_results['Dirty Price'].append(bondDirtyPrice)
> # Create a DataFrame from the bond results
> bond_results_df = pd.DataFrame(bond_results)
> # Print the resultsprint(bond_results_df)
>
>
> Thanks & regards,
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
>
>
|