Пример #1
0
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
Пример #2
0
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
Пример #3
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
Пример #4
0
def Heston_monte_carlo(some_model: hm.HestonClass,
                       some_option: vo.VanillaOption,
                       paths: int,
                       use_parity: bool = False):
    dt = 252
    time_steps = int(some_option.tau * dt)
    forward_log = np.log(some_model.forward)
    vol = some_model.vol
    delta_t = some_option.tau / time_steps
    exp_part = np.exp(-some_model.kappa * delta_t)
    x_part = some_model.theta * (1 - exp_part)
    var_part1 = some_model.epsilon * some_model.epsilon / some_model.kappa * (
        exp_part - np.exp(-2 * some_model.kappa * delta_t))
    var_part2 = some_model.theta * some_model.epsilon * some_model.epsilon / (
        2 * some_model.kappa) * (1 - exp_part)**2
    corr_part = np.sqrt(1 - some_model.rho * some_model.rho)

    for i in range(time_steps):
        N_F = np.random.standard_normal(paths)

        N_v = some_model.rho * N_F + corr_part * np.random.standard_normal(
            paths)

        forward_log += -0.5 * vol * delta_t + np.sqrt(vol) * np.sqrt(
            delta_t) * N_F

        x = vol * exp_part + x_part

        var = vol * var_part1 + var_part2

        y = np.sqrt(np.log(var / (x * x) + 1))

        vol = x * np.exp(-(y * y) / 2 + y * N_v)

    forward = np.exp(forward_log)

    if (np.average(forward) < some_option.strike and use_parity):
        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
Пример #5
0
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
Пример #6
0
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)),
Пример #7
0
        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)
Пример #9
0
    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
Пример #10
0
        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=",")
Пример #11
0
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)
Пример #12
0
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)
Пример #13
0
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
Пример #14
0
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