def compare_values(M0=50, I=5000):
    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)
Пример #2
0
def lsm_compare_values(M0=50, I=5000):
    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)
Пример #3
0
def BCC_jump_calculate_model_values(p0):
    ''' Calculates all model values given parameter vector p0. '''
    lamb, mu, delta = p0
    values = []
    for row, option in options.iterrows():
        T = (option['Maturity'] - option['Date']).days / 365.
        B0T = B([r0, kappa_r, theta_r, sigma_r, 0, T])
        r = -math.log(B0T) / T
        model_value = BCC_call_value(S0, option['Strike'], T, r, kappa_v,
                                     theta_v, sigma_v, rho, v0, lamb, mu,
                                     delta)
        values.append(model_value)
    return np.array(values)
Пример #4
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
def BCC97_hedge_simulation(M=50, I=1000):
    ''' 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)
    # initial option value for S0
    V0LSM = BCC97_lsm_put_value(S0, K, T, M, I)[0]
    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