簡體   English   中英

在 QuantLib 中使用 fixedRateBond.bondYield 無法獲得正確的收益率

[英]Having trouble to get the right yield with fixedRateBond.bondYield in QuantLib

我試圖弄清楚如何使用 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()
businessConvention = ql.Following
#businessConvention = ql.Unadjusted
dateGeneration = ql.DateGeneration.Backward
monthEnd = False

schedule = ql.Schedule (issueDate, maturityDate, tenor, calendar, businessConvention, businessConvention,
                        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 也會產生錯誤的結果。 但至少有一個解決方法(來自 CookBook)使用曲線來獲得 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 amount: ' + 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

您從彭博社獲得的 7.28% 的 YTM 可能是按年報價的。

yld = fixedRateBond.bondYield(cleanPrice, dayCount, ql.Compounded, ql.Annual)
print(yld)

為您提供以下內容:

0.07277290053367616

並且這個收益產生以下干凈的價格:

print(fixedRateBond.cleanPrice(yld, dayCount, ql.Compounded, ql.Annual))

105.44999787859736

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM