问题描述
我正在尝试使用QuantLib Python为摊销浮动利率债券定价。
下面是我的代码:
notional = [3640875000,3640875000,3380812500,3120750000,2860687500,2600625000,2340562500,2080500000,1820437500,1560375000,1300312500,1040250000,780187500,520125000,260062500]
tenor = ql.Semiannual
calendar = ql.UnitedStates()
valuationDate = ql.Date(30,6,2020)
ql.Settings.instance().evaluationDate = valuationDate
issueDate = ql.Date(1,2,2020)
maturityDate = ql.Date(1,2031)
spread = 0.0008
schedule = ql.Schedule(issueDate,maturityDate,ql.Period('6M'),ql.UnitedStates(),ql.ModifiedFollowing,ql.DateGeneration.Forward,False)
myDates = [ql.Date(30,2020),ql.Date(3,8,ql.Date(1,2021),ql.Date(2,2022),2023),2024),2025),2026),2027),2028),2029),2030),2031)]
fwds = [0.030299999999999997,0.025,0.01354543171228029,0.019589368178700814,0.01958777464424011,0.02057467941338146,0.025178974367120032,0.025177220897067684,0.02517897436712047,0.02509806907076861,0.02476222313506464,0.024759679154385567,0.024762223135064203,0.024760527109263717,0.024903682036959026,0.025577044856498768,0.025574331077211018]
fwdcurve = ql.ForwardCurve(myDates,fwds,ql.Actual360(),ql.UnitedStates())
fwdhandle = ql.YieldTermStructureHandle(fwdcurve)
index = ql.IborIndex('MyIndex',ql.USDCurrency(),True,fwdhandle)
index.addFixing(ql.Date(30,1,2.98/100)
amortizingfloatbond = ql.AmortizingFloatingRateBond(0,notional,schedule,index,[spread])
dates = [ql.Date(30,ql.Date(30,12,2035),2040)]
zeros = [0.0091,0.0090,0.0104,0.0194,0.0135,0.0425,0.0379,0.0317]
curve = ql.ZeroCurve(dates,zeros,ql.UnitedStates())
discount_handle = ql.YieldTermStructureHandle(curve)
discount = ql.discountingBondEngine(discount_handle)
amortizingfloatbond.setPricingEngine(discount)
for i,cf in enumerate(amortizingfloatbond.cashflows()):
print((i + 1),cf.date(),cf.amount())`
我根据现有数据构造了零曲线和远期曲线,并使用远期利率构建了ibor指数,并使用零利率对现金流量进行了折现。
以下现金流量是从QuantLib Python获得的:
[1840664583.3333333,1840664583.3333333,1850778125.0,1830551041.6666667,1860891666.6666665,260062500.0,1746753124.9999998,1551706250.0,1470075520.8333333,1314760416.6666665,1183284375.0,1051808333.3333333,925389062.5,788856250.0,664604166.6666666,523014583.3333333,398762499.99999994,261507291.66666666,134365624.99999997,260062500.0]
截至以下日期:
[Date(3,Date(1,Date(2,Date(3,2031),2031)]
截至2020年8月3日的正确现金流量应为: ((0.025 *(34/360))+ 0.0008)* 3640875000 = 37723510.42
我的代码有什么问题,我该如何继续使用QuantLib和Python计算摊销浮动利率债券的正确现金流量?
另外,请建议如何显示我的ibor指数的汇率。
我们将不胜感激LB或GB的任何帮助!
谢谢。
AA
解决方法
这是QuantLib包装器中的问题和代码中的错误调用的组合。
在您的代码中,您拥有
amortizingfloatbond = ql.AmortizingFloatingRateBond(0,notional,schedule,index,ql.Actual360(),ql.ModifiedFollowing,2,[spread])
您传递的最后一个参数是齿轮的位置,而不是价差;因此该债券支付0.0008 * Libor +默认利差。不幸的是,默认跨度为1,而不是0(可能是由于齿轮引起的复制粘贴错误,对于它,正确的默认值为1)。最后,您的债券最终支付了0.0008 * Libor + 100%,从而产生了荒唐的现金流。
要绕过问题并正确初始化绑定,可以使用调用
amortizingfloatbond = ql.AmortizingFloatingRateBond(
0,spreads=[spread])
可以正确设置点差。
此时,第一张优惠券的金额为56324336.25,这是正确的;您的期望值公式应进行修改。首先,LIBOR的固定值为0.0298,您用
指定index.addFixing(ql.Date(30,1,2020),2.98/100)
第二个不是((0.0298 * T)+ 0.0008);它是(0.0298 + 0.0008)* T,其中点差也乘以应计时间。最后,时间不是34/360;在评估日期和优惠券的付款日期之间有34天,但是现金流量基于优惠券的长度,即6个月,或更精确的说是182天。因此:(0.0298 + 0.0008)*(182/360)* 3640875000 = 56324336.25,这是返回的金额。
最后:要显示费率,请使用
for i,cf in enumerate(amortizingfloatbond.cashflows()):
c = ql.as_floating_rate_coupon(cf)
if c:
print((i + 1),c.rate(),c.indexFixing(),c.fixingDate())