【问题标题】:Using QuantLib to compute cash flows for floored FloatingRateBonds使用 QuantLib 计算下限 FloatingRateBonds 的现金流
【发布时间】:2017-02-16 23:41:49
【问题描述】:

我遇到了从有底债券产生现金流的问题。

我最初遇到了一个问题,因为我忽略了设置定价器。从那以后,我设置了一个如下的定价器。

ql_bond = QuantLib.FloatingRateBond(settlement_days, #settlementDays
                                face_amount, # faceAmount
                                ql_schedule,
                                ql_index,
                                QuantLib.Thirty360(),
                                gearings = [],
                                spreads = [libor_spread],
                                caps = [],
                                floors = [libor_floor]
    )

    volatility = 0
    vol = QuantLib.ConstantOptionletVolatility(settlement_days,
                                           QuantLib.UnitedKingdom(),
                                           QuantLib.Unadjusted,
                                           volatility,
                                           QuantLib.Thirty360())

    pricer = QuantLib.BlackIborCouponPricer(QuantLib.OptionletVolatilityStructureHandle(vol))
    QuantLib.setCouponPricer(ql_bond.cashflows(), pricer)

对于某些现金流,我能够为现金流生成合理的金额。但是,其他时候我遇到错误。罢工的值 (-.0225) 等于 libor_floor - libor_spread。我很确定我在这里犯了一个明显的错误,但不知道从哪里开始。如果任何更熟悉 QuantLib 的人有任何建议,他们将不胜感激。

Traceback (most recent call last):
  File "C:\Users\Ryan\git\optimizer\src\calcs\cashflow_calcs.py", line 161, in generate_cashflow
    cashflows.append(utils.cashflow.InterestCashflow(cf_date, cf.amount(), cf_fixing_date, c.indexFixing(), c.accrualDays()))
  File "C:\Users\Ryan\Anaconda3\lib\site-packages\QuantLib\QuantLib.py", line 8844, in amount
    return _QuantLib.CashFlow_amount(self)
RuntimeError: strike + displacement (-0.0225 + 0) must be non-negative

这与我之前的一篇文章有​​关 Using QuantLib to compute cash flows for FloatingRateBond with Floor

【问题讨论】:

    标签: finance quantitative-finance quantlib quantlib-swig


    【解决方案1】:

    问题不在于 QuantLib 本身。 Black 模型是对数正态模型,不适用于负值(因为你不能取它们的对数)。正如你可以猜到的,当利率开始下降时,这成为一个问题。可以通过两种不同的方式来解决:第一种是改变模型,使用普通的,第二种是引入固定位移D和模型log(R+D)而不是log(R),这样对数是正数。

    在这两种情况下,波动率都必须改变(事实上,引用的波动率也会告诉您使用的模型和位移)。在 QuantLib 中,这意味着您必须在构建波动率期限结构时传递相关信息,而这正是您目前遇到的麻烦所在。 C++ 库已经提供了一段时间的功能,但是 Python 模块还没有导出相应的ConstantOptionletVolatility,所以你得到了默认值,即对数正态模型和空位移。

    如果您对 SWIG 有点熟悉,您可以修改相应的接口文件 QuantLib-SWIG/SWIG/volatilities.i(您必须向 ConstantOptionletVolatility 构造函数添加几个参数,就像为 @987654328 所做的那样@class 在同一个文件中),重新生成包装器并编译它们。否则,请在https://github.com/lballabio/QuantLib-SWIG/issues 上提出问题,我们将尝试在下一个版本中添加该功能。


    更新:在最新版本中,ConstantOptionletVolatility 可以进行可选置换。

    【讨论】:

    • 嗨 Luigi,我正在努力解决同样的问题。您是否知道 Python 是否是唯一存在此问题的库?例如,QuantLib XL 和 C# 中有解决方法吗?谢谢!
    • 作为后续,如果我在 Python 中以不同的方式构建波动率期限结构,我可以绕过这个问题吗?
    • 嗨 Luigi,我正在寻找 BlackIborCouponPricer 的替代品。什么是浮动利率券的标准定价模型,它不是对数正态模型,因此不需要置换?
    【解决方案2】:

    除了使用ConstantOptionLetVolatility,您还可以构建一个vol 表面,然后使用OptionletStripper1 将期权波动率添加到定价器。这是改编自http://gouthamanbalaraman.com/blog/interest-rate-cap-floor-valuation-quantlib-python.html

    pricer = ql.BlackIborCouponPricer()
    
    strikes = [-0.01, 0.0, 0.01] 
    expiries = [ql.Period(i, ql.Years) for i in range(1,6)] #or tenors of your choice
    vols = ql.Matrix(len(expiries), len(strikes))
    data = [[65, 65, 65, 65, 65], 
            [65, 65, 65, 65, 65], #vols of your choice
            [65, 65, 65, 65, 65]  
             ]
    
    for i in range(vols.rows()):
        for j in range(vols.columns()):
            vols[i][j] = data[j][i]/100.0
    
    bdc = ql.Unadjusted
    settle_days =0
    daycount = ql.Actual360()       
    
    capfloor_vol = ql.CapFloorTermVolSurface(settle_days, calendar, bdc, expiries, 
    strikes, vols, daycount)
    
    optionlet_surf = ql.OptionletStripper1(parVolSurface = capfloor_vol,
                                       index = float_index,
                                       displacement = 0.01) #this make 'k + d' non-neg 
    
    pricer.setCapletVolatility(ql.OptionletVolatilityStructureHandle
                             (ql.StrippedOptionletAdapter(optionlet_surf)))
    ql.setCouponPricer(bond.cashflows(), pricer)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      相关资源
      最近更新 更多