使用 QuantLib Python 在臟價格和 NPV 之間產生的差異
我使用 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
但是,我注意到了一些差異:
- 據我所知,NPV 應該等於臟價格,但是,這裡不是這樣。
- 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 應該等於臟價格,因為兩者都將在結算日期打折。