繁体   English   中英

使用 QuantLib 和 Python 为摊销浮动利率债券定价

[英]Pricing an Amortizing Floating Rate Bond using QuantLib and Python

我正在尝试使用 QuantLib Python 为摊销浮动利率债券定价。

下面是我的代码:

notional = [3640875000, 3640875000, 3640875000, 3640875000, 3640875000, 3640875000, 3640875000, 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, 2, 2031)
spread = 0.0008
schedule = ql.Schedule(issueDate, maturityDate, ql.Period('6M'), ql.UnitedStates(), ql.ModifiedFollowing, ql.ModifiedFollowing, ql.DateGeneration.Forward, False)
myDates = [ql.Date(30,6,2020), ql.Date(3,8,2020), ql.Date(1,2,2021), ql.Date(2,8,2021), ql.Date(1,2,2022), ql.Date(1,8,2022), ql.Date(1,2,2023), ql.Date(1,8,2023), ql.Date(1,2,2024), ql.Date(1,8,2024), ql.Date(3,2,2025), ql.Date(1,8,2025), ql.Date(2,2,2026), ql.Date(3,8,2026), ql.Date(1,2,2027), ql.Date(2,8,2027), ql.Date(1,2,2028), ql.Date(1,8,2028), ql.Date(1,2,2029), ql.Date(1,8,2029), ql.Date(1,2,2030), ql.Date(1,8,2030), ql.Date(3,2,2031)]
fwds = [0.030299999999999997, 0.025, 0.01354543171228029, 0.019589368178700814, 0.01958777464424011, 0.019589368178700814, 0.02057467941338146, 0.025178974367120032, 0.025177220897067684, 0.02517897436712047, 0.02509806907076861, 0.02476222313506464, 0.024759679154385567, 0.02476222313506464, 0.024759679154385567, 0.024762223135064203, 0.024760527109263717, 0.02476222313506464, 0.024759679154385567, 0.024762223135064203, 0.024903682036959026, 0.025577044856498768, 0.025574331077211018]
fwdcurve = ql.ForwardCurve(myDates, fwds, ql.Actual360(), ql.UnitedStates())
fwdhandle = ql.YieldTermStructureHandle(fwdcurve)
index = ql.IborIndex('MyIndex', ql.Period('6M'), 0, ql.USDCurrency(), ql.UnitedStates(), ql.ModifiedFollowing, True, ql.Actual360(), fwdhandle)
index.addFixing(ql.Date(30, 1, 2020), 2.98/100)
amortizingfloatbond = ql.AmortizingFloatingRateBond(0, notional, schedule, index, ql.Actual360(), ql.ModifiedFollowing, 2, [spread])
dates = [ql.Date(30, 6, 2020), ql.Date(30, 12, 2020), ql.Date(30, 6, 2021), ql.Date(30, 6, 2023), ql.Date(30, 6, 2025), ql.Date(30, 6, 2030), ql.Date(30, 6, 2035), ql.Date(30, 6, 2040)] 
zeros = [0.0091, 0.0090, 0.0104, 0.0194, 0.0135, 0.0425, 0.0379, 0.0317]
curve = ql.ZeroCurve(dates, zeros, ql.Actual360(), 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, 1840664583.3333333, 1850778125.0, 1830551041.6666667, 1860891666.6666665, 1830551041.6666667, 1860891666.6666665, 1840664583.3333333, 260062500.0, 1746753124.9999998, 260062500.0, 1551706250.0, 260062500.0, 1470075520.8333333, 260062500.0, 1314760416.6666665, 260062500.0, 1183284375.0, 260062500.0, 1051808333.3333333, 260062500.0, 925389062.5, 260062500.0, 788856250.0, 260062500.0, 664604166.6666666, 260062500.0, 523014583.3333333, 260062500.0, 398762499.99999994, 260062500.0, 261507291.66666666, 260062500.0, 134365624.99999997, 260062500.0]

截至以下日期:

[Date(3,8,2020), Date(1,2,2021), Date(2,8,2021), Date(1,2,2022), Date(1,8,2022), Date(1,2,2023), Date(1,8,2023), Date(1,2,2024), Date(1,8,2024), Date(1,8,2024), Date(3,2,2025), Date(3,2,2025), Date(1,8,2025), Date(1,8,2025), Date(2,2,2026), Date(2,2,2026), Date(3,8,2026), Date(3,8,2026), Date(1,2,2027), Date(1,2,2027), Date(2,8,2027), Date(2,8,2027), Date(1,2,2028), Date(1,2,2028), Date(1,8,2028), Date(1,8,2028), Date(1,2,2029), Date(1,2,2029), Date(1,8,2029), Date(1,8,2029), Date(1,2,2030), Date(1,2,2030), Date(1,8,2030), Date(1,8,2030), Date(3,2,2031), Date(3,2,2031)]

截至 2020 年 8 月 3 日的正确现金流量应为:((0.025 * (34/360)) + 0.0008) * 3640875000 = 37723510.42

我的代码有什么问题,我应该如何使用 QuantLib 和 Python 计算摊销浮动利率债券的正确现金流?

另外,请建议如何显示我的 ibor 指数中的利率。

来自 LB 或 GB 的任何帮助将不胜感激!

谢谢你。

机管局

这是 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, notional, schedule, index, ql.Actual360(), ql.ModifiedFollowing, 2, 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())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM