Source code for putcall.calibration.implied_volatility

# -*- coding: utf-8 -*-

# putcall
# -------
# Collection of classical option pricing formulas.
# 
# Author:   sonntagsgesicht, based on a fork of Deutsche Postbank [pbrisk]
# Version:  0.2, copyright Wednesday, 18 September 2019
# Website:  https://github.com/sonntagsgesicht/putcall
# License:  Apache License 2.0 (see LICENSE file)


from mathtoolspy import Optimizer1Dim, Constraint
from mathtoolspy.solver.minimize_algorithm_1dim_brent import minimize_algorithm_1dim_brent as brent


[docs]class OptionValueByVolatility: def __init__(self, option_value_function, forward, strike, time, option_type, discount_factor=1.0): self.option_value_function = option_value_function self.forward = forward self.strike = strike self.time = time self.option_type = option_type self.discount_factor = discount_factor
[docs] def option_value(self, vol): return self.option_value_function(self.forward, self.strike, self.time, vol, self.option_type, self.discount_factor)
def __call__(self, vol): return self.option_value(vol)
[docs]class ImpliedVolCalculator: VOL_CALIB_TOL = 1e-9 MAX_VOL_FOR_IMPLIED_VOL = 10.0
[docs] def implied_vol(self, price, option_value_function_by_volatility, upper_bound=1.0, initial_value=0.05): dev_fct = ImpliedVolCalculator.ImpliedVolErrorFunction(price, option_value_function_by_volatility) opt = Optimizer1Dim(minimize_algorithm=brent) MAXVOL = ImpliedVolCalculator.MAX_VOL_FOR_IMPLIED_VOL tol = ImpliedVolCalculator.VOL_CALIB_TOL max_vol = upper_bound if upper_bound < MAXVOL else MAXVOL while max_vol <= ImpliedVolCalculator.MAX_VOL_FOR_IMPLIED_VOL: constraint = Constraint(0.000001, max_vol) opt_result = opt.optimize(dev_fct, constraint, initial_value, tol) if opt_result.successful: impl_vol = opt_result.xmin * opt_result.xmin return impl_vol max_vol = 2.0 * max_vol raise Exception("Unable to find implied volatility for price " + str(price))
[docs] class ImpliedVolErrorFunction: def __init__(self, price, option_value_function_by_volatility): self.price = price self.option_value = option_value_function_by_volatility def __call__(self, squared_root_of_vol): vol = squared_root_of_vol * squared_root_of_vol price = self.option_value(vol) diff = price - self.price return abs(diff)