【问题标题】:Retrieving Black vol from Quantlib BachelierSwaption price从 Quantlib BachelierSwaption 价格中检索 Black vol
【发布时间】:2019-05-29 14:29:08
【问题描述】:

我想从 Quantlib BachelierSwaptionEngine 计算的掉期价格中检索 Black Vol。看起来这可以通过优化器(例如 newton 方法)在 Quantlib 中完成,或者直接通过implicitVolatility 方法完成。 我无法在 Quantlib Python 中使用 Quantlib 优化器或implicitVolatility 方法。

下面的代码显示了我如何在 Quantlib 中计算掉期价格。从那里我需要根据代码中计算的掉期价格检索黑色卷

import Quantlib as ql
from scipy import optimize

calc_date = ql.Date(29,3,2019)

rate = ql.SimpleQuote(0.01)
rate_handle = ql.QuoteHandle(rate)
dc = ql.Actual365Fixed()
spot_curve = ql.FlatForward(calc_date, rate_handle, dc)

start = 10
length = 10
start_date =  ql.TARGET().advance(calc_date, start, ql.Years)
maturity_date = start_date + ql.Period(length, ql.Years)
fixed_schedule = ql.Schedule(start_date, maturity_date,
                      ql.Period(1, ql.Years), ql.TARGET(), ql.Unadjusted, 
                      ql.Unadjusted,ql.DateGeneration.Forward, False)
floating_schedule = ql.Schedule(start_date, maturity_date,
                        ql.Period(6, ql.Months), ql.TARGET(), 
                        ql.ModifiedFollowing, ql.ModifiedFollowing,
                        ql.DateGeneration.Forward, True)

index6m = ql.Euribor6M(ql.YieldTermStructureHandle(spot_curve))

rate = 1.45 / 100
swap = ql.VanillaSwap(ql.VanillaSwap.Receiver, 10000000,
               fixed_schedule, rate, ql.Thirty360(ql.Thirty360.BondBasis),
               floating_schedule, index6m, 0.0, index6m.dayCounter())

swap.setPricingEngine(ql.DiscountingSwapEngine( 
ql.YieldTermStructureHandle(spot_curve)))


swaption_normal_model = ql.Swaption(swap, 
  ql.EuropeanExercise(swap.startDate()))


normal_vol = ql.SimpleQuote(0.005266)
swaption_normal_model.setPricingEngine
(ql.BachelierSwaptionEngine(ql.YieldTermStructureHandle(spot_curve), 
ql.QuoteHandle(normal_vol)))
swaption_normal_model_value = swaption_normal_model.NPV()

【问题讨论】:

    标签: python quantlib


    【解决方案1】:

    我使用了 scipy 中的牛顿最小化函数来检索隐含的黑色卷,见下文:

    swaption_black_model = ql.Swaption(swap, ql.EuropeanExercise(swap.startDate()))
    initial_vol_guess = 0.60
    
    
    def find_implied_black(vol):
        black_vol = ql.SimpleQuote(vol)
        swaption_black_model.setPricingEngine(
        ql.BlackSwaptionEngine(ql.YieldTermStructureHandle(spot_curve), 
        ql.QuoteHandle(black_vol)))
        swaption_black_model_value = swaption_black_model.NPV()
        diff = swaption_normal_model_value - swaption_black_model_value
    
        return diff
    
    
    implied_black_vol = optimize.newton(find_implied_black, initial_vol_guess)
    implied_black_vol = ql.SimpleQuote(implied_black_vol)
    swaption_black_model.setPricingEngine(
    ql.BlackSwaptionEngine(ql.YieldTermStructureHandle(spot_curve), 
    ql.QuoteHandle(implied_black_vol)))
    swaption_black_model_value = swaption_black_model.NPV()
    
    print('Normal swaption price is {}'.format(swaption_normal_model_value))
    print('Black swaption price is {}'.format(swaption_black_model_value))
    

    【讨论】:

      【解决方案2】:

      QuantLib 具有确定隐含波动率的内部函数,您可以求解 ShiftedLognormal vol 或 Normal vol。

      这是一个例子:

      yts = ql.YieldTermStructureHandle(spot_curve)
      blackVol = swaption_normal_model.impliedVolatility(swaption_normal_model_value, yts, 0.5)
      
      blackEngine = ql.BlackSwaptionEngine(yts, ql.QuoteHandle(ql.SimpleQuote(blackVol)))
      swaption_normal_model.setPricingEngine(blackEngine)
      
      print(swaption_normal_model.NPV(), swaption_normal_model_value)
      

      此外,将您的交换对象命名为 swaption_normal_model 并不是一个好主意,因为您可以设置不同的定价引擎

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-11
        • 2021-05-19
        • 2022-01-12
        • 1970-01-01
        • 2015-10-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多