程式

使用 QuantLib Python 在臟價格和 NPV 之間產生的差異

  • August 13, 2021

我使用 QuantLib Python 為固定利率債券定價。

我的程式碼如下:

import QuantLib as ql

valuationDate = ql.Date(30, 6, 2020)
ql.Settings.instance().evaluationDate = valuationDate
compounding = ql.Continuous
calendar = ql.UnitedStates()
coupon = 0.05
couponFrequency = ql.Annual
issueDate = ql.Date(7, 5, 2016)
maturityDate = ql.Date(7, 5, 2024)
settlementDays = 2
settlementDate = calendar.advance(issueDate, ql.Period(settlementDays, ql.Days))
dayCount = ql.ActualActual(ql.ActualActual.ISMA)
fixedRateBond = ql.FixedRateBond(settlementDays, calendar, 100.0, issueDate, maturityDate, ql.Period(couponFrequency), [coupon], dayCount, ql.Unadjusted, ql.Unadjusted)
curve = ql.FlatForward(valuationDate, ql.QuoteHandle(ql.SimpleQuote(0.02)), dayCount, compounding)
handle = ql.YieldTermStructureHandle(curve)
bondEngine = ql.DiscountingBondEngine(handle)
fixedRateBond.setPricingEngine(bondEngine)
bondYield = fixedRateBond.bondYield(dayCount, compounding, couponFrequency)
cleanPrice = fixedRateBond.cleanPrice()
dirtyPrice = fixedRateBond.dirtyPrice()
print('NPV:', fixedRateBond.NPV())
print('Bond Yield:', bondYield)
print('Clean Price:', cleanPrice)
print('Dirty Price:', dirtyPrice)
print('Accrued Interest:', fixedRateBond.accruedAmount())
print('Actual Accrued Amount', dirtyPrice - cleanPrice)

我得到的結果如下:

淨現值:111.7127354483437

債券收益率:0.01989558171322524

淨價:110.9578553230744

臟價:111.72497861074564

應計利息:0.767123287671234

實際應計金額 0.7671232876712395

但是,我注意到了一些差異:

  1. 據我所知,NPV 應該等於臟價格,但是,這裡不是這樣。
  2. QuantLib 的accruedAmount功能不等於dirtyPrice減去cleanPrice.

有人可以解釋我哪裡出錯了嗎?

謝謝。

正如@AKdemy 所說,在浮點數學的精度範圍內,兩個應計金額是相同的。

和方法返回兩個略有不同的數量:將現金流貼現NPV到貼現曲線的參考日期(在您的情況下為估值日期),同時貼現到債券的結算日期。如果在估值日期和結算日期之間支付息票,這也會導致更大的差異:在這種情況下,息票金額將包含在 NPV 中,但不包含在價格中。dirtyPrice``NPV``dirtyPrice

注意:債券的結算日期不是你定義的那個settlementDate。相反,它是估值日期後兩天,而不是發行日期,所以應該是

settlementDate = calendar.advance(valuationDate, ql.Period(settlementDays, ql.Days))

或者,一旦你建立了聯繫,

settlementDate = bond.settlementDate()

您可能想要更改的另一件事:在期限結構中使用 act/act(ISMA) 是有風險的(請參閱https://www.youtube.com/watch?v=dQjd3hAshj4)。如果您需要使用它,您應該首先創建債券的時間表,這樣您就可以將其傳遞給日期計數器:

schedule = ql.Schedule(issueDate, maturityDate, ql.Period(couponFrequency), calendar, ql.Unadjusted, ql.Unadjusted, ql.DateGeneration.Forward, True)
dayCount = ql.ActualActual(ql.ActualActual.ISMA, schedule)
fixedRateBond = ql.FixedRateBond(settlementDays, 100.0, schedule, [coupon], dayCount)

這樣,當日計數器就有了有關優惠券參考期間的資訊,這是行為/行為計算規則所要求的。

完成上述兩項更改後,您可以檢查 和 之間的NPV區別dirtyPrice。如果設置settlementDays為 0,臟價格應該等於 NPV,因為在這兩種情況下,現金流都將折現到估值日期;相反,如果您將settlementDate上面的值傳遞給曲線,則 NPV 應該等於臟價格,因為兩者都將在結算日期打折。

引用自:https://quant.stackexchange.com/questions/66419