コード例 #1
0
 def recalib_calendar(param):
     norm = sum(
         (w(log_moneyness_t, parameters[:, t]) -
          w(log_moneyness_t, param))**2
     ) + 0.0001 * sum_negatives(
         np.array(svi_raw(k, param, maturities[t]) -
                  slice_after)) + +0.00001 * g(param)[1]
     return norm
コード例 #2
0
        def fitness(indv):
            a, b, m, rho, sigma = indv.solution

            model_total_implied_variance=svi_raw(self.k,np.array([a, b, m, rho, sigma]),self.tau)
            value = norm(self.total_implied_variance - model_total_implied_variance,ord=2)

            # if bool(len(self.slice_before)) and np.array(model_total_implied_variance < self.slice_before).any():
            #     value +=(np.count_nonzero(~np.array(model_total_implied_variance < self.slice_before))*100)
            #     # value = 1e6
            #
            # if bool(len(self.slice_after)) and np.array(model_total_implied_variance > self.slice_after).any():
            #     value += float(np.count_nonzero(~np.array(model_total_implied_variance > self.slice_after)) * 100)
            #     # value = 1e6
            # if np.isnan(value):
            #     value = 1e6

            value = float(value)
            return value
コード例 #3
0
def svi_interpolation(spot, log_moneyness, tau_interp, interest_interp,
                      parameters, theta, maturities):

    # forward_theta, interest_rate_theta

    # close = forward_interp*np.exp(-interest_interp * tau_interp)
    if np.isin(tau_interp, maturities):
        total_implied_variance = svi_raw(
            log_moneyness, parameters[:, maturities == tau_interp], tau_interp)
        implied_volatility = np.sqrt(total_implied_variance / tau_interp)

    elif min(maturities) < tau_interp and tau_interp < max(maturities):
        theta_interp = interp1d(maturities, theta)(tau_interp)
        idx = np.argmin(abs(maturities - tau_interp))
        if maturities[idx] < tau_interp:
            idx = idx + 1
        alpha_t = (np.sqrt(theta[idx]) - np.sqrt(theta_interp)) / (
            np.sqrt(theta[idx]) - np.sqrt(theta[idx - 1]))

        parameters_jw_fromer = svi_convertparameters(parameters[:, idx - 1],
                                                     'raw', 'jumpwing',
                                                     maturities[idx - 1])
        parameters_jw_after = svi_convertparameters(parameters[:, idx], 'raw',
                                                    'jumpwing',
                                                    maturities[idx])

        param_interp_jw = alpha_t * parameters_jw_fromer + (
            1 - alpha_t) * parameters_jw_after

        param_interp = svi_convertparameters(param_interp_jw, 'jumpwing',
                                             'raw', tau_interp)

        total_implied_variance = svi_raw(log_moneyness, param_interp,
                                         tau_interp)

        implied_volatility = np.sqrt(total_implied_variance / tau_interp)

    elif tau_interp < maturities[0]:
        # extrapolation for small maturities
        theta_interp = interp1d(maturities, theta,
                                fill_value='extrapolate')(tau_interp)

        strike_1 = spot * np.exp(log_moneyness)
        call_price_1 = np.array(
            [x if x >= 0 else 0 for x in (spot - strike_1)])

        idx = 0
        total_implied_variance_2 = svi_raw(log_moneyness, parameters[:, idx],
                                           maturities[idx])
        implied_volatility_2 = np.sqrt(total_implied_variance_2 /
                                       maturities[idx])
        strike_2 = spot * np.exp(
            interest_interp * maturities[0]) * np.exp(log_moneyness)
        call_price_2 = eurocall(implied_volatility_2, spot, strike_2,
                                interest_interp, maturities[idx], 0)

        forward_interp = interp1d(
            np.array([0, maturities[0]]),
            [spot, spot * np.exp(interest_interp * maturities[0])])(tau_interp)
        alpha_t = (np.sqrt(theta[idx]) - np.sqrt(theta_interp)) / np.sqrt(
            theta[idx])
        K_t = forward_interp * np.exp(log_moneyness)
        call_price = K_t * (alpha_t * call_price_1 / strike_1 +
                            (1 - alpha_t) * call_price_2 / strike_2)
        implied_volatility = calcvol(spot, K_t, interest_interp, tau_interp,
                                     call_price, '0')
        total_implied_variance = np.array(implied_volatility)**2 * tau_interp

    # extrapolation for large maturities

    else:
        theta_interp = interp1d(maturities, theta,
                                fill_value='extrapolate')(tau_interp)

        total_implied_variance = svi_raw(log_moneyness, parameters[:, -1],
                                         maturities[-1])
        total_implied_variance = total_implied_variance + theta_interp - theta[
            -1]
        implied_volatility = np.sqrt(total_implied_variance / tau_interp)

    return total_implied_variance
コード例 #4
0
def fit_svi_surface(implied_volatility, log_moneyness, maturity):

    total_implied_variance = np.array(implied_volatility**2 * maturity)

    maturities = np.array(sorted(list(set(maturity))))
    T = len(maturities)
    theta = np.zeros(T)
    parameters = np.zeros([5, T])

    for t in np.arange(T - 1, -1, -1):
        pos = maturity == maturities[t]

        log_moneyness_t = np.array(log_moneyness[pos])
        k = np.arange(-1, 1, 0.005)
        total_implied_variance_t = total_implied_variance[pos]

        if t == T - 1:

            # slice_before = []
            slice_after = []

        else:
            # slice_before=[]
            param_after = parameters[:, t + 1]
            slice_after = svi_raw(k, param_after, maturities[t + 1])

        print(
            '================================starting fitting================================================'
        )

        # parameters[:, t] = get_svi_optimal_params_non_calendar(slice_after,[list(log_moneyness_t),
        #                                                                     total_implied_variance_t],maturities[t])
        parameters[:, t] = svi_calibration_util(
            slice_after, [log_moneyness_t, total_implied_variance_t],
            maturities[t])

        # penalize butterfly arbitrage
        # a, b, rho, m, sigma    shunxu
        params_old = parameters[:, t]
        if (g(params_old)[0] < 0).any():
            parameters_bnd = svi_convertparameters(params_old, 'raw',
                                                   'jumpwing', maturities[t])
            parameters_bnd[3] = parameters_bnd[2] + 2 * parameters_bnd[1]
            parameters_bnd[4] = parameters_bnd[0] * 4 * parameters_bnd[
                2] * parameters_bnd[3] / (parameters_bnd[2] +
                                          parameters_bnd[3])**2
            parameters_bnd_raw = svi_convertparameters(parameters_bnd,
                                                       'jumpwing', 'raw',
                                                       maturities[t])

            def recalib(param):
                norm = sum(
                    (w(log_moneyness_t, params_old) -
                     w(log_moneyness_t, param))**2) + 0.00001 * g(param)[1]

                return norm

            a, b, rho, m, sigma = params_old
            a_bnds, b_bnds, rho_bnds, m_bnds, sigma_bnds = parameters_bnd

            bnds = ((min(a, a_bnds), max(a, a_bnds)),
                    (min(b, b_bnds), max(b, b_bnds)), (min(rho, rho_bnds),
                                                       max(rho, rho_bnds)),
                    (min(m, m_bnds), max(m, m_bnds)), (min(sigma, sigma_bnds),
                                                       max(sigma, sigma_bnds)))
            res = minimize(
                recalib,
                (np.array(parameters_bnd_raw) + np.array(params_old)) / 2,
                bounds=bnds,
                method='SLSQP',
                tol=1e-9)
            param_new = res.x
            parameters[:, t] = param_new

#penalize calendar arbitrage and butterfly arbitrage

        if slice_after != [] and np.array(
            (svi_raw(k, parameters[:, t], maturities[t]) -
             slice_after) > 0).any():
            print(
                np.array((svi_raw(k, parameters[:, t], maturities[t]) -
                          slice_after) > 0))
            print('eliminating calendar arb')
            param_no_calendar_arb = parameters[:, t]

            # a:param_no_calendar_arb[0]
            # param_no_calendar_arb[0] = param_no_calendar_arb[0] + 0.5
            # while np.array((svi_raw(k, param_no_calendar_arb, maturities[t]) - slice_after) > 0).any():
            #     param_no_calendar_arb[0] = param_no_calendar_arb[0] - 0.5
            def recalib_calendar(param):
                norm = sum(
                    (w(log_moneyness_t, parameters[:, t]) -
                     w(log_moneyness_t, param))**2
                ) + 0.0001 * sum_negatives(
                    np.array(svi_raw(k, param, maturities[t]) -
                             slice_after)) + +0.00001 * g(param)[1]
                return norm

            res2 = minimize(recalib_calendar,
                            param_no_calendar_arb,
                            method='SLSQP',
                            tol=1e-9)
            parameters[:, t] = res2.x

        print(parameters[:, t])
        theta[t] = svi_raw(0, parameters[:, t], maturities[t])

        plt.plot(g(parameters[:, t])[0], 'r--')

        plt.plot([0] * 600, 'b')
        plt.show()

        a, b, rho, m, sigma = parameters[:, t]
        x_range = np.arange(
            min(log_moneyness_t) - 0.005,
            max(log_moneyness_t) + 0.02, 0.1 / 100)
        tv_svi2 = a + b * (rho * (x_range - m) + np.sqrt(
            (x_range - m)**2 + sigma**2))

        plt.figure()
        plt.plot(np.exp(log_moneyness_t), implied_volatility[pos], 'ro')
        plt.plot(np.exp(x_range), np.sqrt(tv_svi2 / maturities[t]), 'b--')

        plt.show()

    return parameters, theta
コード例 #5
0
ファイル: test.py プロジェクト: xiaoyou009/SVI-Surface
strikes = d['exe_price'].values
impliedVols = d['impvol'].values
ttm = d['ttm'].values
logMoneynesses = np.log(strikes / spot * np.exp(rf * ttm))
maturities = np.array(sorted(list(set(ttm))))

params = np.array(
    [[-6.12602361e-04, -7.68306690e-03, -1.41268209e-03, 1.27275581e-02],
     [3.28095217e-02, 7.23893507e-02, 1.00896003e-01, 1.13173980e-01],
     [-3.81018899e-01, -4.26001565e-01, -5.45357904e-01, -7.19617321e-01],
     [-2.32187306e-02, -4.54770989e-02, -2.26383083e-02, 1.24983464e-02],
     [3.77894587e-02, 1.33798429e-01, 8.35171426e-02, 1.07997580e-01]])
k = np.arange(-1, 1, 0.005)
theta = np.zeros(4)
for i in range(4):
    theta[i] = svi_raw(0, params[:, i], maturities[i])

#log_moneyness, tau_interp, interest_interp, parameters, theta,maturities, forward_theta, interest_rate_theta

tau_interp = 0.04
plt.plot(k,
         svi_interpolation(spot, k, tau_interp, 0.03, params, theta,
                           maturities),
         'orange',
         label=str(tau_interp))

plt.plot(k, svi_raw(k, params[:, 0], maturities[0]), 'blue', label='0.090')
plt.plot(k, svi_raw(k, params[:, 1], maturities[1]), 'green', label='0.167')
# plt.plot(k,svi_raw(k,params[:,2],maturities[2]),'blue',label='0.416')
# plt.plot(k,svi_raw(k,params[:,3],maturities[3]),'purple',label='0.665')
コード例 #6
0
strikes = d['exe_price'].values
impliedVols = d['impvol'].values
ttm = d['ttm'].values
logMoneynesses=np.log(strikes / spot * np.exp(rf * ttm))
maturities = np.array(sorted(list(set(ttm))))
k=np.arange(-1,1,0.005)
# params=np.array([[ -6.12602361e-04  ,-7.68306690e-03 , -1.41268209e-03 ,  1.27275581e-02],
#  [  3.28095217e-02 ,  7.23893507e-02  , 1.00896003e-01 ,  1.13173980e-01],
#  [ -3.81018899e-01  ,-4.26001565e-01 , -5.45357904e-01  ,-7.19617321e-01],
#  [ -2.32187306e-02 , -4.54770989e-02  ,-2.26383083e-02 ,  1.24983464e-02],
#  [  3.77894587e-02  , 1.33798429e-01 ,  8.35171426e-02  , 1.07997580e-01]])
params,theta= fit_svi_surface(impliedVols,logMoneynesses,ttm)
implied_vols = ql.Matrix(len(k), len(maturities))
volset=[]
for i in range(4):
    volset.append(np.sqrt(svi_raw(k,params[:,i],maturities[i])/maturities[i]))
for i in range(implied_vols.rows()):
    for j in range(implied_vols.columns()):
        implied_vols[i][j] = volset[j][i]


black_var_surface = ql.BlackVarianceSurface(evalDate, calendar, [ql.Date(28,2,2018),ql.Date(28,3,2018),ql.Date(27,6,2018),ql.Date(26,9,2018)], k,
                                                    implied_vols, daycounter)
#
# plt.figure(figsize=(16,9))
# for i in np.arange(0.01,0.5,0.01):
#     tau_interp=i
#     plt.legend()
#     plt.plot(k,np.array([black_var_surface.blackVol(tau_interp,i) for i in k])**2*tau_interp ,label=str(tau_interp))
#
# plt.plot(k,svi_raw(k,params[:,0],maturities[0]),'black',label=0.090)