def create_data(sample): shift = 0 beta = 0 #alpha, rho, nu params = np.random.random_sample( (sample, 3)) * [0.01499, 1.96, 0.69999] + [0.00001, -0.98, 0.00001] T_index = [1 / 12, 1 / 4, 0.5] + [i for i in range(1, 31)] T_random = np.random.randint(0, len(T_index), sample) T = [] for i in range(sample): T.append(T_index[T_random[i]]) F0 = np.random.random_sample(sample) * (0.035 + 0.005) - 0.005 Kpb = np.linspace(-200, 200, 11) K = [] for i in range(len(F0)): K.append(F0[i] + Kpb / 10000) ### GENERATE THE SABR VOLS ### import SABRnormal vol_input = [] for i in range(sample): vol_input_ind = [] for j in range(len(Kpb)): aux = SABRnormal.normal_vol(K[i][j], F0[i], T[i], params[i][0], beta, params[i][1], params[i][2], shift) vol_input_ind.append(aux) vol_input.append(vol_input_ind) ### Create the matrix of inputs ### K = np.matrix(K) vol_input = np.matrix(vol_input) # The order is: [K (vector of strikes), sigma (vector of vols), T] X = np.hstack((K, vol_input, np.matrix(T).T)) y = params np.save('X_sample.npy', X) np.save('y_sample.npy', y) return X, y
#NNParameters=[] #for i in range(1,len(model.layers)): # NNParameters.append(model.layers[i].get_weights()) #y_test[:,0] = np.ravel(scaler.inverse_transform(y_test[:,0].reshape(-1,1))) # Comprobar con modelo aleatorio # import SABRnormal import matplotlib.pyplot as plt testcase = -2000 Xtestcase = np.ravel(X_test[testcase, :]) testparams = np.ravel(model.predict(X_test[testcase, :].reshape(1, -1))) testparams[0] = scaler.inverse_transform(testparams[0]) vol_test = [] for j in range(11): aux = SABRnormal.normal_vol(Xtestcase[j], Xtestcase[5], Xtestcase[-1], testparams[0], 0, testparams[1], testparams[2], 0) vol_test.append(aux) plt.figure() plt.subplot(121) plt.plot(Xtestcase[:11], Xtestcase[11:-1], color='blue', marker='x', linewidth=1.0) plt.plot(Xtestcase[:11], np.array(vol_test), color='green', marker='o', linewidth=1.0)
def analisis(X, network, seed, plot_swap_option, plot_option, test_Hagan, test_Hagan_ATM): def objfun(param, k, f, t, beta, shift, sigmaMKT): """ Objective function to minimize for calibration while estimating the 3 parameters at the same time """ vbles = np.hstack((k, param, t)).reshape(1, -1) vols = np.ravel(network.predict(vbles)) MSE = np.sum((vols - sigmaMKT)**2) return MSE import SABRnormal from scipy.optimize import minimize number_swaptions = X.shape[0] error_test = np.zeros((number_swaptions, 11)) # calibration to NN module for i in range(number_swaptions): args = (X[i, :11], X[i, 5], X[i, -1], 0, 0, X[i, 11:-1]) res = minimize(objfun, seed, args, method='BFGS') #,options = {'disp': True}) vol_test = [] for j in range(11): aux = SABRnormal.normal_vol(X[i, j], X[i, 5], X[i, -1], res.x[0], 0, res.x[1], res.x[2], 0) vol_test.append(aux) error_test[i] = (X[i, 11:-1] - vol_test) RMSE = np.sqrt(np.mean(np.square(error_test), axis=0)) * 10000 title = [ "ATM - 5", "ATM - 4", "ATM - 3", "ATM - 2", "ATM - 1", "ATM", "ATM + 1", "ATM + 2", "ATM + 3 ", "ATM + 4", "ATM + 5" ] data = pd.DataFrame(RMSE, columns=['NN'], index=title) import matplotlib.pyplot as plt ### 3D plot of RMSE vs maturity of swaptions and options ### if plot_swap_option == 1: x_array = np.unique(X[:, -1]) result = np.sqrt(np.mean(np.square(error_test), axis=1)) z = np.hsplit(result, 14) y_array = np.hstack((np.linspace(1, 10, 10), 15, 20, 25, 30)) x_array, y_array = np.meshgrid(x_array, y_array) fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_surface(x_array, y_array, np.array(z), cmap='viridis', edgecolor='none') ax.set_title('Volatilility error mean accross strikes') ax.set_xlabel('Option maturity') ax.set_ylabel('Swap maturity') ax.set_zlabel('RMSE mean') plt.show() ### Plot of RMSE vs swaption maturity ### if plot_option == 1: x_array = np.unique(X[:, -1]) result = np.sqrt(np.mean(np.square(error_test), axis=1)) z = np.hsplit(result, 14) plt.figure() plt.plot(x_array, np.mean(np.matrix(z), axis=0).reshape(-1, 1)) plt.title('RMSE accross maturities') plt.xlabel('Swaption maturities') plt.ylabel('RMSE') if test_Hagan == 1: error_Hagan = np.zeros((number_swaptions, 11)) for i in range(len(X)): res = SABRnormal.calibrate(X[i, :11], X[i, 5], X[i, -1], 0, 0, X[i, 11:-1], seed) vol_test = [] for j in range(11): aux = SABRnormal.normal_vol(X[i, j], X[i, 5], X[i, -1], res[0], 0, res[1], res[2], 0) vol_test.append(aux) error_Hagan[i] = (X[i, 11:-1] - vol_test) RMSE_Hagan = np.sqrt(np.mean(np.square(error_Hagan), axis=0)) * 10000 result_Hagan = pd.DataFrame(RMSE_Hagan, columns=['Hagan'], index=title) data = data.add(result_Hagan, fill_value=0) if test_Hagan_ATM == 1: error_Hagan_ATM = np.zeros((number_swaptions, 11)) seed = np.delete(seed, 0) # now alpha is implicit, no need to fit it for i in range(len(X)): res = SABRnormal.calibrate2(X[i, :11], X[i, 5], X[i, -1], 0, 0, X[i, 11:-1], seed) vol_test = [] for j in range(11): aux = SABRnormal.normal_vol(X[i, j], X[i, 5], X[i, -1], res[0], 0, res[1], res[2], 0) vol_test.append(aux) error_Hagan_ATM[i] = (X[i, 11:-1] - vol_test) RMSE_Hagan_ATM = np.sqrt(np.mean(np.square(error_Hagan_ATM), axis=0)) * 10000 result_Hagan_ATM = pd.DataFrame(RMSE_Hagan_ATM, columns=['Hagan ATM'], index=title) data = data.add(result_Hagan_ATM, fill_value=0) return data[['NN', 'Hagan', 'Hagan ATM']]
K_range.append(aux) xvector = np.hstack( (K_range, Trandom[i], alpharandom[i], rhorandom[i], nurandom[i])) X_random.append(xvector) X_random = np.matrix(X_random) X = np.vstack((X_fixed, X_random)) ### OBTAIN SABR VOLATILIES (NORMAL) ### import SABRnormal volatility = [] for i in range(len(X)): aux2 = [] for j in range(len(nstrike)): aux = SABRnormal.normal_vol(X[i, j], 0.03, X[i, 10], X[i, 11], beta, X[i, 12], X[i, 13], shift) aux2.append(aux) volatility.append(aux2) volatility = np.matrix(volatility) ### PREPARE DATA FOR NN ### from sklearn import preprocessing X_mean = X.mean(axis=0) X_std = X.std(axis=0) X_norm = preprocessing.scale(X) X_train = X_norm[:250000, :] X_test = X_norm[250000:, :] y_train = volatility[:250000, :] y_test = volatility[250000:, :]
T = np.random.randint(1, 30, sample) F0 = np.random.random_sample(sample) * 0.0299 + 0.0201 Kpb = np.linspace(-200, 200, 9) K = [] for i in range(len(F0)): K.append(F0[i] + Kpb / 10000) ### GENERATE THE SABR VOLS ### import SABRnormal vol_input = [] for i in range(sample): vol_input_ind = [] for j in range(len(Kpb)): aux = SABRnormal.normal_vol(K[i][j], F0[i], T[i], params[i][0], beta, params[i][1], params[i][2], shift) vol_input_ind.append(aux) vol_input.append(vol_input_ind) ### Create the matrix of inputs ### K = np.matrix(K) vol_input = np.matrix(vol_input) # The order is: [K (vector of strikes), sigma (vector of vols), F0, T] X = np.hstack((K, np.matrix(F0).T, vol_input, np.matrix(T).T)) # Create data input and output for neural network # The output to predict will be the parameters alpha, rho, nu X_train = X[:int(0.8 * sample)] X_test = X[int(0.8 * sample):] y_train = params[:int(0.8 * sample)] y_test = params[int(0.8 * sample):]