QuantLibPython:使用VanillaSwap instrumen的quantlib调度解决非正时间前向错误

2024-03-29 12:01:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在QuantLib环境中使用自举曲线为远期掉期定价。对于我的评估日期2019-04-04,曲线引导运行如预期。我还能够轻松定价10年期远期启动掉期。当远期定价出现问题时,尝试用15Y互换。假设我的结算是t+2(2019-04-08),我使用结算日期和日历对象找到掉期的远期开始日期,错误似乎主要发生在我的远期开始日期在周末时,因此使用下一个工作日作为开始日期。在我们的例子中,2034-04-08是一个星期六,所以我们最终将交换的开始日期定为2034-04-10。然后引发此错误:

无法计算2034年4月11日至2034年4月11日之间的远期汇率: 使用实际/360天计数器的非正时间(0)

在这里的评论中提到了这一点,但我没有找到一个正式的问题来解决这个“问题”。在

为了理解这个问题,我相信落后的一代可能是问题的一部分,因为它似乎创建了一个存根。使用反向发电的掉期开始日期是2034年4月11日,而我提供的掉期开始日期是2034年4月10日。这在我的日程表中都有显示(固定和浮动)。在

在我的进一步研究中,我在这里寻找“存根”:https://leanpub.com/quantlibpythoncookbook/read,发现了我认为是答案的一部分。Schedule构造函数允许指定短/长的前/后存根,但是即使我将firstDate指定为2034年4月11日,也会抛出相同的错误。这是复制错误的完整代码。正如你所见,我的日程安排包括2034年4月10日和2034年4月11日,我相信这就是我的问题所在。我仍然不明白为什么以及如何解决这个问题。在


import QuantLib as ql

# my quotes
nodes=(
 (ql.Date( 4, 4, 2019 ), 1.0),
 (ql.Date( 8, 4, 2020 ), 0.9744804179560926),
 (ql.Date( 8, 4, 2021 ), 0.9523386108738999),
 (ql.Date( 8, 4, 2022 ), 0.9315169815568433),
 (ql.Date( 11, 4, 2023 ), 0.910405285996171),
 (ql.Date( 8, 4, 2024 ), 0.8892891964251837),
 (ql.Date( 8, 4, 2025 ), 0.8676501405451038),
 (ql.Date( 8, 4, 2026 ), 0.8457795884699698),
 (ql.Date( 8, 4, 2027 ), 0.8237398951999767),
 (ql.Date( 10, 4, 2028 ), 0.801457566049863),
 (ql.Date( 9, 4, 2029 ), 0.7795144954869505),
 (ql.Date( 8, 4, 2031 ), 0.7362944371445531),
 (ql.Date( 11, 4, 2034 ), 0.6755019523836218),
 (ql.Date( 12, 4, 2039 ), 0.5864073271433347),
 (ql.Date( 8, 4, 2044 ), 0.5120023623536163),
 (ql.Date( 8, 4, 2049 ), 0.4479312303231183),
 (ql.Date( 8, 4, 2059 ), 0.34859916237300465),
 (ql.Date( 8, 4, 2069 ), 0.2788046487083811))

node_dates, node_rates = zip(*nodes)

# Construct the discount curve
curve = ql.DiscountCurve(node_dates, node_rates, ql.Actual360(), ql.UnitedStates())
termStruct = ql.RelinkableYieldTermStructureHandle()
termStruct.linkTo(curve)


curve_date = ql.Date(4,4,2019) # the curve date
settlement = ql.Period(2,
                       ql.Days)

settle_date = ql.UnitedStates().advance(curve_date,
                                        settlement) # the settlement date, assume t+2 settlement

fwdstart = ql.UnitedStates().advance(settle_date,
                                     ql.Period(15,ql.Years)) # forward start date of swap

fwdend = ql.UnitedStates().advance(fwdstart,
                                    ql.Period(5,ql.Years)) # forwrad end date of swap

fixedSchedule = ql.Schedule( fwdstart,  # forward start
                             fwdend,  # forward end
                             ql.Period('6M'),  # period tenor
                             ql.UnitedStates(),  # calendar
                             ql.ModifiedFollowing,  # convention
                             ql.ModifiedFollowing,  # termination date convention
                             ql.DateGeneration.Backward,  # date generation
                             True  # EoM
                             )
print('\n' + 10*'*' + ' Fixed Schedule ' + 10*'*')
for d in fixedSchedule:
    print(d)
print(40*'*')

floatingSchedule = ql.Schedule( fwdstart,  # forward start
                                fwdend,  # forward end
                                ql.Period('3M'),  # period tenor
                                ql.UnitedStates(),  # calendar
                                ql.ModifiedFollowing,  # convention
                                ql.ModifiedFollowing,  # termination date convention
                                ql.DateGeneration.Backward,  # date generation
                                True  # EoM
                                )

print('\n' + 10*'*' + ' Floating Schedule ' + 10*'*')
for d in floatingSchedule:
    print(d)
print(40*'*')

forwardswap = ql.VanillaSwap( type=ql.VanillaSwap.Receiver,  # direction
                              nominal=1E8,  # notional
                              fixedSchedule=fixedSchedule,  # fixed schedule
                              fixedRate=0.023,  # fixed rate
                              fixedDayCount=ql.Actual360(),  # fixed leg basis
                              floatSchedule=floatingSchedule,  # floating schedule
                              index=ql.USDLibor(ql.Period('3M')),
                              spread=0.0,  # spread
                              floatingDayCount=ql.Thirty360() # float leg basis
                              )

swap_engine = ql.DiscountingSwapEngine(termStruct)
forwardswap.setPricingEngine(swap_engine)




Tags: nodedate错误periodscheduleforwardprintcurve