예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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)
예제 #4
0
 def test_Euro1d(self):
     T = 1
     domain = Domain1d(0, 6, T)
     vol, ir, dividend, strike = 0.1, 0.03, 0.01, 1
     solver = Euro1d(domain, vol, ir, dividend, strike, CallPutType.PUT)
     spot = 1
     solver.solve(400, 200)
     approx_put = solver.evaluate(spot, T)
     analytical = Analytical_Sol(spot, strike, T, ir, vol, dividend_yield=dividend)
     _, real_put = analytical.european_option_price()
     assert abs(approx_put-0.030050214069580493) < 0.00000000000001
     assert abs(approx_put-real_put)/real_put < 0.00054
예제 #5
0
 def restore_helper1d(self, t, nS, model_name, a, b, T, vol, ir, dividend,
                      strike, cpType):
     domain = Domain1d(a, b, T)
     solver = Euro1d(domain, vol, ir, dividend, strike, cpType)
     Sanaly, S = np.linspace(domain.a, domain.b,
                             nS), np.linspace(domain.a, domain.b,
                                              nS).reshape(-1, 1)
     fitted = solver.restore(S, t * np.ones_like(S), model_name)
     real_call, real_put = Analytical_Sol(
         Sanaly, strike, T - t, ir, vol,
         dividend_yield=dividend).european_option_price()
     if cpType == CallPutType.PUT:
         real = real_put
     elif cpType == CallPutType.CALL:
         real = real_call
     diff = abs(fitted - real)
     plt.plot(Sanaly, real, alpha=0.7, label="Real")
     plt.plot(Sanaly, fitted[0], alpha=0.7, label="Approx")
     print("error: {}; max error:{}; mean error: {}".format(
         diff, np.max(diff), np.mean(diff)))
     plt.legend()
     plt.show()
예제 #6
0
class Test(unittest.TestCase):
    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_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_price1d(self):
        np.random.seed(1)
        _, real_put = self.analytical1.european_option_price()
        approx_put = self.opt1.price(5000)
        assert abs(approx_put - 2.6101834050208175) < 0.00000000000001
        assert abs(approx_put - real_put) / real_put < 0.006187

    def test_price1d_V2(self):
        np.random.seed(1)
        _, real_put = self.analytical1.european_option_price()
        approx_put = self.opt1.priceV2(300000)
        assert abs(approx_put - 2.61594175018011) < 0.00000000000001
        assert abs(approx_put - real_put) / real_put < 0.003994

    def test_price_antithetic_variates(self):
        np.random.seed(1)
        _, real_put = self.analytical1.european_option_price()
        approx_put = self.opt1.price_antithetic_variates(5000)
        assert abs(approx_put - 2.631103908508011) < 0.00000000000001
        assert abs(approx_put - real_put) / real_put < 0.00178

    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_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
예제 #7
0
파일: MCEuroTest.py 프로젝트: tshih-tw/hdp
class Test(unittest.TestCase):
    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):
            tmp = np.sum(l, axis=1)
            return np.maximum(strike - tmp, np.zeros_like(tmp))

        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_sobol(self):
        _, real_put = self.analytical1.european_option_price()
        approx_put = self.opt1.priceV4(10000)
        assert abs(approx_put - 2.6263259615779786) < 0.00000000000001
        assert abs(approx_put - real_put) / real_put < 3.98046746e-05

    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

    def test_price1d(self):
        np.random.seed(1)
        _, real_put = self.analytical1.european_option_price()
        approx_put = self.opt1.price(5000)
        assert abs(approx_put - 2.6101834050208175) < 0.00000000000001
        assert abs(approx_put - real_put) / real_put < 0.006187

    def test_price1d_V2(self):
        np.random.seed(1)
        _, real_put = self.analytical1.european_option_price()
        approx_put = self.opt1.priceV2(300000)
        assert abs(approx_put - 2.61594175018011) < 0.00000000000001
        assert abs(approx_put - real_put) / real_put < 0.003994

    def test_price_antithetic_variates(self):
        np.random.seed(1)
        _, real_put = self.analytical1.european_option_price()
        approx_put = self.opt1.price_antithetic_variates(5000)
        assert abs(approx_put - 2.631103908508011) < 0.00000000000001
        assert abs(approx_put - real_put) / real_put < 0.00178

    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 np.maximum(np.sum(l, axis=1) - strike, np.zeros(len(l)))

        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_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 np.maximum(np.sum(l, axis=1) - strike, np.zeros(len(l)))

        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