def get_local_vol_derivative(self, z_t: Types.ndarray, t=None): delta_t_T = self._day_counter.yearFraction(self._value_date, t) rho_t = self._f_rho(delta_t_T) nu_t = self._f_v(delta_t_T) atm_vol_t = self.get_atm_volatility(t)[0] alpha_t = ParameterTools.alpha_atm_sabr(rho_t, nu_t, atm_vol_t, delta_t_T) return SABRTools.f_partial_der_parameters(z_t, delta_t_T, alpha_t, rho_t, nu_t)
def get_smile_for_differents_rho(alpha: float, rho_s: Types.ndarray, nu: float, k_s: Types.ndarray, f0: float, T: float): no_strikes = len(k_s) iv_hagan = [] for rho_i in rho_s: iv_list = [] for i in range(0, no_strikes): z = np.log(f0 / k_s[i]) iv_list.append(SABRTools.sabr_vol_jit(alpha, rho_i, nu, z, T)) iv_hagan.append((rho_i, iv_list)) return iv_hagan
def get_vol(self, t: int, x_t: Types.ndarray, f0_t): d_t = self._day_counter.yearFraction(self._iv_surface._value_date, ql.Date(t)) if d_t > 0: parameters = self._iv_surface.get_parameters() atm_info = self._iv_surface.get_atm_volatility(ql.Date(t)) return SABRTools.get_sabr_loc_vol( np.array(parameters['nu']), # Esto hay que modificarlo np.array(parameters['rho']), # Esto hay que modificarlo atm_info[0], atm_info[1], d_t, f0_t, x_t) else: return np.zeros(x_t.shape)
def get_implied_volatility(*args, f=0.0, k=0.0, t=0.0): return SABRTools.sabr_vol_jit(args[0], args[1], args[2], np.log(f / k), t)
sep=";") no_dates = len(parameters['date']) no_z_i = 100 z_i = np.linspace(-0.5, 0.5, no_z_i) sabr_iv_map = {} for i in range(1, no_dates): alpha_i = float(parameters['alpha'][i]) rho_i = float(parameters['rho'][i]) nu_i = float(parameters['nu'][i]) dti = (float(parameters['date'][i]) - float(parameters['value_date'][i])) / 365.0 iv = [] for j in range(0, no_z_i): iv.append(SABRTools.sabr_vol_jit(alpha_i, rho_i, nu_i, z_i[j], dti)) sabr_iv_map[int(parameters['date'][i])] = iv nu_param = [] rho_param = [] delta_time = [] for i in range(1, no_dates): delta_time.append( (float(parameters['date'][i]) - float(parameters['value_date'][i])) / 365.0) nu_param.append(float(parameters['nu'][i])) rho_param.append(float(parameters['rho'][i])) # To plot the skew for diferent maturities # plt.plot(delta_time, nu_param, label="vol-of_vol parameter", color="black", linestyle="dashed") #
no_dt = len(dt) for i in range(0, no_dt): no_time_steps = int(dt[i] / delta_time) rnd_generator.set_seed(seed) # european_option = EuropeanOption(f0, 1, TypeSellBuy.BUY, TypeEuropeanOption.CALL, f0, dt[i]) # map_output = SABR_Engine.get_path_multi_step(0.0, dt[i], parameters, f0, no_paths, no_time_steps, # Types.TYPE_STANDARD_NORMAL_SAMPLING.ANTITHETIC, # rnd_generator) # # results = european_option.get_price(map_output[Types.SABR_OUTPUT.PATHS]) # mc_option_price.append(results[0]) # price the option with var swap approximation analytic_price = EuropeanOptionExpansion.get_var_swap_apprx_price(f0, 1.0, TypeSellBuy.BUY, TypeEuropeanOption.CALL, f0, dt[i], parameters, Types.TypeModel.SABR) var_swap_approximation_price.append(analytic_price) # hagan's price iv_hagan = SABRTools.sabr_vol_jit(parameters[0], parameters[1], parameters[2], 0.0, dt[i]) hagan_price = black_scholes_merton('c', f0, f0, dt[i], 0.0, iv_hagan, 0.0) hagan_approximation_price.append(hagan_price) plt.plot(dt, mc_option_price, label='mc price') plt.plot(dt, var_swap_approximation_price, label='variance swap approximation') plt.plot(dt, hagan_approximation_price, label='Hagan approximation') plt.legend() plt.title('ATM option price') plt.show()
map_output = SABR_Engine.get_path_multi_step( 0.0, T, parameters, f0, no_paths, no_time_steps, Types.TYPE_STANDARD_NORMAL_SAMPLING.REGULAR_WAY, rnd_generator) option_prices_mc = [] option_prices_hagan = [] density_mc = [] density_hagan = [] no_options = len(european_options) for i in range(0, no_options): result = european_options[i].get_price( map_output[Types.SABR_OUTPUT.PATHS][:, -1]) option_prices_mc.append(result[0]) z = np.log(f0 / k_s[i]) iv_hagan = SABRTools.sabr_vol_jit(alpha, rho, nu, z, T) option_prices_hagan.append( black_scholes_merton('c', f0, k_s[i], T, 0.0, iv_hagan, 0.0)) pdf_hagan = [] pdf_mc = [] plt.figure(figsize=(8, 5)) for i in range(1, no_options - 1): pdf_hagan.append( (option_prices_hagan[i + 1] - 2.0 * option_prices_hagan[i] + option_prices_hagan[i - 1]) / (delta_strike * delta_strike)) pdf_mc.append((option_prices_mc[i + 1] - 2.0 * option_prices_mc[i] + option_prices_mc[i - 1]) / (delta_strike * delta_strike)) plt.plot(k_s[1:no_options - 1], pdf_hagan,
def get_var_swap_apprx_price(strike: float, notional: float, buy_sell: TypeSellBuy, option_type: TypeEuropeanOption, spot: float, delta_time: float, parameters: List[float], model: Types.TypeModel): if model == Types.TypeModel.SABR: alpha = parameters[0] rho = parameters[1] nu = parameters[2] var_swap = SABRTools.get_variance_swap(alpha, nu, delta_time) if option_type == TypeEuropeanOption.CALL: bs0 = black_scholes_merton('c', spot, strike, delta_time, 0.0, var_swap, 0.0) h_0 = delta_vega(strike, spot, var_swap, delta_time) rho_term = SABRTools.get_rho_term_var_swap(alpha, nu, delta_time) * h_0 if buy_sell == TypeSellBuy.BUY: return notional * (bs0 + 0.5 * rho * rho_term) else: return - notional * (bs0 + 0.5 * rho * rho_term) else: bs0 = black_scholes_merton('p', spot, strike, delta_time, 0.0, var_swap, 0.0) h_0 = delta_vega(strike, spot, var_swap, delta_time) rho_term = SABRTools.get_rho_term_var_swap(alpha, nu, delta_time) * h_0 forward = (spot - strike) call_price = notional * (bs0 + 0.5 * rho * rho_term) if buy_sell == TypeSellBuy.BUY: return call_price - forward else: return forward - call_price elif model == Types.TypeModel.HESTON: k = parameters[0] theta = parameters[1] epsilon = parameters[2] rho = parameters[3] v0 = parameters[4] var_swap = HestonTool.get_variance_swap(v0, k, theta, delta_time) if option_type == TypeEuropeanOption.CALL: bs0 = black_scholes_merton('c', spot, strike, delta_time, 0.0, var_swap, 0.0) h_0 = delta_vega(strike, spot, var_swap, delta_time) rho_term = HestonTool.get_rho_term_var_swap(v0, k, theta, epsilon, delta_time) * h_0 if buy_sell == TypeSellBuy.BUY: return notional * (bs0 + 0.5 * rho * rho_term) else: return - notional * (bs0 + 0.5 * rho * rho_term) else: bs0 = black_scholes_merton('p', spot, strike, delta_time, 0.0, var_swap, 0.0) h_0 = delta_vega(strike, spot, var_swap, delta_time) rho_term = HestonTool.get_rho_term_var_swap(v0, k, theta, delta_time) * h_0 forward = (spot - strike) call_price = notional * (bs0 + 0.5 * rho * rho_term) if buy_sell == TypeSellBuy.BUY: return call_price - forward else: return forward - call_price elif model == Types.TypeModel.ROUGH_BERGOMI: return 0.0 else: print(f'At the moment we have not implmented the approximation price for {str(model)} ')
delta_time = np.zeros(no_dates) for i in range(0, no_dates): delta_time[i] = day_counter.yearFraction(ql_date, ql.Date(int(dates_list[i]))) rho_i = ParameterTools.rho_sabr(p_rho, delta_time[i]) nu_i = ParameterTools.nu_sabr(p_nu, delta_time[i]) atm_vol_i = sabr_term_structure_vol.get_atm_volatility( ql.Date(int(dates_list[i]))) alpha_i = ParameterTools.alpha_atm_sabr(rho_i, nu_i, atm_vol_i[0], delta_time[i]) x_i_s = np.log(forward_map[int(dates_list[i])]) - z_i_s m_loc_vol[i, :] = loc_vol.get_vol(int(dates_list[i]), x_i_s, forward_map[int(dates_list[i])]) for j in range(0, no_z_i_s): m_iv[i, j] = SABRTools.sabr_vol_jit(alpha_i, rho_i, nu_i, z_i_s[j], delta_time[i]) fig_surface = plt.figure(figsize=(13, 5)) ax = fig_surface.add_subplot(121, projection='3d') t, z = np.meshgrid(delta_time, z_i_s) surf = ax.plot_surface(t, z, m_iv.transpose(), rstride=1, cstride=1, cmap=cm.gray, linewidth=0, antialiased=False)