Exemple #1
0
def compare_values(M0=50, I=50000):
    results = []
    for T in t_list:
        #
        # Simulation
        #
        M = int(M0 * T)
        cho_matrix = generate_cholesky(rho)
        rand = random_number_generator(M, I, anti_paths, moment_matching)
        r = SRD_generate_paths(r0, kappa_r, theta_r, sigma_r, T, M, I, rand, 0,
                               cho_matrix)
        v = SRD_generate_paths(v0, kappa_v, theta_v, sigma_v, T, M, I, rand, 2,
                               cho_matrix)
        S = B96_generate_paths(S0, r, v, lamb, mu, delta, rand, 1, 3,
                               cho_matrix, T, M, I, moment_matching)
        for K in k_list:
            #
            # Valuation
            #
            h = np.maximum(S[-1] - K, 0)
            B0T = B([r0, kappa_r, theta_r, sigma_r, 0.0, T])
            V0_mcs = B0T * np.sum(h) / I  # MCS estimator
            #
            # European Call Option via Fourier
            #
            ra = -math.log(B0T) / T  # average short rate/yield
            C0 = BCC_call_value(S0, K, T, ra, kappa_v, theta_v, sigma_v, rho,
                                v0, lamb, mu, delta)

            results.append((T, K, C0, V0_mcs, V0_mcs - C0))

    print(" %6s | %6s | %7s | %7s | %7s" % ('T', 'K', 'C0', 'MCS', 'DIFF'))
    for res in results:
        print(" %6.3f | %6d | %7.3f | %7.3f | %7.3f" % res)
Exemple #2
0
def lsm_compare_values(M0=50, I=50000):
    results = []
    for T in t_list:
        #
        # Simulation
        #
        M = int(M0 * T)
        cho_matrix = generate_cholesky(rho)
        rand = random_number_generator(M, I, anti_paths, moment_matching)
        r = SRD_generate_paths(r0, kappa_r, theta_r, sigma_r, T, M, I, rand, 0,
                               cho_matrix)
        v = SRD_generate_paths(v0, kappa_v, theta_v, sigma_v, T, M, I, rand, 2,
                               cho_matrix)
        S = B96_generate_paths(S0, r, v, lamb, mu, delta, rand, 1, 3,
                               cho_matrix, T, M, I, moment_matching)
        for K in k_list:
            #
            # Valuation
            #
            B0T = B([r0, kappa_r, theta_r, sigma_r, 0.0, T])
            V0_lsm = BCC97_lsm_valuation(S, r, v, K, T, M, I)
            # LSM estimator
            #
            # European Call Option via Fourier
            #
            ra = -math.log(B0T) / T  # average short rate/yield
            C0 = BCC_call_value(S0, K, T, ra, kappa_v, theta_v, sigma_v, rho,
                                v0, lamb, mu, delta)
            P0 = C0 + K * B0T - S0

            results.append((T, K, P0, V0_lsm, V0_lsm - P0))

    print(" %6s | %6s | %7s | %7s | %7s" % ('T', 'K', 'P0', 'LSM', 'DIFF'))
    for res in results:
        print(" %6.3f | %6d | %7.3f | %7.3f | %7.3f" % res)
Exemple #3
0
def plot_zcb_values(p0, T):
    ''' Plots unit zero-coupon bond values (discount factors). '''
    t_list = np.linspace(0.0, T, 20)
    r_list = B([r0, p0[0], p0[1], p0[2], t_list, T])
    plt.figure(figsize=(8, 5))
    plt.plot(t_list, r_list, 'b')
    plt.plot(t_list, r_list, 'ro')
    plt.xlabel('time horizon in years')
    plt.ylabel('unit zero-coupon bond value')
Exemple #4
0
def graphical_comparison(M=50, x_disc='exact'):
    MCS_values = zcb_estimator(M, x_disc)
    CIR_values = []
    dt = T / M
    t_list = np.arange(0.0, T + 0.001, dt)  # dates of interest
    for t in t_list:
        alpha = r0, kappa_r, theta_r, sigma_r, t, T
        CIR_values.append(B(alpha))
        # CIR model values given date list

    fig, ax = plt.subplots(2, sharex=True, figsize=(8, 6))
    ax[0].plot(t_list, MCS_values, 'ro', label='MCS values')
    ax[0].plot(t_list, CIR_values, 'b', label='CIR values')
    ax[0].legend(loc=0)
    ax[0].set_ylim(min(CIR_values) - 0.005, max(CIR_values) + 0.005)
    ax[0].set_ylabel('option values')
    ax[0].set_title('maturity $T=2$')
    ax[1].bar(t_list - 0.025 / 2., MCS_values - CIR_values, width=0.025)
    plt.ylabel('difference')
    plt.xlim(min(t_list) - 0.1, max(t_list) + 0.1)
    plt.xlabel('time $t$')
    plt.tight_layout()
Exemple #5
0
                print(tmpl_1 % ('T', 'K', 'V0', 'V0_LSM', 'V0_CV', 'P0',
                                'P0_MCS', 'err', 'rerr', 'acc1', 'acc2'))
            # correlation matrix, cholesky decomposition
            v0, kappa_v, sigma_v, rho = para[panel]
            correlation_matrix = np.zeros((3, 3), dtype=np.float)
            correlation_matrix[0] = [1.0, rho, 0.0]
            correlation_matrix[1] = [rho, 1.0, 0.0]
            correlation_matrix[2] = [0.0, 0.0, 1.0]
            CM = np.linalg.cholesky(correlation_matrix)

            z = 0  # option counter
            S, r, v, h, V, matrix = 0, 0, 0, 0, 0, 0
            gc.collect()
            for T in t_list:  # times-to-maturity
                # discount factor
                B0T = B([r0, kappa_r, theta_r, sigma_r, 0.0, T])
                # average constant short rate/yield
                ra = -math.log(B0T) / T
                # time interval in years
                dt = T / M
                # pseudo-random numbers
                rand = random_number_generator(M, I)
                # short rate process paths
                r = SRD_generate_paths(x_disc, r0, kappa_r, theta_r, sigma_r,
                                       T, M, I, rand, 0, CM)
                # volatility process paths
                v = SRD_generate_paths(x_disc, v0, kappa_v, theta_v, sigma_v,
                                       T, M, I, rand, 2, CM)
                # index level process paths
                S = H93_index_paths(S0, r, v, 1, CM)
                for K in k_list:  # strikes
Exemple #6
0
def BCC97_hedge_simulation(M=50, I=10000):
    ''' Monte Carlo simualtion of dynamic hedging paths
    for American put option in BSM model. '''
    #
    # Initializations
    #
    po = np.zeros(M + 1, dtype=np.float)  # vector for portfolio values
    delt = np.zeros(M + 1, dtype=np.float)  # vector for deltas
    ds = dis * S0
    V_1, S, r, v, ex, rg, h, dt = BCC97_lsm_put_value(S0 + (2 - a) * ds, K, T,
                                                      M, I)
    # 'data basis' for delta hedging
    V_2 = BCC97_lsm_put_value(S0 - a * ds, K, T, M, I)[0]
    delt[0] = (V_1 - V_2) / (2 * ds)
    V0LSM = BCC97_lsm_put_value(S0, K, T, M,
                                I)[0]  # initial option value for S0
    po[0] = V0LSM  # initial portfolio values

    #
    # Hedge Runs
    #
    pl_list = []
    runs = min(I, 10000)
    for run in range(runs):
        bo = V0LSM - delt[0] * S0  # initial bond position value
        p = run
        run += 1
        for t in range(1, M + 1, 1):
            if ex[t, p] == 0:
                df = math.exp((r[t, p] + r[t - 1, p]) / 2 * dt)
                if t != M:
                    po[t] = delt[t - 1] * S[t, p] + bo * df  # portfolio payoff
                    ds = dis * S[t, p]
                    sd = S[t, p] + (2 - a) * ds  # disturbed index level
                    stateV_A = [
                        sd * v[t, p] * r[t, p], sd * v[t, p], sd * r[t, p],
                        v[t, p] * r[t, p], sd**2, v[t, p]**2, r[t, p]**2, sd,
                        v[t, p], r[t, p], 1
                    ]
                    # state vector for S[t, p] + (2.0 - a) * ds
                    stateV_A.reverse()
                    V0A = max(0, np.dot(rg[t], stateV_A))
                    # revaluation via regression
                    sd = S[t, p] - a * ds  # disturbed index level
                    stateV_B = [
                        sd * v[t, p] * r[t, p], sd * v[t, p], sd * r[t, p],
                        v[t, p] * r[t, p], sd**2, v[t, p]**2, r[t, p]**2, sd,
                        v[t, p], r[t, p], 1
                    ]
                    # state vector for S[t, p] - a * ds
                    stateV_B.reverse()
                    V0B = max(0, np.dot(rg[t], stateV_B))
                    # revaluation via regression
                    delt[t] = (V0A - V0B) / (2 * ds)
                else:
                    po[t] = delt[t - 1] * S[t, p] + bo * df
                    delt[t] = 0.0
                bo = po[t] - delt[t] * S[t, p]
            else:
                po[t] = delt[t - 1] * S[t, p] + bo * df
                break
        alpha_t = [kappa_r, theta_r, sigma_r, r0, 0.0, t * dt]
        pl = (po[t] - h[t, p]) * B(alpha_t)
        if run % 1000 == 0:
            print "run %5d   p/l %8.3f" % (run, pl)
        pl_list.append(pl)
    pl_list = np.array(pl_list)

    #
    # Results Output
    #
    print "\nSUMMARY STATISTICS FOR P&L"
    print "---------------------------------"
    print "Dynamic Replications %12d" % runs
    print "Time Steps           %12d" % M
    print "Paths for Valuation  %12d" % I
    print "Maximum              %12.3f" % max(pl_list)
    print "Average              %12.3f" % np.mean(pl_list)
    print "Median               %12.3f" % np.median(pl_list)
    print "Minimum              %12.3f" % min(pl_list)
    print "---------------------------------"

    return pl_list