QuantLib經過回測後返回的bondYield略有不同


1

我才剛剛開始熟悉QuantLib(特別是固定利率債券定價功能)。我閱讀了許多示例,從中可以計算出債券價格和債券收益率。

以下腳本使用bond.cleanPrice使用輸入收益率(0.057154825761367800000)計算債券價格(96.9073930899788536)。

然後,我將計算出的債券價格作為價格,然後將其反饋回bond.bondYield計算(其他輸入不變),期望恢復我的原始輸入收益率。

我發現反向計算的收益率很接近,但沒有我天真地期望的收益率(它匹配8個小數位)。我做錯什麼了嗎?這個可接受的精度是否基於數值求解器的最大迭代次數?還有嗎?

import QuantLib as ql


def calculate_bond_price():

    settlementDays = 0
    faceValue = 100

    issueDate = ql.Date(11, 2, 2020)
    maturityDate = ql.Date(11, 2, 2025)
    tenor = ql.Period(ql.Quarterly)
    calendar = ql.NullCalendar()
    businessConvention = ql.Following
    dateGeneration = ql.DateGeneration.Backward
    monthEnd = False
    schedule = ql.Schedule (issueDate, maturityDate, tenor, calendar, businessConvention, businessConvention, dateGeneration, monthEnd)

    coupon_rate = 0.05
    coupons = [coupon_rate]

    dayCount = ql.Thirty360()

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

## manually specify a yield rate to 16 decimal places
## this is the value I expect to get back from bond.bondYield calculation
    yield_rate = 0.057154825761367800000

    bond_price = bond.cleanPrice(yield_rate, dayCount, ql.Simple, ql.Quarterly)
    print(f'PRICE >> calculated={bond_price:20,.16f}')
    # OUTPUTS: PRICE >> calculated= 96.9073930899788536

# feed the calculated bond price back into a bond.bondYield calculation with exact same (dayCount, Simple, Quarterly) inputs
# expect to get back the yield_rate (16 decimal); but only match to 8 decimals
    back_calculate_bond_yield = bond.bondYield(bond_price, dayCount, ql.Simple, ql.Quarterly)
    print(f'YIELD >> calculated={back_calculate_bond_yield:20,.16f} | expected={yield_rate:20,.16f} | diff={back_calculate_bond_yield-yield_rate:20,.16f}')
    # OUTPUTS: YIELD >> calculated=  0.0571548314094543 | expected=  0.0571548257613678 | diff=  0.0000000056480865


if __name__ == '__main__':
    calculate_bond_price()
4

I would start by saying that yes, this is an acceptable precision.

However, the reason you are not getting the same result is because, by default, QuantLib has accuracy=1.0e-8 and maxEvaluations=100.

You can set these parameters like this:

bond.bondYield(bond_price, dayCount, ql.Simple, ql.Quarterly, ql.Date(), 1.0e-16, 100)

This will get you much closer...

YIELD >> calculated= 0.0571548257613679 | expected= 0.0571548257613678 | diff= 0.0000000000000001