def test_price1d_control_variates(self): strike = 45 asset_num = 1 init_price_vec = 50 * np.ones(asset_num) vol_vec = 0.3 * np.ones(asset_num) ir = 0.05 dividend_vec = np.zeros(asset_num) corr_mat = np.eye(asset_num) time_to_maturity = 0.25 random_walk = GBM(time_to_maturity, 100, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) analytical2 = Analytical_Sol(init_price_vec[0], strike, time_to_maturity, ir, vol_vec[0], dividend_yield=0) def test_payoff(*l): return max(np.sum(l) - strike, 0) opt2 = Euro(test_payoff, random_walk) real_call, _ = analytical2.european_option_price() np.random.seed(1) approx_call = opt2.price1d_control_variates(1000) np.random.seed(1) approx_call2 = opt2.price(1000) assert abs(approx_call - 6.412754547048265) < 0.00000000000001 assert abs(approx_call - real_call) / real_call < 0.0025422 assert abs(abs(approx_call2 - real_call) / real_call) < 0.04899
def test_correlated_pricing(self): strike = 50 asset_num = 2 init_price_vec = np.array([110, 60]) vol_vec = np.array([0.4, 0.2]) ir = 0.1 dividend_vec = 0 * np.ones(asset_num) corr_mat = np.eye(asset_num) corr_mat[0, 1] = 0.4 corr_mat[1, 0] = 0.4 random_walk = GBM(182 / 365, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(l): return max(l[0] - l[1] - strike, 0) opt = Euro(test_payoff, random_walk) np.random.seed(1) callV2 = opt.priceV2(1000000) real_call = 12.5583468 assert abs(callV2 - 12.566682253085943) < 0.00000000000001 assert abs(callV2 - real_call) / real_call < 0.00066374 np.random.seed(1) callV3 = opt.priceV3(20000) assert abs(callV3 - 12.586752483453562) < 0.00000000000001 assert abs(callV3 - real_call) / real_call < 0.0022619
def test_get_discounted_cashflow_at_t0(self): random_walk = GBM(3, 3, np.ones(1), 0.03, np.ones(1), np.zeros(1), np.eye(1)) def test_payoff(*l): return max(3 - np.sum(l), 0) opt = American(test_payoff, random_walk) discount = opt._get_discounted_cashflow_at_t0(np.array([[0, 0, 0, 0], [0, 0, 1, 0], [0, 2, 0, 0]])) assert discount == (0+np.exp(-2*0.03)+2*np.exp(-1*0.03))/3
def test_price_importance_sampling(self): strike = 80 asset_num = 1 init_price_vec = 50 * np.ones(asset_num) vol_vec = 0.2 * np.ones(asset_num) ir = 0.03 dividend_vec = np.zeros(asset_num) corr_mat = np.eye(asset_num) time_to_maturity = 1 random_walk = GBM(time_to_maturity, 100, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) analytical2 = Analytical_Sol(init_price_vec[0], strike, time_to_maturity, ir, vol_vec[0], dividend_yield=0) def test_payoff(*l): return max(np.sum(l) - strike, 0) test_payoff.strike = strike opt2 = Euro(test_payoff, random_walk) real_call, _ = analytical2.european_option_price() np.random.seed(1) approx_call = opt2.price_importance_sampling(10000) np.random.seed(1) weak_approx_call = opt2.priceV2(10000) assert abs(approx_call - 0.06082838151186516) < 0.00000000000001 assert abs(approx_call - real_call) / real_call < 0.00297664353761824 assert abs(weak_approx_call - real_call) / real_call < 0.1362349660567213
def setUp(self): strike = 100 asset_num = 1 init_price_vec = 100 * np.ones(asset_num) vol_vec = 0.1 * np.ones(asset_num) ir = 0.03 dividend_vec = np.zeros(asset_num) corr_mat = np.eye(asset_num) random_walk = GBM(1, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(*l): return max(strike - np.sum(l), 0) self.opt1 = Euro(test_payoff, random_walk) spot_price = init_price_vec[0] time_to_maturity = 1 interest_rate = 0.03 sigma = 0.1 self.analytical1 = Analytical_Sol(spot_price, strike, time_to_maturity, interest_rate, sigma, dividend_yield=0)
def test_get_discounted_cashflow(self): random_walk = GBM(3, 3, np.ones(1), 0.03, np.ones(1), np.zeros(1), np.eye(1)) def test_payoff(*l): return max(3 - np.sum(l), 0) opt = American(test_payoff, random_walk) cashflow_matrix = np.array([[0, 0, 0, 3], [0, 0, 0, 0], [0, 0, 0, 2]]) discounted = opt._get_discounted_cashflow(2, cashflow_matrix, 3) assert sum(abs(discounted - np.array([2.9113366, 0, 1.94089107]))) < 0.00000001 cashflow_matrix2 = np.array([[0, 0, 3, 0], [0, 0, 0, 0], [0, 0, 0, 2]]) discounted2 = opt._get_discounted_cashflow(0, cashflow_matrix2, 3) assert sum(abs(discounted2 - np.array([2.8252936, 0, 1.82786237]))) < 0.00000001
def setUp(self): strike = 1 asset_num = 1 init_price_vec = 0.99*np.ones(asset_num) vol_vec = 0.2*np.ones(asset_num) ir = 0.03 dividend_vec = np.zeros(asset_num) corr_mat = np.eye(asset_num) random_walk = GBM(1, 300, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(*l): return max(strike - np.sum(l), 0) self.opt1 = American(test_payoff, random_walk)
def test_amer_std(self): # although this is not a euro experiment... T = 1 strike = 50 asset_num = 1 init_price_vec = 50*np.ones(asset_num) vol_vec = 0.5*np.ones(asset_num) ir = 0.05 dividend_vec = np.zeros(asset_num) corr_mat = np.eye(asset_num) nTime = 365 random_walk = GBM(T, nTime, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(*l): return max(strike - np.sum(l), 0) opt = American(test_payoff, random_walk) MCAmerExperimentStd(10, 16, 30, opt)
def test_std_6d(self): dim = 6 T = 1 strike = 40 init_price_vec = np.full(dim, 40) vol = 0.2 ir = 0.06 dividend = 0.04 corr = 0.25 vol_vec = np.full(dim, vol) dividend_vec = np.full(dim, dividend) corr_mat = np.full((dim, dim), corr) np.fill_diagonal(corr_mat, 1) payoff_func = lambda x: np.maximum(strike - np.mean(x, axis=1), np.zeros(len(x))) random_walk = GBM(T, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) opt = Euro(payoff_func, random_walk) MCEuroExperimentStd(10, 19, 500, opt)
def test_price2d(self): np.random.seed(555) strike = 100 asset_num = 2 init_price_vec = 100*np.ones(asset_num) vol_vec = 0.2*np.ones(asset_num) ir = 0.05 dividend_vec = 0.1*np.ones(asset_num) corr_mat = np.eye(asset_num) corr_mat[0, 1] = 0.3 corr_mat[1, 0] = 0.3 random_walk = GBM(1, 300, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(*l): return max(np.max(l) - strike, 0) opt = American(test_payoff, random_walk) put = opt.price(3000) real_put = 9.6333 assert abs(put - 9.557936820537265) < 0.00000000000001 assert abs(put - real_put)/real_put < 0.00783
def test_amer(self): # although this is not a euro experiment... T = 1 strike = 50 asset_num = 1 init_price_vec = 50*np.ones(asset_num) vol_vec = 0.5*np.ones(asset_num) ir = 0.05 dividend_vec = np.zeros(asset_num) corr_mat = np.eye(asset_num) nTime = 365 random_walk = GBM(T, nTime, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(*l): return max(strike - np.sum(l), 0) opt = American(test_payoff, random_walk) analy = 8.723336355455928 np.random.seed(1) result = MCEuroExperiment(analy, 10, 16, opt, "V1") hdpPickle.dump(result, 'MCAmer_1d.pickle') print(result)
def test_conv_rate_6d_control_sobol(self): dim = 6 T = 1 strike = 40 init_price_vec = np.full(dim, 40) vol = 0.2 ir = 0.06 dividend = 0.04 corr = 0.25 vol_vec = np.full(dim, vol) dividend_vec = np.full(dim, dividend) corr_mat = np.full((dim, dim), corr) np.fill_diagonal(corr_mat, 1) payoff_func = lambda x: np.maximum(strike - np.mean(x, axis=1), np.zeros(len(x))) random_walk = GBM(T, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) opt = Euro(payoff_func, random_walk) analy = 1.50600 np.random.seed(1) result = MCEuroExperiment(analy, 14, 21, opt, "V8") hdpPickle.dump(result, 'MCEuro_6d_control_sobol.pickle') print(result)
def test_conv_rate_4dGA_anti_sol(self): from scipy.stats.mstats import gmean dim = 4 T = 1 strike = 40 init_price_vec = np.full(dim, 40) vol = 0.2 ir = 0.06 dividend = 0.04 corr = 0.25 vol_vec = np.full(dim, vol) dividend_vec = np.full(dim, dividend) corr_mat = np.full((dim, dim), corr) np.fill_diagonal(corr_mat, 1) payoff_func = lambda x: np.maximum((gmean(x, axis=1) - strike), np.zeros(len(x))) random_walk = GBM(T, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) opt = Euro(payoff_func, random_walk) analy = 2.165238512096621 np.random.seed(1) result = MCEuroExperiment(analy, 20, 24, opt, "V6") hdpPickle.dump(result, 'MCEuro_4dGA_AntiSol.pickle') print(result)
def test_nd_control_variates(self): from scipy.stats.mstats import gmean dim = 4 T = 1 strike = 40 init_price_vec = np.full(4, 40) vol = 0.2 ir = 0.06 dividend = 0.04 corr = 0.25 vol_vec = np.full(dim, vol) dividend_vec = np.full(dim, dividend) corr_mat = np.full((dim, dim), corr) np.fill_diagonal(corr_mat, 1) payoff_func = lambda x: np.maximum( (gmean(x, axis=1) - strike), np.zeros(len(x))) random_walk = GBM(T, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) opt = Euro(payoff_func, random_walk) np.random.seed(1) price = opt.priceV7(100000) assert abs(price - 2.16043821457437) < 1e-10
def test_geometric_avg_4d(self): from scipy.stats.mstats import gmean dim = 4 T = 1 strike = 40 init_price_vec = np.full(4, 40) vol = 0.2 ir = 0.06 dividend = 0.04 corr = 0.25 vol_vec = np.full(dim, vol) dividend_vec = np.full(dim, dividend) corr_mat = np.full((dim, dim), corr) np.fill_diagonal(corr_mat, 1) payoff_func = lambda x: np.maximum( (gmean(x, axis=1) - strike), np.zeros(len(x))) random_walk = GBM(T, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) opt = Euro(payoff_func, random_walk) np.random.seed(1) price = opt.priceV2(100000) # "real": 2.164959740690803 assert abs(price - 2.1654452369352635) < 1e-10 assert (price - 2.164959740690803) / 2.164959740690803 < 0.0002243
def test_correlated_pricing(self): strike = 50 asset_num = 2 init_price_vec = np.array([110, 60]) vol_vec = np.array([0.4, 0.2]) ir = 0.1 dividend_vec = 0 * np.ones(asset_num) corr_mat = np.eye(asset_num) corr_mat[0, 1] = 0.4 corr_mat[1, 0] = 0.4 random_walk = GBM(182 / 365, 400, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(l): return np.maximum(l[:, 0] - l[:, 1] - strike, np.zeros(len(l))) opt = Euro(test_payoff, random_walk) np.random.seed(1) callV2 = opt.priceV2(1000000) real_call = 12.5583468 assert abs(callV2 - 12.566682253085943) < 0.00000000000001 assert abs(callV2 - real_call) / real_call < 0.00066374 np.random.seed(1) callV3 = opt.priceV3(20000) assert abs(callV3 - 12.586752483453562) < 0.00000000000001 assert abs(callV3 - real_call) / real_call < 0.0022619 """ Test 2: european 2d spread put """ np.random.seed(1) def test_payoff2(l): return np.maximum(-l[:, 0] + l[:, 1] + strike, np.zeros(len(l))) opt = Euro(test_payoff2, random_walk) spreadput2d = opt.priceV2(500000) assert abs(spreadput2d - 10.108531893795202) < 1e-10
strike / self.random_walk.init_price_vec ) - self.random_walk.T * self.random_walk.vol_vec**2 / 2 scale = self.random_walk.vol_vec * sqrt(self.random_walk.T) density_ratio = norm.pdf(Zs, loc=norm_mean_old, scale=scale) / norm.pdf( Zs, loc=norm_mean_new, scale=scale) payoff = np.array( [self.payoff_func(Y) for Y in self.simulation_result]) return np.mean(np.multiply(payoff, density_ratio.T)) * np.exp( -self.random_walk.ir * self.random_walk.T) if __name__ == "__main__": import sys, os sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../') from blackscholes.utils.GBM import GBM init_price_vec = np.ones(5) vol_vec = 0.2 * np.ones(5) ir = 0.00 dividend_vec = np.zeros(5) corr_mat = np.eye(5) random_walk = GBM(3, 100, init_price_vec, ir, vol_vec, dividend_vec, corr_mat) def test_payoff(*l): return max(np.sum(l) - 5, 0) a = Euro(test_payoff, random_walk).price(10000) print(a)