예제 #1
0
    def plot_vars_and_means(asset, ax1, ax2):
        '''
        Produces plots for upper left and upper right.
        '''

        solver = option.SimpleLayeredMCOptionSolver(max_interval_length=.01,
                                                    base_steps=10000,
                                                    min_L=5)

        (price, means, variances,
         counts) = solver.solve_option_price(asset, True)
        for l, (m, v, c) in enumerate(zip(means, variances, counts)):
            print(l, m, v, c)

        # means and variances actually contain V(p(l) - p(l-1))
        layer_means = np.array(means).cumsum()
        layer_vars = np.array(variances).cumsum()

        # take log of base 4, for plotting
        variances = [math.log(v, 4) for v in variances]
        layer_vars = [math.log(v, 4) for v in layer_vars]
        means = [math.log(abs(m), 4) for m in means]
        layer_means = [math.log(abs(m), 4) for m in layer_means]

        ax1.plot([1, 2, 3, 4, 5], layer_vars, marker='x', label="P_l")
        ax1.plot([2, 3, 4, 5],
                 variances[1:],
                 ls="--",
                 marker='x',
                 label="P_l - P_(l-1)")
        ax1.set_xlabel("l")
        ax1.set_ylabel("Log_M Variance")
        ax1.legend()

        ax2.plot([1, 2, 3, 4, 5], layer_means, marker='x', label="P_l")
        ax2.plot([2, 3, 4, 5],
                 means[1:],
                 ls="--",
                 marker='x',
                 label="P_l - P_(l-1)")
        ax2.set_xlabel("l")
        ax2.set_ylabel("Log_M |mean|")
        ax2.legend()
예제 #2
0
def create_hist(opt, n_trials=500, n_bins=20, interval=.005):

    exact_solver = option.AnalyticEuropeanStockOptionSolver()
    exact_sol = exact_solver.solve_option_price(opt)

    lower_bound = exact_sol - interval
    upper_bound = exact_sol + interval

    solver = option.SimpleLayeredMCOptionSolver(max_interval_length=interval,
                                                base_steps=1000)

    approx_sols = np.zeros((n_trials, 1))
    in_bound_count = 0
    for i in range(n_trials):
        approx_sol = solver.solve_option_price(opt, False)
        if lower_bound <= approx_sol <= upper_bound:
            in_bound_count += 1
        approx_sols[i] = approx_sol

    mean, sigma = np.mean(approx_sols), np.std(approx_sols)
    conf_int = stats.norm.interval(.95, loc=mean, scale=sigma)
    fig, ax = plt.subplots()
    ax.hist(approx_sols, bins=50)
    ax.axvline(x=conf_int[0], color='r', ls='--', label='95% CI')
    ax.axvline(x=conf_int[1], color='r', ls='--')
    ax.axvline(x=lower_bound,
               color='g',
               ls='--',
               label='epsilon +/-%f' % interval)
    ax.axvline(x=upper_bound, color='g', ls='--')
    ax.set_xlabel("Option Price")
    ax.set_ylabel("Count")
    plt.legend(loc='upper right', bbox_to_anchor=(1.02, 1), borderaxespad=0)

    plt.title(
        "%i trials; Sample Empirical Var.%.2E\nNo. Samples in epsilon interval %i"
        % (n_trials, Decimal(np.var(approx_sols)), in_bound_count))

    plt.show()
예제 #3
0
    def plot_Npaths_for_epsilon(asset, ax3):

        epsilon_list = [.001, .0005, .0002, .0001]

        #epsilon_list = [.01, .005, .002, .001]

        def calc_comp_cost(counts, level_scaling_factor=4):
            C = counts[0]
            for l in range(1, len(counts)):
                C += counts[l] * (level_scaling_factor**l +
                                  level_scaling_factor**(l - 1))
            return C

        cost_list = []
        for i, e in enumerate(epsilon_list):
            print("NEW TRIAL")
            solver = option.SimpleLayeredMCOptionSolver(max_interval_length=e,
                                                        base_steps=1000,
                                                        min_L=3)

            (price, means, variances,
             counts) = solver.solve_option_price(asset, True)

            for l, (m, v, c) in enumerate(zip(means, variances, counts)):
                print(l, m, v, c)
            cost_list.append(calc_comp_cost(counts))
            layers = [i for i in range(len(counts))]
            ax3.plot(layers, counts, ls="--", marker='x', label="e = %s" % e)

        ax3.set_yscale('log')
        ax3.set_xlabel("l")
        ax3.set_ylabel("N_l")
        ax3.legend(loc='upper right')
        ax4.plot(epsilon_list, cost_list, marker='x', label='MLMC')
        ax4.set_xlabel("epsilon")
        ax4.set_ylabel("Cost (total MC steps)")
        ax4.legend(loc='upper right')
예제 #4
0
def plot_numpaths(one_option, ax3, ax4, epsilon_list, str_solver_type):
    '''
    Two lower graphs for simple layer solver or heuristic solver
    Args:
        str_solver_type (string): either "simple" or "heuristic"
    '''
    # this is num steps * epsilon**2
    ml_cost_list = []
    naive_cost_list = []
    for i, epsilon in enumerate(epsilon_list):
        print("NEW TRIAL")        
    
        if str_solver_type == "simple":
            layer_solver = option.SimpleLayeredMCOptionSolver(epsilon)
        elif str_solver_type == "heuristic":
            layer_solver = option.HeuristicLayeredMCOptionSolver(epsilon)
        else:
            raise ValueError("type is 'simple' or 'heuristic'")        
        (option_price, means, variances, counts) = layer_solver.solve_option_price(one_option, True)
        epsilon_scaled_cost = calc_total_numsteps(counts, layer_solver.level_scaling_factor) * epsilon**2
        ml_cost_list.append(epsilon_scaled_cost)
        ax3.plot(range(len(counts)), counts, ls="--",marker='x',label="e = %s" % epsilon)
        
        naive_solver = option.NaiveMCOptionSolver(epsilon)
        option_value, pricer_stdev, n_paths, n_steps = naive_solver.solve_option_price(one_option, True)
        naive_cost_list.append(n_paths * n_steps * epsilon**2)
        
    ax3.set_yscale('log')
    ax3.set_xlabel("level")
    ax3.set_ylabel("N(l)")
    ax3.legend(loc='best')
    
    ax4.plot(epsilon_list, ml_cost_list, marker='x', label='MLMC')
    ax4.plot(epsilon_list, naive_cost_list, ls="--", marker='x', label='Std MC')
    ax4.set_xlabel("epsilon")
    ax4.set_ylabel("cost x square(epsilon)")
    ax4.legend(loc='best')
예제 #5
0
def main():
    spot_1 = 100
    vol_1 = 0.2 / (252**0.5)
    kappa_1 = 0.15 / (252**0.5)
    theta_1 = 0.25 / (252**0.5)
    gamma_1 = 0.1 / (252**0.5)
    
    spot_2 = 50
    vol_2 = 0.4 / (252**0.5)
    kappa_2 = 0.35 / (252**0.5)
    theta_2 = 0.5 / (252**0.5)
    gamma_2 = 0.2 / (252**0.5)
    
    risk_free = 0.05 / 252
    expiry = 100
    is_call = True
    
    hvs_1 = stock.VariableVolatilityStock(spot_1, vol_1, kappa_1, theta_1, theta_1)
    hvs_2 = stock.VariableVolatilityStock(spot_2, vol_2, kappa_2, theta_2, theta_2)
    
    cvs_1 = stock.ConstantVolatilityStock(spot_1, vol_1)
    cvs_2 = stock.ConstantVolatilityStock(spot_2, vol_2)
    
    heston_swaption = option.EuropeanSwaption([hvs_1, hvs_2], risk_free, expiry, is_call)
    constvol_vanilla = option.EuropeanStockOption(cvs_1, risk_free, expiry, is_call, spot_1)
    heston_vanilla = option.EuropeanStockOption(hvs_1, risk_free, expiry, is_call, spot_1)
    
    ROOT_DIR = os.getcwd()    
    
    # Case 1: simple layer solver, heston vol, swaption
    # filename = ROOT_DIR + '/figs/simple_layer_heston_swap'
    # fig, ((ax1,ax2), (ax3,ax4)) = plt.subplots(2,2)
    
    # epsilon = 2.0
    # simple_layer_solver = option.SimpleLayeredMCOptionSolver(epsilon)
    # plot_log_var_mean(heston_swaption, simple_layer_solver, ax1, ax2)
        
    # epsilon_list = [5.0, 4.0, 3.0, 2.0, 1.0]
    # plot_numpaths(heston_swaption, ax3, ax4, epsilon_list, 'simple')
    
    # plt.tight_layout()
    # plt.savefig(filename)
    
    # Case 2: heuristic layer solver, heston vol, swaption
    # filename = ROOT_DIR + '/figs/heuristic_layer_heston_swap'
    # fig, ((ax1,ax2), (ax3,ax4)) = plt.subplots(2,2)
    
    # epsilon = 1.0
    # heuristic_layer_solver = option.HeuristicLayeredMCOptionSolver(epsilon)
    # plot_log_var_mean(heston_swaption, heuristic_layer_solver, ax1, ax2)
    
    # epsilon_list = [4.0, 3.0, 2.0, 1.0, 0.5]
    # plot_numpaths(heston_swaption, ax3, ax4, epsilon_list, 'heuristic')
    
    # Case 3: simple layer solver, constant vol, vanilla call
    # filename = ROOT_DIR + '/figs/simple_layer_constvol_vanillacall'
    # fig, ((ax1,ax2), (ax3,ax4)) = plt.subplots(2,2)
    
    # epsilon = 0.1
    # simple_layer_solver = option.SimpleLayeredMCOptionSolver(epsilon)
    # plot_log_var_mean(constvol_vanilla, simple_layer_solver, ax1, ax2)
        
    # epsilon_list = [0.5, 0.4, 0.3, 0.2, 0.1]
    # plot_numpaths(constvol_vanilla, ax3, ax4, epsilon_list, 'simple')
    
    # Case 4: simple layer solver, heston vol, vanilla call
    filename = ROOT_DIR + '/figs/simple_layer_heston_vanillacall'
    fig, ((ax1,ax2), (ax3,ax4)) = plt.subplots(2,2)
    
    epsilon = 0.5
    simple_layer_solver = option.SimpleLayeredMCOptionSolver(epsilon)
    plot_log_var_mean(heston_vanilla, simple_layer_solver, ax1, ax2)
        
    epsilon_list = [2.5, 2.0, 1.5, 1.0, 0.5]
    plot_numpaths(heston_vanilla, ax3, ax4, epsilon_list, 'simple')
    
    plt.tight_layout()
    plt.savefig(filename)
    
    plt.show()