Срочная структура облигации в python с использованием QuantLib - PullRequest
0 голосов
/ 25 марта 2020

HI Я попытался построить структуру термина, используя python в QuantLib. однако мой вывод выглядит довольно повсеместно, когда я чекаю против страницы BBG. кто-то может посоветовать, если код имеет смысл? также приложенные выходы (и оснастка Bloomberg - последний столбец дает нулевую кривую)

Если вы посмотрите на мой вывод, тенор за 4 года ушел в минус - наверняка невозможно, учитывая ставки номинала. Другие цифры также выглядят по-разному.

Любые советы приветствуются.

enter image description here

enter image description here

import matplotlib
matplotlib.use('macosx')
import matplotlib.pyplot as plt
import QuantLib as ql
import pandas as pd




# Deposit rates
depo_maturities = [ql.Period(1,ql.Months),ql.Period(3,ql.Months),ql.Period(6,ql.Months)]
depo_cpn = [.149,.165,.155] #yields they are trading at




# Coupon Bonds
bond_maturities = [ql.Period(i, ql.Years) for i in range(1,11)]
bond_cpn = [1.5,.5,.75,.1,.625,1.5,1.25,1.625,.875,4.75]
bond_rates = [.106,.114,.151,.187,.252,.214,.272,.311,.4089,.474]
bond_quotes = [101.161,100.896,101.987,103.301,101.926,108.078,107.088,111.111,104.374,144.568]




bond_long_maturities = [ql.Period(12,ql.Years),ql.Period(15,ql.Years),ql.Period(20,ql.Years),ql.Period(25,ql.Years),
                        ql.Period(30,ql.Years),ql.Period(40,ql.Years),ql.Period(50,ql.Years)]
bond_long_cpn = [4.25,4.5,4.25,3.25,1.75,1.75,1.625] #coupons
bond_long_rates = [.593,.667,.767,.858,.848,.669,.543] #yields
bond_long_quotes = [142.974,152.719,162.806,151.432,123.016,135.634,148.58]






'''####### Depo Helpers #########'''


calc_date = ql.Date(24, 3, 2020)
ql.Settings.instance().evaluationDate = calc_date


calendar = ql.UnitedKingdom()
business_convention = ql.Unadjusted
day_count = ql.Thirty360()
end_of_month = True
settlement_days = 0
face_amount = 100
coupon_frequency = ql.Period(ql.Annual)


#Create depo bondhelps
depo_helpers = [ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(r/100.0)),
                                     m,
                                     settlement_days,
                                     calendar,
                                     business_convention,
                                     end_of_month,
                                     day_count )
                for r, m in zip(depo_cpn, depo_maturities)]






'''####### Bonds Helpers #########'''


day_count = ql.Thirty360()
end_of_month = True
settlement_days = 2


# create fixed rate bond helpers from fixed rate bonds
bond_cpn += bond_long_cpn
bond_maturities += bond_long_maturities
bond_quotes += bond_long_quotes
bond_rates += bond_long_rates


bond_helpers = []
for r, m, q in zip(bond_cpn, bond_maturities,bond_quotes):
    termination_date = calc_date + m
    quote = ql.QuoteHandle(ql.SimpleQuote(q))
    schedule = ql.MakeSchedule(calc_date,termination_date,m)
    helper = ql.FixedRateBondHelper(quote,settlement_days,face_amount,schedule,[r/100.0],day_count,business_convention)
    bond_helpers.append(helper)




#The yield curve is constructed by putting the two helpers together.
rate_helpers = depo_helpers + bond_helpers
yieldcurve = ql.PiecewiseLogCubicDiscount(calc_date,rate_helpers, day_count)




#The spot cpn is obtined from yieldcurve object using the zeroRate method.
spots = []
tenors = []
for d in yieldcurve.dates():
    yrs = day_count.yearFraction(calc_date, d)
    compounding = ql.Compounded
    freq = ql.Annual
    zero_rate = yieldcurve.zeroRate(yrs, compounding, freq)
    tenors.append(yrs)
    eq_rate = zero_rate.equivalentRate(day_count,compounding,freq,calc_date,d).rate()
    spots.append(100*eq_rate)




spotcurve = pd.DataFrame(dict(tenors=tenors,spots=spots))
spotcurve.set_index('tenors',inplace=True)


print('\n')
spotcurve = spotcurve.iloc[1:]
pars = depo_cpn+bond_rates
spotcurve['pars'] = pars
spotcurve['spots'] = round(spotcurve['spots'],3)
print(spotcurve)


plt.figure(figsize=(7,4))
plt.plot(spotcurve)#,'b',lw=1.5)
plt.plot(spotcurve,'ro')
plt.grid(True)
plt.xlabel('Tenor')
plt.ylabel('Curves')
plt.show()
...