无法使用quantlib中的fixedratebond.BondFaild获得正确的收益率

wfypjpf4  于 2021-09-08  发布在  Java
关注(0)|答案(0)|浏览(147)

我想知道如何用quantlib的价格来估算债券收益率。有很多不同的例子,但我仍然找不到正确的解决方案。我有一张2039年3月到期的债券,每182天支付一次息票。我将quantlib的计算结果与彭博社和交易所的数据进行了比较。代码如下:

issueDate = ql.Date(19,6,2019) #05.06.2019
maturityDate = ql.Date(16,3,2039) #16.03.2039
cpn_freq = 2
tenor = ql.Period('26W') #ql.Period(ql.Semiannual)
calendar = ql.Russia()
bussinessConvention = ql.Following

# bussinessConvention = ql.Unadjusted

dateGeneration = ql.DateGeneration.Backward
monthEnd = False

schedule = ql.Schedule (issueDate, maturityDate, tenor, calendar, bussinessConvention, bussinessConvention,
                        dateGeneration, monthEnd)

dayCount = ql.Actual365Fixed()

# settings for bond

compounding = ql.Compounded
cleanPrice = 105.45
ytm  = 0.0728
couponRate = 0.077
coupons = [couponRate]
settlementDays = 1
faceValue = 100

fixedRateBond = ql.FixedRateBond(settlementDays, faceValue, schedule, coupons, dayCount)

for c in fixedRateBond.cashflows():
    print('%20s %12f' % (c.date(), c.amount()))

它产生了与彭博类似的结果(相同的息票日期和金额-3.839):

October 9th, 2019     2.658082
     April 8th, 2020     3.839452
   October 7th, 2020     3.839452
     April 7th, 2021     3.839452
   October 6th, 2021     3.839452
     April 6th, 2022     3.839452
   October 5th, 2022     3.839452
     April 5th, 2023     3.839452
   October 4th, 2023     3.839452
     April 3rd, 2024     3.839452
   October 2nd, 2024     3.839452
     April 2nd, 2025     3.839452
   October 1st, 2025     3.839452
     April 1st, 2026     3.839452
September 30th, 2026     3.839452
    March 31st, 2027     3.839452
September 29th, 2027     3.839452
    March 29th, 2028     3.839452
September 27th, 2028     3.839452
    March 28th, 2029     3.839452
September 26th, 2029     3.839452
    March 27th, 2030     3.839452
September 25th, 2030     3.839452
    March 26th, 2031     3.839452
September 24th, 2031     3.839452
    March 24th, 2032     3.839452
September 22nd, 2032     3.839452
    March 23rd, 2033     3.839452
September 21st, 2033     3.839452
    March 22nd, 2034     3.839452
September 20th, 2034     3.839452
    March 21st, 2035     3.839452
September 19th, 2035     3.839452
    March 19th, 2036     3.839452
September 17th, 2036     3.839452
    March 18th, 2037     3.839452
September 16th, 2037     3.839452
    March 17th, 2038     3.839452
September 15th, 2038     3.839452
    March 16th, 2039     3.839452
    March 16th, 2039   100.000000

但是,试图计算ytd时给出了错误的数字:

fixedRateBond.bondYield(cleanPrice, dayCount, ql.Compounded, ql.Semiannual) * 100

7.170206456184388

但应该是7.28%。如果我尝试改用: fixedRateBond.bondYield(cleanPrice, dayCount, ql.Compounded, ql.Period('26W')) * 100 我有一个错误:

Possible C/C++ prototypes are:
    Bond::yield(DayCounter const &,Compounding,Frequency,Real,Size)
    Bond::yield(DayCounter const &,Compounding,Frequency,Real)
    Bond::yield(DayCounter const &,Compounding,Frequency)
    Bond::yield(Real,DayCounter const &,Compounding,Frequency,Date const &,Real,Size)
    Bond::yield(Real,DayCounter const &,Compounding,Frequency,Date const &,Real)
    Bond::yield(Real,DayCounter const &,Compounding,Frequency,Date const &)
    Bond::yield(Real,DayCounter const &,Compounding,Frequency)

更新:如果与实际ytm一起使用,clearprice和dirtyprice似乎也会产生错误的结果。但至少有一个解决办法(来自烹饪书)使用曲线来获得正确的clearprice和dirtyprice数据。但我仍然很难找到ytm的正确号码。

bond_yield = fixedRateBond.bondYield(cleanPrice, dayCount, compounding,  ql.Semiannual )* 100
bond_dp = fixedRateBond.dirtyPrice(ytm, dayCount, ql.Compounded, ql.Semiannual)
bond_cp = fixedRateBond.cleanPrice(ytm, dayCount, ql.Compounded, ql.Semiannual)
bond_dur = ql.BondFunctions.duration(fixedRateBond,0.0731,dayCount, ql.Compounded,ql.Semiannual, ql.Duration.Modified)

print('Yield: ' + str(bond_yield)) #ql.Period('26W')
print('Dirty price: ' + str(bond_dp))
print('Clean price: ' + str(bond_cp))
print('Accrued ammount: ' + str(fixedRateBond.accruedAmount()))
print('Day counter: ' + str(fixedRateBond.dayCounter()))
print('Settlement date: ' + str(fixedRateBond.settlementDate()))
print('Dutation: ' + str(bond_dur))

print('Using curve')

flat_curve = FlatForward(fixedRateBond.settlementDate(), ytm, dayCount, Compounded)
engine = DiscountingBondEngine(YieldTermStructureHandle(flat_curve))
fixedRateBond.setPricingEngine(engine)
P2 = fixedRateBond.dirtyPrice()
print('Dirty price: ' +str(P2))
print('Cleand price: '+str(fixedRateBond.cleanPrice()))
print('YTM:' + str(fixedRateBond.bondYield(dayCount, Compounded,2)))

Yield: 7.150867552757262
Dirty price: 106.15244992161799
Clean price: 104.12724444216592
Accrued amount: 2.0252054794520635
Day counter: Actual/365 (Fixed) day counter
Settlement date: July 12th, 2021
Duration: 9.550427694884139

Using curve:
Dirty price: 107.46228302550196
Clean price: 105.43707754604989
YTM:0.07152117539749295

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题