from Pricing.PV.ExerciceBoundaryIntegrationBlackScholesAmericanOptionPricer import ExerciceBoundaryIntegrationBlackScholesAmericanOptionPricer
from Pricing.PV.PricingParameters import PricingParameters
from Smile.Implicitation.IImpliedVolatilitySolver import IImpliedVolatilitySolver
from Smile.Implicitation.OptionQuotation import OptionQuotation
from scipy import optimize
from Rates.IDiscountRateCurveInterpolator import IDiscountRateCurveInterpolator
[docs]class AmericanImpliedVolatilitySolver(IImpliedVolatilitySolver):
""" Class to compute the implied volatility associated to an american option quotation.
Parameters
----------
underlying_level : float
The market value of the option underlying.
discount_rate_curve_interpolator : :class:`~Rates.IDiscountRateCurveInterpolator`
A time interpolation of the discount rate curve
pricing_parameters : :class:`~Pricing.PV.PricingParameters`
The numerical parameters for the american option pricer
"""
def __init__(self, underlying_level : float, discount_rate_curve_interpolator : IDiscountRateCurveInterpolator, pricing_parameters: PricingParameters) :
self.__underlying_level = underlying_level
self.__discount_rate_curve_interpolator = discount_rate_curve_interpolator
self.__pricing_parameters = pricing_parameters
self.__min = 1e-10
self.__max = 10.0
[docs] def solve(self, option_quotation: OptionQuotation) -> float:
""" Solve for the implied volatility given an option quotation.
Parameters
----------
option_quotation : :class:`~Smile.Implicitation.OptionQuotation`
Characteristics and quotation of an option.
Returns
-------
implied_volatility : float
The implied volatility of the option
"""
pricer = ExerciceBoundaryIntegrationBlackScholesAmericanOptionPricer(option_quotation.quotation_date, self.__pricing_parameters)
interest_rate = self.__discount_rate_curve_interpolator.linear_rate(option_quotation.american_option.expiry_date)
func = lambda vol : pricer.price(self.__underlying_level, interest_rate, vol, option_quotation.american_option) - option_quotation.quote_value
(option_vol, root_result) = optimize.brentq(func, self.__min, self.__max, full_output=True)
if not root_result.converged:
raise ValueError("Volatility implicitation did not converge for quotation {0}".format(option_quotation))
return option_vol