QuantLib 的遠期債券收益率
我正在研究使用 QuantLib 計算遠期債券收益率的方法。在 Python QuantLib 書中,我看到了一個債券期貨的例子,其中
futures = ql.FixedRateBondForward(calc_date, futures_maturity_date, ql.Position.Long, 0.0, settlement_days, day_count, calendar, business_convention, ctd_bond, yield_curve_handle, yield_curve_handle) implied_yield = futures.impliedYield(ctd_price/ctd_cf, futures_price, calc_date, ql.Compounded, day_count).rate()
做這樣的事情是否正確?
fwd= ql.FixedRateBondForward(calc_date, fwd_date, ql.Position.Long, 0.0, settlement_days, day_count, calendar, business_convention, bond, yield_curve_handle, yield_curve_handle) fwd_price = fwd.cleanForwardPrice() fwd_yield = fwd.impliedYield(bond_spot_price, fwd_price, calc_date, ql.Compounded, day_count).rate()
您的問題的直接答案實際上是否定的,如果您想要的只是遠期起始債券的收益率,這裡有一些其他方法可以獲得遠期債券收益率(我假設它是您想要的遠期起始債券,即不中間現金流)
import QuantLib as ql today = ql.Date().todaysDate() calendar = ql.NullCalendar() dayCounter = ql.ActualActual() dates = [today, ql.Date(28,10,2021), ql.Date(28,10,2022), ql.Date(28,10,2025)] zeros = [0.01, 0.02, 0.03, 0.04] crv = ql.LogLinearZeroCurve(dates, zeros, dayCounter, calendar) yts = ql.YieldTermStructureHandle(crv) engine = ql.DiscountingBondEngine(yts)
定義一個簡單的正向起始債券,您可以從它的價格 (npv) 中獲得債券收益率。
issueDate = today + ql.Period('2Y') maturityDate = issueDate + ql.Period('2Y') bond = ql.FixedRateBond(0, calendar, 100.0, issueDate, maturityDate, ql.Period('1Y'), [0.05], dayCounter) bond.setPricingEngine(engine) bondPrice = bond.NPV() print(f"Bond Price: {bondPrice:.5f}") bondYield = bond.bondYield(bondPrice, dayCounter, ql.Compounded, ql.Annual) print(f"Bond Yield: {bondYield:.3%}")
債券價格:95.32379
債券收益率:3.689%
然而,這將是現在開始的收益率,而不是遠期收益率。
您使用的方法:
fwd = ql.FixedRateBondForward(today, issueDate, ql.Position.Long, 100, 2, dayCounter, ql.TARGET(), ql.Following, bond, yts, yts) fwdPrice = fwd.cleanForwardPrice() fwdYield = fwd.impliedYield(bondPrice, fwdPrice, today, ql.Compounded, dayCounter).rate() print(f"Fwd Yield: {fwdYield:.3%}")
正向收益率:3.045%
也不會給你遠期收益。根據 QuantLib 文件,implicitYield 方法給出:
“基於基礎現貨和遠期價值的簡單收益率計算,考慮到基礎收益。當 t>0 時,呼叫:底層現貨價值=現貨價值(t),前向價值=罷工價格,以獲得目前收益率。對於回購,如果 t=0 ,implicitYield 應重現即期回購利率。對於 FRA,這應重現 FRA 到期日的相關零利率"
所以如果你給它提供bondPrice和遠期債券價格,你基本上會得到零利率。事實上,由於遠期債券價格只是複合債券價格:
print(fwdPrice) print(bondPrice * crv.discount(issueDate)**-1)
101.21680137389713
101.21680137389713:
zeroRate = crv.zeroRate(issueDate, dayCounter, ql.Compounded).rate() print(f"Zero Rate: {zeroRate:.3%}")
零利率:3.045%
你可以做的是建立遠期債券的現金流:
cfs = ql.Leg([ql.AmortizingPayment(-100, issueDate)] + [*bond.cashflows()][:-1]) bond2 = ql.Bond(2, calendar, today, cfs) bond2.setPricingEngine(engine) for cf in bond2.cashflows(): print(cf.date().ISO(), cf.amount())
2022-10-28 -100.0
2023-10-28 5.000000000000004
2024-10-28 5.002432816827618
2024-10-28 100.0
並得到它的產量:
fwdYield = bond2.bondYield(bond2.NPV(), dayCounter, ql.Compounded, ql.Annual) print(f"Fwd Yield: {fwdYield:.3%}")
正向收益率:4.336%
如果你不知道優惠券,你可以從曲線中得到每年復利:
fwdRate = crv.forwardRate(issueDate, maturityDate, dayCounter, ql.Compounded, ql.Annual).rate() print(f"Fwd Rate: {fwdRate:.3%}")
轉發率:4.361%
這或多或少:
$$ fwd = \frac{DF_0 - DF_T}{\sum^T_{i=1} DF_i} $$
其中 i 是現金流量日期,T 是到期日
dates = ql.MakeSchedule(issueDate, maturityDate, ql.Period('1Y'), ) dfs = [crv.discount(date) for date in dates] fwdRate2 = (dfs[0]-dfs[-1])/ sum(dfs[1:]) print(f"Fwd Rate: {fwdRate2:.3%}")
轉發率:4.354%