def calc_prices(spot : float, epsilon : float): vol1 = 0.04 vol2 = 0.01 kappa1 = 2 kappa2 = 0.1 theta1 = 0.04 theta2 = 0.01 epsilon1 = 0.5 epsilon2 = 2 rho1 = -0.7 rho2 = 0.8 rate = 0.05 tau = 1.005 #set to match option data strike = 100 some_option = vo.EUCall(tau, strike) some_model = hm.HestonClass(spot, vol1, kappa1, theta1, epsilon, rho1, rate) # case 1 some_model2 = hm.HestonClass(spot, vol2, kappa2, theta2, epsilon, rho2, rate) al1 = al.Andersen_Lake(some_model, some_option) mc1 = mc.Heston_monte_carlo(some_model, some_option, 10000) al2 = al.Andersen_Lake(some_model2, some_option) mc2 = mc.Heston_monte_carlo(some_model2, some_option, 10000) return al1, mc1, al2, mc2
def generate_sobol_data(no_sobol : int): model_input = generate_sobol_input(no_sobol) option_input = dg.option_input_generator() # different option combinations some_option_list = np.array([]) for option in option_input: some_option_list = np.append(some_option_list, vo.EUCall(option[0], option[1])) # generating data for neural net with model as input and grid as output gridInput = model_input # going parallel cpu_cores = cpu_count() parallel_set = np.array_split(model_input, cpu_cores, axis=0) parallel_list = [] # generating list of datasets for parallel for i in range(cpu_cores): parallel_list.append((parallel_set[i], some_option_list)) # parallel pool = Pool(cpu_cores) res = pool.starmap(dg.imp_vol_generator, parallel_list) res = np.concatenate(res, axis = 1) price_output = res[0] imp_vol_output = res[1] # saving grid datasets np.savetxt("Data/sobol_final_input"+str(no_sobol)+".csv", gridInput, delimiter=",") np.savetxt("Data/sobol_final_price"+str(no_sobol)+".csv", price_output, delimiter=",") np.savetxt("Data/sobol_final_imp"+str(no_sobol)+".csv", imp_vol_output, delimiter=",") return 0
def monte_carlo_generator(input_array: np.ndarray, paths: int): option_input = option_input_generator() some_option_list = np.array([]) for option in option_input: some_option_list = np.append(some_option_list, vo.EUCall(option[0], option[1])) output_price_matrix = np.empty([np.shape(input_array)[0], 25]) output_imp_vol_matrix = np.empty([np.shape(input_array)[0], 25]) i = 0 for someInput in input_array: output_price_matrix[i, :], output_imp_vol_matrix[i, :] = calc_mc_data( someInput, paths) i += 1 return output_price_matrix, output_imp_vol_matrix
def calc_mc_data(input_array: np.array, paths: int) -> (np.array, np.array): option_array = option_input_generator() some_option_list = np.array([]) for option in option_array: some_option_list = np.append(some_option_list, vo.EUCall(option[0], option[1])) some_model = hm.HestonClass(input_array[0], input_array[1], input_array[2], input_array[3], input_array[4], input_array[5], input_array[6]) output_lenght = np.shape(some_option_list)[0] output_price = np.empty(output_lenght, dtype=np.float64) output_imp_vol = np.empty(output_lenght, dtype=np.float64) for i in range(output_lenght): output_price[i] = mc.Heston_monte_carlo(some_model, some_option_list[i], paths) output_imp_vol[i] = some_model.impVol(output_price[i], some_option_list[i]) return output_price, output_imp_vol
kappa1 = 2 kappa2 = 0.1 theta1 = 0.04 theta2 = 0.01 epsilon1 = 0.5 epsilon2 = 2 epsilon = np.linspace(start=0.5, stop=2, num=10) rho1 = -0.7 rho2 = 0.8 rate = 0.05 input_array = np.array(list(itertools.product(spot, epsilon))) tau = 1.005 #set to match option data strike = 100 some_option = vo.EUCall(tau, strike) spot = np.reshape(spot, (-1, 1)) spot_plot = np.linspace(start=75, stop=125, num=200) spot_plot = np.reshape(spot_plot, (-1, 1)) eps1_plot = np.reshape(np.repeat(epsilon1, len(spot_plot)), (-1, 1)) eps2_plot = np.reshape(np.repeat(epsilon2, len(spot_plot)), (-1, 1)) input_multi_easy = np.concatenate([spot_plot, eps1_plot], axis=1) input_multi_hard = np.concatenate([spot_plot, eps2_plot], axis=1) h = 0.1 input_good_easy = np.concatenate([ spot_plot, np.reshape(np.repeat(vol1, len(spot_plot)), (-1, 1)), np.reshape(np.repeat(kappa1, len(spot_plot)), (-1, 1)), np.reshape(np.repeat(theta1, len(spot_plot)), (-1, 1)),
output_price_matrix[i, :], output_imp_vol_matrix[i, :] = calc_imp_vol( someInput, option_list) i += 1 return output_price_matrix, output_imp_vol_matrix if __name__ == "__main__": #model_input = model_input_generator() model_input = model_input_random_generator(200000) option_input = option_input_generator() # different option combinations some_option_list = np.array([]) for option in option_input: some_option_list = np.append(some_option_list, vo.EUCall(option[0], option[1])) # going parallel if cpu_count() == 4: cpu_cores = 4 else: cpu_cores = int(min(cpu_count() / 4, 16)) parallel_set = np.array_split(model_input, cpu_cores, axis=0) parallel_list = [] # generating list of datasets for parallel for i in range(cpu_cores): parallel_list.append((parallel_set[i], some_option_list)) # parallel pool = Pool(cpu_cores)
# rate rate = 0.05 # Which options to test # Maturity no_mats = 10 maturity = np.linspace(start = 0.01, stop = 2, num = no_mats) # strike no_strikes = 10 strike = np.linspace(start = 75, stop = 125, num = no_strikes) option_input = np.array(list(itertools.product(maturity, strike))) # different option combinations someOptionList = np.array([]) for option in option_input: someOptionList = np.append(someOptionList, vo.EUCall(option[0], option[1])) # Dataframe for NN with multiple outputs test1Data = np.array((forward, vol, kappa, theta, epsilon, rho, rate)) test1Data = np.reshape(test1Data, (1, 7)) # Model test for multiple outputs predictions_grid_1 = norm_labels_grid_1.inverse_transform(model_grid_1.predict(norm_feature_grid_1.transform(test1Data))) predictions_grid_2 = norm_labels_grid_2.inverse_transform(model_grid_2.predict(norm_feature_grid_2.transform(test1Data))) # Model test for single outputs testLength = np.shape(option_input)[0] predictions_single = np.empty(testLength) start_predict = time.time() for i in range(testLength): testData = np.concatenate((test1Data, option_input[i]), axis=None)
kappa1 = 2 kappa2 = 0.1 theta1 = 0.04 theta2 = 0.01 epsilon1 = 0.5 epsilon2 = 2 epsilon = np.linspace(start = 0.5, stop = 2, num = 10) rho1 = -0.7 rho2 = 0.8 rate = 0.05 input_array = np.array(list(itertools.product(spot, epsilon))) tau = 1.05 #set to match option data strike = 100 some_option = vo.EUCall(tau, strike) spot = np.reshape(spot, (-1, 1)) ### Single data al_output1 = np.loadtxt("Data/al_output1.csv", delimiter=",") mc_output1 = np.loadtxt("Data/mc_output1.csv", delimiter=",") al_output2 = np.loadtxt("Data/al_output2.csv", delimiter=",") mc_output2 = np.loadtxt("Data/mc_output2.csv", delimiter=",") al_output1 = np.reshape(al_output1, (-1, 1)) mc_output1 = np.reshape(mc_output1, (-1, 1)) al_output2 = np.reshape(al_output2, (-1, 1)) mc_output2 = np.reshape(mc_output2, (-1, 1)) ### Multi data
some_put = vo.EUPut(some_option.tau, some_option.strike) put_price = np.exp(-some_model.rate * some_option.tau) * (np.average( some_put(forward))) print(put_price) call_price = put_price - np.exp(-some_model.rate * some_option.tau) * ( some_option.strike - some_model.forward) else: call_price = np.exp(-some_model.rate * some_option.tau) * (np.average( some_option(forward))) return call_price if __name__ == '__main__': test_model = hm.HestonClass(50, 0.01, 0.1, 0.01, 2, 0.8, 0.05) test_option = vo.EUCall(0.01, 100) print(Heston_monte_carlo(test_model, test_option, 5000)) print(Heston_monte_carlo(test_model, test_option, 5000, True)) print(al.Andersen_Lake(test_model, test_option)) """ model_input = np.loadtxt("Data/MC/HestonMC_input.csv", delimiter=",") mc_imp_vol_1 = np.loadtxt("Data/MC/Heston_mc_imp_vol_1.csv", delimiter=",") mc_price_1 = np.loadtxt("Data/MC/HestonMC_price_1.csv", delimiter=",") mc_imp_vol_10 = np.loadtxt("Data/MC/Heston_mc_imp_vol_10.csv", delimiter=",") mc_price_10 = np.loadtxt("Data/MC/HestonMC_price_10.csv", delimiter=",") mc_imp_vol_100 = np.loadtxt("Data/MC/Heston_mc_imp_vol_100.csv", delimiter=",") mc_price_100 = np.loadtxt("Data/MC/HestonMC_price_100.csv", delimiter=",") mc_imp_vol_1000 = np.loadtxt("Data/MC/Heston_mc_imp_vol_1000.csv", delimiter=",") mc_price_1000 = np.loadtxt("Data/MC/HestonMC_price_1000.csv", delimiter=",") mc_imp_vol_10000 = np.loadtxt("Data/MC/Heston_mc_imp_vol_10000.csv", delimiter=",")
import numpy as np import itertools import matplotlib.pyplot as plt from matplotlib import cm import joblib from keras.models import load_model import glob from sklearn.metrics import mean_squared_error as mse from sklearn.preprocessing import MinMaxScaler, StandardScaler from keras.optimizers import Adam import os import itertools import pickle from Thesis.Heston import AndersenLake as al, HestonModel as hm, DataGeneration as dg, ModelGenerator as mg, MC_al, ModelTesting as mt from Thesis.misc import VanillaOptions as vo from Thesis.BlackScholes import BlackScholes as bs some_easy_case = mt.easy_case() some_heston_model = hm.HestonClass(*some_easy_case[0]) some_option = vo.EUCall(2, 75) al.Andersen_Lake(some_heston_model, some_option)
import numpy as np import time import matplotlib.pyplot as plt from Thesis.Heston import AndersenLake as al, MonteCarlo as mc, HestonModel as hm from Thesis.misc import VanillaOptions as vo model_input = np.loadtxt("Data/benchmark_input.csv", delimiter=",") #imp_vol = np.loadtxt("Data/benchmark_input.csv", delimiter = ",") some_model = hm.HestonClass(*model_input[0]) some_option = vo.EUCall(0.1, 87.5) price = al.Andersen_Lake(some_model, some_option) print(price) imp_vol = some_model.impVol(price, some_option) print(imp_vol)
def model_testing2(model_list: list, plot_title: str) -> list: some_easy_case = easy_case() some_hard_case = hard_case() option = option_input() model_class_easy = hm.HestonClass(some_easy_case[0, 0], some_easy_case[0, 1], some_easy_case[0, 2], some_easy_case[0, 3], some_easy_case[0, 4], some_easy_case[0, 5], some_easy_case[0, 6]) model_class_hard = hm.HestonClass(some_hard_case[0, 0], some_hard_case[0, 1], some_hard_case[0, 2], some_hard_case[0, 3], some_hard_case[0, 4], some_hard_case[0, 5], some_hard_case[0, 6]) some_option_list = np.array([]) for some_option in option: some_option_list = np.append(some_option_list, vo.EUCall(some_option[0], some_option[1])) benchmark_price_easy, benchmark_easy = dg.calc_imp_vol( some_easy_case[0], some_option_list) benchmark_price_hard, benchmark_hard = dg.calc_imp_vol( some_hard_case[0], some_option_list) fig = plt.figure(figsize=(30, 20), dpi=200) imp_ax_easy = fig.add_subplot(221, projection='3d') error_ax_easy = fig.add_subplot(222, projection='3d') imp_ax_hard = fig.add_subplot(223, projection='3d') error_ax_hard = fig.add_subplot(224, projection='3d') no_models = len(model_list) color = iter(plt.cm.gist_rainbow(np.linspace(0, 1, no_models))) x = option[:, 0] y = option[:, 1] mse_list = [] for model_string in model_list: some_easy_case = easy_case() some_hard_case = hard_case() model_string = ' '.join(glob.glob("Models5/*/" + model_string)) model = load_model(model_string) model_folder = model_string[:model_string.rfind("/") + 1] if os.path.exists(model_folder + "/norm_feature.pkl"): norm_feature = joblib.load(model_folder + "norm_feature.pkl") normal_in = True else: normal_in = False if os.path.exists(model_folder + "/norm_labels.pkl"): norm_labels = joblib.load(model_folder + "norm_labels.pkl") normal_out = True else: normal_out = False if (model_string.find("Single") != -1 or model_string.find("single") != -1): # single output predictions_easy = np.zeros(np.shape(option)[0]) predictions_hard = np.zeros(np.shape(option)[0]) for i in range(np.shape(option)[0]): test_single_input_easy = np.concatenate( (some_easy_case, option[i]), axis=None) test_single_input_easy = np.reshape(test_single_input_easy, (1, -1)) test_single_input_hard = np.concatenate( (some_hard_case, option[i]), axis=None) test_single_input_hard = np.reshape(test_single_input_hard, (1, -1)) if normal_in: test_single_input_easy = norm_feature.transform( test_single_input_easy) test_single_input_hard = norm_feature.transform( test_single_input_hard) if normal_out: predictions_easy[i] = norm_labels.inverse_transform( model.predict(test_single_input_easy)) predictions_hard[i] = norm_labels.inverse_transform( model.predict(test_single_input_hard)) else: predictions_easy[i] = model.predict(test_single_input_easy) predictions_hard[i] = model.predict(test_single_input_hard) else: # we have a grid if normal_in: some_easy_case = norm_feature.transform(some_easy_case) some_hard_case = norm_feature.transform(some_hard_case) if normal_out: predictions_easy = norm_labels.inverse_transform( model.predict(some_easy_case))[0] predictions_hard = norm_labels.inverse_transform( model.predict(some_hard_case))[0] else: predictions_easy = model.predict(some_easy_case)[0] predictions_hard = model.predict(some_hard_case)[0] # if prices, calc imp vol if (model_string.find("Price") != -1 or model_string.find("price") != -1): imp_vol_predictions_easy = np.zeros(np.shape(predictions_easy)) imp_vol_predictions_hard = np.zeros(np.shape(predictions_hard)) for i in range(np.shape(predictions_easy)[0]): imp_vol_predictions_easy[i] = model_class_easy.impVol( predictions_easy[i], some_option_list[i]) imp_vol_predictions_hard[i] = model_class_hard.impVol( predictions_hard[i], some_option_list[i]) predictions_easy = imp_vol_predictions_easy predictions_hard = imp_vol_predictions_hard c = next(color) z_easy = predictions_easy z_hard = predictions_hard name = model_string[model_string.find("/") + 1:] imp_ax_easy.plot_trisurf(x, y, z_easy, alpha=0.5, label=name, color=c) imp_ax_hard.plot_trisurf(x, y, z_hard, alpha=0.5, label=name, color=c) predictions = np.concatenate((predictions_easy, predictions_hard)) benchmark = np.concatenate((benchmark_easy, benchmark_hard)) mse_list.append((name, mse(predictions, benchmark))) error_ax_easy.plot_trisurf(x, y, z_easy - benchmark_easy, alpha=0.5, label=name, color=c) error_ax_hard.plot_trisurf(x, y, z_hard - benchmark_hard, alpha=0.5, label=name, color=c) imp_ax_easy.plot_trisurf(x, y, benchmark_easy, color="black", alpha=0.5, label="benchmark") imp_ax_easy.set_ylabel("Strike") imp_ax_easy.set_xlabel("Time to maturity") imp_ax_easy.set_title("Implied volatility, easy case") error_ax_easy.set_ylabel("Strike") error_ax_easy.set_xlabel("Time to maturity") error_ax_easy.set_title("Error") imp_ax_hard.plot_trisurf(x, y, benchmark_hard, color="black", alpha=0.5, label="benchmark") imp_ax_hard.set_ylabel("Strike") imp_ax_hard.set_xlabel("Time to maturity") imp_ax_hard.set_title("Implied volatility, hard case") error_ax_hard.set_ylabel("Strike") error_ax_hard.set_xlabel("Time to maturity") error_ax_hard.set_title("Error") handles, labels = imp_ax_easy.get_legend_handles_labels() for i in range(len(handles)): handles[i]._facecolors2d = handles[i]._facecolors3d handles[i]._edgecolors2d = handles[i]._edgecolors3d fig.subplots_adjust(top=0.95, left=0.1, right=0.95, bottom=0.2) fig.legend(handles, labels, loc="lower center", ncol=4, fontsize=15) fig.suptitle(plot_title, fontsize=20) plt.savefig("Final_plots/" + plot_title.replace(" ", "_") + ".png") plt.close() return mse_list
def timing(model_string: str) -> float: some_model = hm.HestonClass(100, 0.04, 2, 0.04, 0.5, -0.7, 0.05) some_model_array = np.array((100, 0.04, 2, 0.04, 0.5, -0.7, 0.05)) option = mt.option_input() some_option_list = np.array([]) for some_option in option: some_option_list = np.append(some_option_list, vo.EUCall(some_option[0], some_option[1])) model_string = "standardize_single_5_1000.h5" model_string = ' '.join(glob.glob("Models5/*/" + model_string)) model = load_model(model_string) model_folder = model_string[:model_string.rfind("/") + 1] if os.path.exists(model_folder + "/norm_feature.pkl"): norm_feature = joblib.load(model_folder + "norm_feature.pkl") normal_in = True else: normal_in = False if os.path.exists(model_folder + "/norm_labels.pkl"): norm_labels = joblib.load(model_folder + "norm_labels.pkl") normal_out = True else: normal_out = False if (model_string.find("single") != -1): # single output predictions = np.zeros(np.shape(option)[0]) test_grid = np.zeros((25, 9)) for i in range(np.shape(option)[0]): test_single_input = np.concatenate((some_model_array, option[i]), axis=None) test_single_input = np.reshape(test_single_input, (1, -1)) if normal_in: test_single_input = norm_feature.transform(test_single_input) test_grid[i] = test_single_input elif (model_string.find("mat") != -1): # single output predictions = np.zeros(np.shape(option)[0]) test_grid = np.zeros((5, 8)) for i in range(5): test_mat_input = np.concatenate( (some_model_array, option[i * 5][0]), axis=None) test_mat_input = np.reshape(test_mat_input, (1, -1)) if normal_in: test_mat_input = norm_feature.transform(test_mat_input) test_grid[i] = test_mat_input else: # we have a grid if normal_in: some_model_array = norm_feature.transform(some_model_array) test_grid = some_model_array inp_tensor = tf.convert_to_tensor(test_grid) start_time = time.time() for i in range(100): if normal_out: predictions = norm_labels.inverse_transform(model(test_grid)) else: predictions = model(test_grid) stop_time = time.time() return (stop_time - start_time) / 100