ส่งต่อผลตอบแทนพันธบัตรด้วย QuantLib

Oct 28 2020

ฉันกำลังหาวิธีคำนวณผลตอบแทนพันธบัตรล่วงหน้าโดยใช้ 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()
```

คำตอบ

4 DavidDuarte Oct 28 2020 at 21:58

คำตอบโดยตรงสำหรับคำถามของคุณคือไม่และนี่คือวิธีอื่น ๆ ในการรับผลตอบแทนพันธบัตรล่วงหน้าหากสิ่งที่คุณต้องการคือผลตอบแทนของพันธบัตรเริ่มต้นไปข้างหน้า (ฉันสมมติว่ามันเป็นพันธบัตรเริ่มต้นไปข้างหน้าที่คุณต้องการนั่นคือไม่ใช่ กระแสเงินสดระดับกลาง)

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%}")

อัตราผลตอบแทน Fwd: 3.045%

ยังจะไม่ให้ผลตอบแทนล่วงหน้า ตามเอกสาร QuantLib วิธีการโดยนัยให้:

"การคำนวณผลตอบแทนอย่างง่ายตามจุดอ้างอิงและมูลค่าส่งต่อโดยคำนึงถึงรายได้พื้นฐานเมื่อ t> 0 ให้เรียกด้วย: underlyingSpotValue = spotValue (t), forwardValue = strikePrice เพื่อให้ได้ผลตอบแทนปัจจุบันสำหรับ repo ถ้า t = 0 , โดยนัย Yield ควรสร้างอัตราการซื้อคืนเฉพาะจุดสำหรับ FRA สิ่งนี้ควรจำลองอัตราศูนย์ที่เกี่ยวข้อง ณ วันครบกำหนดของ FRA "

ดังนั้นหากคุณป้อนพันธบัตรราคาและราคาพันธบัตรล่วงหน้าโดยทั่วไปคุณจะได้รับอัตราศูนย์ และอันที่จริงเนื่องจากราคาพันธบัตรล่วงหน้าเป็นเพียงราคาพันธบัตรทบต้น:

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%}")

อัตราผลตอบแทน Fwd: 4.336%

หากคุณไม่ทราบคูปองคุณสามารถได้รับการทบไปข้างหน้าทุกปีจากเส้นโค้ง:

fwdRate = crv.forwardRate(issueDate, maturityDate, dayCounter, ql.Compounded, ql.Annual).rate()
print(f"Fwd Rate: {fwdRate:.3%}")

อัตรา Fwd: 4.361%

ซึ่งจะมากหรือน้อย:

$$ fwd = \frac{DF_0 - DF_T}{\sum^T_{i=1} DF_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%}")

อัตรา Fwd: 4.354%