2 votes

Retrouver le vol noir de Quantlib BachelierSwaption price

Je souhaite récupérer un Black Vol à partir d'un prix de swaption calculé par le Quantlib BachelierSwaptionEngine. Il semble que cela puisse être fait dans Quantlib via un optimiseur (comme la méthode newton) ou directement via la méthode impliedVolatility. Je n'arrive pas à utiliser l'optimiseur Quantlib ou la méthode impliedVolatility dans Quantlib Python.

Le code ci-dessous montre comment je calcule le prix des swaptions dans Quantlib. A partir de là, j'ai besoin de récupérer un vol noir basé sur le prix du swaption calculé dans le code.

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()

2voto

Oamriotn Points 207

J'ai utilisé la fonction de minimisation de Newton de Scipy pour récupérer le vol noir implicite, voir ci-dessous :

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))

0voto

David Duarte Points 479

QuantLib dispose d'une fonction interne pour déterminer la volatilité implicite et vous pouvez résoudre soit le vol ShiftedLognormal, soit le vol Normal.

En voici un exemple :

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)

De plus, nommer votre objet swaption comme swaption_normal_model n'est pas vraiment une bonne idée puisque vous pouvez définir différents moteurs de tarification.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X