示例#1
0
    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)
示例#2
0
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)
示例#4
0
 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)
示例#5
0
                         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")
#
示例#6
0
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,
示例#8
0
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)