Получение Black vol от Quantlib BachelierЗаполнение цены - PullRequest
1 голос
/ 29 мая 2019

Я хочу получить Black Vol из цены своптиона, рассчитанной с помощью Quantlib BachelierSwaptionEngine. Похоже, что это можно сделать в Quantlib через оптимизатор (например, метод Ньютона) или напрямую через метод impliedVolatility. Я не могу использовать оптимизатор Quantlib или метод impliedVolatility в Quantlib Python.

Приведенный ниже код показывает, как я рассчитываю цену своптиона в 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()

1 Ответ

1 голос
/ 04 июня 2019

Я использовал функцию минимизации ньютона от 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))
...