QuantLib-Python:使用适用于VanillaSwap仪器的quantlib Schedule解决非正向时间前移错误

时间:2019-05-17 18:00:07

标签: python quantitative-finance quantlib quantlib-swig

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

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

C++ Quantlib Vanilla Swap: setting future fixing dates and gearing for floating leg的评论中对此进行了处理,但是我没有找到解决此“问题”的正式问题。

试图理解问题,我相信向后生成日期可能是问题的一部分,因为它似乎在创建存根。使用向后生成的交换的开始日期为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)



0 个答案:

没有答案