Source code for Smile.Representations.SmileRepresentationConverter

import numpy as np
from Smile.Representations.MoneynessSmileRepresentation import MoneynessSmileRepresentation
from scipy.stats import norm

from Smile.Representations.StrikeSmileRepresentation import StrikeSmileRepresentation


[docs]class SmileRepresentationConverter: """ Class that permits to convert a smile representation from Strike-> Vol(Strike) to Moneyness -> Vol(Moneyness) and vice-versa """ @staticmethod
[docs] def moneyness_to_strike(underlying_level : float, moneyness : float, volatility : float, duration : float) -> float: """ Compute the strike associated to a given moneyness expressed in delta. Parameters ---------- underlying_level : float The market value of the option underlying. moneyness : float The moneyness expressed in terms of delta. volatility : float The volatility associated to the inputted moneyness. duration : float The duration of the option for which the moneyness was provided Returns ------- strike : float The strike associated to the given moneyness. Examples -------- >>> from Smile.Representations.SmileRepresentationConverter import SmileRepresentationConverter >>> underlying_level = 100.0 >>> moneyness = 0.45 >>> volatility = 0.15 >>> duration = 2.5 >>> SmileRepresentationConverter.moneyness_to_strike(underlying_level, moneyness, volatility, duration) 103.02517658563964 """ return underlying_level / np.exp(norm.ppf(moneyness) * volatility * np.sqrt(duration))
@staticmethod
[docs] def strike_to_moneyness(underlying_level : float, strike : float, volatility : float, duration : float) -> float: """ Compute the moneyness expressed in delta associated to a given strike. Parameters ---------- underlying_level : float The market value of the option underlying. strike : float The strike of the option. volatility : float The volatility associated to the inputted strike. duration : float The duration of the option for which the strike was provided Returns ------- moneyness : float The moneyness associated to the given strike. Examples -------- >>> from Smile.Representations.SmileRepresentationConverter import SmileRepresentationConverter >>> underlying_level = 100.0 >>> strike = 103.0251 >>> volatility = 0.15 >>> duration = 2.5 >>> SmileRepresentationConverter.strike_to_moneyness(underlying_level, strike, volatility, duration) 0.45000124057807839 """ return norm.cdf(np.log(underlying_level / strike) / (volatility * np.sqrt(duration)))
@staticmethod
[docs] def strike_representation(moneyness_representation: MoneynessSmileRepresentation, underlying_level: float, duration : float) -> StrikeSmileRepresentation: """ Compute the smile parametrized in strike equivalent to a given smile parametrized in deltas. Parameters ---------- moneyness_representation : :class:`~Smile.Representations.MoneynessSmileRepresentation` The representation of the volatility smile in terms of deltas. underlying_level : float The market value of the option underlying. duration : float The duration of the option for which the strike was provided Returns ------- strike_smile_representation : :class:`~Smile.Representations.StrikeSmileRepresentation` The representation of the volatility smile in terms of strikes. Examples -------- >>> from Smile.Representations.SmileRepresentationConverter import SmileRepresentationConverter >>> from Smile.Representations.MoneynessSmileRepresentation import MoneynessSmileRepresentation >>> import numpy as np >>> underlying_level = 100.0 >>> duration = 2.5 >>> atm_vol = 0.15 >>> moneyness = np.array([0.05,0.25,0.5,0.75,0.95]) >>> vol_shifts = np.array([0.10, 0.05, 0, -0.03, -0.09]) >>> moneyness_representation = MoneynessSmileRepresentation(atm_vol, moneyness, vol_shifts) >>> strike_representation = SmileRepresentationConverter.strike_representation(moneyness_representation,underlying_level, duration) >>> print(strike_representation) Strikes |65.108|84.538|100.000|116.786|142.618| Vols |0.165|0.158|0.150|0.145|0.137| Skew |0.100|0.050|0.000|-0.030|-0.090| <BLANKLINE> """ volvec = moneyness_representation.volatilities strikes = underlying_level / np.exp( norm.ppf(moneyness_representation.moneyness[::-1]) * volvec * np.sqrt(duration)) return StrikeSmileRepresentation(moneyness_representation.atm_vol, strikes, moneyness_representation.vol_shifts)
@staticmethod
[docs] def moneyness_representation(strike_representation: StrikeSmileRepresentation, underlying_level: float, duration : float) -> MoneynessSmileRepresentation: """ Compute the smile parametrized in deltas equivalent to a given smile parametrized in strikes. Parameters ---------- strike_representation : :class:`~Smile.Representations.StrikeSmileRepresentation` The representation of the volatility smile in terms of strikes. underlying_level : float The market value of the option underlying. duration : float The duration of the option for which the strike was provided Returns ------- moneyness_representation : :class:`~Smile.Representations.MoneynessSmileRepresentation` The representation of the volatility smile in terms of deltas. Examples -------- >>> from Smile.Representations.SmileRepresentationConverter import SmileRepresentationConverter >>> from Smile.Representations.StrikeSmileRepresentation import StrikeSmileRepresentation >>> import numpy as np >>> underlying_level = 100.0 >>> duration = 2.5 >>> atm_vol = 0.15 >>> strikes = np.array([65.108,84.538,100.000,116.786,142.618]) >>> vol_shifts = np.array([0.10, 0.05, 0, -0.03, -0.09]) >>> strike_representation = StrikeSmileRepresentation(atm_vol, strikes, vol_shifts) >>> moneyness_representation = SmileRepresentationConverter.moneyness_representation(strike_representation,underlying_level, duration) >>> print(moneyness_representation) Moneyness |0.087|0.267|0.500|0.767|0.977| Vols |0.165|0.158|0.150|0.145|0.137| Skew |0.100|0.050|0.000|-0.030|-0.090| <BLANKLINE> """ volvec = strike_representation.volatilities calldeltavec = norm.cdf( np.log(underlying_level / strike_representation.strikes[::-1]) / (volvec * np.sqrt(duration))) return MoneynessSmileRepresentation(strike_representation.atm_vol, calldeltavec, strike_representation.vol_shifts)
if __name__ == "__main__": import doctest doctest.testmod()