Ejemplo n.º 1
0
def create_cpu(nspots=30, nvols=30):
    F = HestonFiniteDifferenceEngine(H, nspots=nspots,
                                        nvols=nvols, spotdensity=10, varexp=4,
                                        var_max=12, verbose=False)
    F.init()
    F.operators[1].diagonalize()
    return F
Ejemplo n.º 2
0
    def setUp(self):
        DefaultHeston = HestonOption(spot=100,
                                     strike=100,
                                     interest_rate=0.03125,
                                     volatility=0.2,
                                     tenor=1.0,
                                     mean_reversion=1,
                                     mean_variance=0.12,
                                     vol_of_variance=0.3,
                                     correlation=10.4)
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
        # mean_reversion=3, mean_variance=0.04,
        # vol_of_variance=0.6, correlation=-0.7)

        self.dt = 1.0 / 2.0
        self.F = HestonFiniteDifferenceEngine(option,
                                              nspots=5,
                                              nvols=5,
                                              force_bandwidth=None,
                                              flip_idx_var=False)

        # self.F = HestonFiniteDifferenceEngine(H, nspots=100,
        # nvols=100, spotdensity=10, varexp=4,
        # var_max=12, flip_idx_spot=False,
        # flip_idx_var=False, verbose=False,
        # force_bandwidth=None,
        # force_exact=False)
        self.F.init()
        self.FGG = FDG.HestonFiniteDifferenceEngine(
            option, nspots=self.F.grid.shape[0], nvols=self.F.grid.shape[1])
        self.FGG.set_zero_derivative()
        self.FGG.make_operator_templates()
Ejemplo n.º 3
0
    def setUp(self):
        DefaultHeston = HestonOption(spot=100,
                                     strike=100,
                                     interest_rate=0.06,
                                     volatility=0.2,
                                     tenor=1.0,
                                     mean_reversion=1,
                                     mean_variance=0.12,
                                     vol_of_variance=0.3,
                                     correlation=0.4)
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
        # mean_reversion=3, mean_variance=0.04,
        # vol_of_variance=0.6, correlation=-0.7)

        self.dt = 1.0 / 150.0
        self.F = HestonFiniteDifferenceEngine(option,
                                              nspots=150,
                                              nvols=80,
                                              force_bandwidth=None,
                                              flip_idx_var=False)

        self.F.init()
        self.F.operators[1].diagonalize()
        self.FG = FDG.HestonFiniteDifferenceEngine(option,
                                                   nspots=self.F.grid.shape[0],
                                                   nvols=self.F.grid.shape[1])
        self.FG.make_operator_templates()
        self.FG.set_zero_derivative()
        self.FG.scale_and_combine_operators()
    def setUp(self):
        DefaultHeston = HestonBarrierOption(spot=100
                        , strike=100
                        , interest_rate=0.06
                        , volatility = 0.2
                        , tenor=1.0
                        , mean_reversion = 1
                        , mean_variance = 0.12
                        , vol_of_variance = 0.3
                        , correlation = 0.4
                        , top = (False, 170.0)
                        )
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
                                        # mean_reversion=3, mean_variance=0.04,
                                        # vol_of_variance=0.6, correlation=-0.7)


        self.dt = 1.0/150.0
        self.F = HestonFiniteDifferenceEngine(option, nspots=150,
                                                   nvols=80,
                                                   force_bandwidth=None,
                                                   flip_idx_var=False)


        self.F.init()
        self.F.operators[1].diagonalize()
        self.FG = FDG.HestonFiniteDifferenceEngine(option,
                                                   nspots=self.F.grid.shape[0],
                                                   nvols=self.F.grid.shape[1])
        self.FG.make_operator_templates()
        self.FG.set_zero_derivative()
        self.FG.scale_and_combine_operators()
Ejemplo n.º 5
0
    def setUp(self):
        DefaultHeston = HestonOption(spot=100
                        , strike=100
                        , interest_rate=0.03125
                        , volatility = 0.2
                        , tenor=1.0
                        , mean_reversion = 1
                        , mean_variance = 0.12
                        , vol_of_variance = 0.3
                        , correlation = 10.4
                        )
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
                                        # mean_reversion=3, mean_variance=0.04,
                                        # vol_of_variance=0.6, correlation=-0.7)


        self.dt = 1.0/2.0
        self.F = HestonFiniteDifferenceEngine(option, nspots=5,
                                                   nvols=5,
                                                   force_bandwidth=None,
                                                   flip_idx_var=False)


        # self.F = HestonFiniteDifferenceEngine(H, nspots=100,
                                         # nvols=100, spotdensity=10, varexp=4,
                                         # var_max=12, flip_idx_spot=False,
                                         # flip_idx_var=False, verbose=False,
                                         # force_bandwidth=None,
                                         # force_exact=False)
        self.F.init()
        self.FGG = FDG.HestonFiniteDifferenceEngine(option, nspots=self.F.grid.shape[0], nvols=self.F.grid.shape[1])
        self.FGG.set_zero_derivative()
        self.FGG.make_operator_templates()
Ejemplo n.º 6
0
    def setUp(self):
        DefaultHeston = HestonOption(spot=100
                        , strike=100
                        , interest_rate=0.03
                        , volatility = 0.2
                        , tenor=1.0
                        , mean_reversion = 1
                        , mean_variance = 0.12
                        , vol_of_variance = 0.3
                        , correlation = 0.4
                        )
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
                                        # mean_reversion=3, mean_variance=0.04,
                                        # vol_of_variance=0.6, correlation=-0.7)


        self.dt = 1.0/150.0
        self.F = HestonFiniteDifferenceEngine(option, nspots=150,
                                                   nvols=80,
                                                   force_bandwidth=None,
                                                   flip_idx_var=False)


        # self.F = HestonFiniteDifferenceEngine(H, nspots=100,
                                         # nvols=100, spotdensity=10, varexp=4,
                                         # var_max=12, flip_idx_spot=False,
                                         # flip_idx_var=False, verbose=False,
                                         # force_bandwidth=None,
                                         # force_exact=False)
        self.F.init()
        self.F.operators[1].diagonalize()
class HestonBarrierOption_test(unittest.TestCase):

    def setUp(self):
        DefaultHeston = HestonBarrierOption(spot=100
                        , strike=100
                        , interest_rate=0.06
                        , volatility = 0.2
                        , tenor=1.0
                        , mean_reversion = 1
                        , mean_variance = 0.12
                        , vol_of_variance = 0.3
                        , correlation = 0.4
                        , top = (False, 170.0)
                        )
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
                                        # mean_reversion=3, mean_variance=0.04,
                                        # vol_of_variance=0.6, correlation=-0.7)


        self.dt = 1.0/150.0
        self.F = HestonFiniteDifferenceEngine(option, nspots=150,
                                                   nvols=80,
                                                   force_bandwidth=None,
                                                   flip_idx_var=False)


        self.F.init()
        self.F.operators[1].diagonalize()
        self.FG = FDG.HestonFiniteDifferenceEngine(option,
                                                   nspots=self.F.grid.shape[0],
                                                   nvols=self.F.grid.shape[1])
        self.FG.make_operator_templates()
        self.FG.set_zero_derivative()
        self.FG.scale_and_combine_operators()


    def test_implicit(self):
        t, dt = self.F.option.tenor, self.dt
        dt = 1/600.0
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_implicit(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        V2 = self.F.solve_implicit(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        # ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V2, V, ans, V - ans
        npt.assert_array_almost_equal(V, V2, decimal=6)
        # npt.assert_allclose(V, ans, rtol=0.001)


    def test_douglas(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_douglas(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        V2 = self.F.solve_douglas(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        # ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V, ans, V - ans
        # npt.assert_allclose(V, ans, rtol=0.001)
        npt.assert_array_almost_equal(V, V2, decimal=6)


    def test_hundsdorferverwer(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_hundsdorferverwer(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        V2 = self.F.solve_hundsdorferverwer(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        # ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V2, V, ans, V - ans
        # npt.assert_allclose(V, ans, rtol=0.001)
        npt.assert_array_almost_equal(V, V2, decimal=7)


    def test_smooth(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_smooth(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        V2 = self.F.solve_smooth(t/dt, dt, self.F.grid.domain[-1])[self.F.idx]
        # ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V, ans, V - ans
        # npt.assert_allclose(V, ans, rtol=0.001)
        npt.assert_array_almost_equal(V, V2, decimal=7)
class HestonOptionConstruction_test(unittest.TestCase):

    def setUp(self):
        DefaultHeston = HestonBarrierOption(spot=100
                        , strike=100
                        , interest_rate=0.03125
                        , volatility = 0.2
                        , tenor=1.0
                        , mean_reversion = 1
                        , mean_variance = 0.12
                        , vol_of_variance = 0.3
                        , correlation = 10.4
                        , top = (False, 170.0)
                        )
        option = DefaultHeston

        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
                                        # mean_reversion=3, mean_variance=0.04,
                                        # vol_of_variance=0.6, correlation=-0.7)

        self.dt = 1.0/2.0
        self.F = HestonFiniteDifferenceEngine(option, nspots=5,
                                                   nvols=5,
                                                   force_bandwidth=None,
                                                   force_exact=False,
                                                   flip_idx_var=False)

        # self.F = HestonFiniteDifferenceEngine(H, nspots=100,
                                         # nvols=100, spotdensity=10, varexp=4,
                                         # var_max=12, flip_idx_spot=False,
                                         # flip_idx_var=False, verbose=False,
                                         # force_bandwidth=None,
                                         # force_exact=False)

        self.F.init()

        self.FGG = FDG.HestonFiniteDifferenceEngine(option,
                                                    force_exact=False,
                                                    nspots=self.F.grid.shape[0],
                                                    nvols=self.F.grid.shape[1])
        self.FGG.set_zero_derivative()
        self.FGG.make_operator_templates()


    def test_scale_and_combine_FGG_0(self):
        self.FGG.scale_and_combine_operators(self.FGG.simple_operators)

        ref = self.F.operators[0]
        tst = self.FGG.operators[0].immigrate()

        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=13)
        tst.D *= 0
        ref.D *= 0
        npt.assert_equal(tst, ref)


    def test_scale_and_combine_FGG_1(self):
        self.FGG.scale_and_combine_operators()

        ref = self.F.operators[1]
        tst = self.FGG.operators[1]
        tst = tst.immigrate()

        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=14)
        tst.D *= 0
        ref.D *= 0
        npt.assert_equal(tst, ref)


    def test_scale_and_combine_FGG_01(self):
        self.FGG.scale_and_combine_operators()
        ref = self.F.operators[(0,1)].copy()
        tst = self.FGG.operators[(0,1)].immigrate()
        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=14)
        tst.D *= 0
        ref.D *= 0
        npt.assert_equal(tst, ref)

        dom = np.random.random(self.FGG.grid.shape)
        ref = self.FGG.operators[(0,1)].apply(dom.copy())
        tst = self.F.operators[(0,1)].apply(dom)
        fp(ref - tst, 'e')
        npt.assert_array_almost_equal(tst, ref, decimal=14)


    def test_verify_spots_FGG(self):
        ref = self.F.spots.copy()
        tst = self.FGG.spots.copy()
        npt.assert_equal(tst, ref)


    def test_verify_vars_FGG(self):
        ref = self.F.vars.copy()
        tst = self.FGG.vars.copy()
        npt.assert_equal(tst, ref)


    def test_verify_simple_operators_0_FGG(self):
        ref = self.F.simple_operators[(0,)].copy()
        tst = self.FGG.simple_operators[(0,)].copy().immigrate()
        npt.assert_equal(tst, ref)
        ref = self.F.simple_operators[(0,)].copy()
        tst = self.FGG.simple_operators[(0,)].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_equal(tst, ref)


    def test_verify_simple_operators_1_FGG(self):
        ref = self.F.simple_operators[(1,)].copy()
        tst = self.FGG.simple_operators[(1,)].copy().immigrate()
        npt.assert_equal(tst, ref)
        ref = self.F.simple_operators[(1,)].copy()
        tst = self.FGG.simple_operators[(1,)].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_equal(tst, ref)


    def test_verify_simple_operators_00_FGG(self):
        ref = self.F.simple_operators[(0,0)].copy()
        tst = self.FGG.simple_operators[(0,0)].copy().immigrate()
        npt.assert_equal(tst, ref)
        ref = self.F.simple_operators[(0,0)].copy()
        tst = self.FGG.simple_operators[(0,0)].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_equal(tst, ref)


    def test_verify_simple_operators_11_FGG(self):
        ref = self.F.simple_operators[(1,1)].copy()
        tst = self.FGG.simple_operators[(1,1)].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_array_almost_equal(ref.bottom_factors, tst.bottom_factors)
        tst.bottom_factors *= 0
        ref.bottom_factors *= 0
        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=14)
        tst.D *= 0
        ref.D *= 0
        npt.assert_equal(tst, ref)


    def test_verify_simple_operators_01_FGG(self):
        ref = self.F.simple_operators[(0,1)]
        tst = self.FGG.simple_operators[(0,1)].immigrate()
        npt.assert_equal(tst, ref)


    def test_add_operators_0_FGG(self):
        fst = self.F.simple_operators[(0,)]
        snd = self.F.simple_operators[(0,0)]
        ref = (snd + fst) + 0.5
        fst = self.FGG.simple_operators[(0,)]
        snd = self.FGG.simple_operators[(0,0)]
        tst = (snd + fst) + 0.5
        tst = tst.immigrate()
        tst.derivative = ref.derivative
        npt.assert_array_almost_equal(ref.D.data, tst.D.data, decimal=12)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)


    def test_add_operators_1(self):
        fst = self.F.simple_operators[(1,)]
        snd = self.F.simple_operators[(1,1)]
        ref = (snd + fst) + 0.5
        fst = self.FGG.simple_operators[(1,)]
        snd = self.FGG.simple_operators[(1,1)]
        tst = (snd + fst) + 0.5
        tst = tst.immigrate()
        tst.derivative = ref.derivative
        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)


    def test_scale_operators_0_FGG(self):
        d = (0,)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(self.F.coefficient_vector(self.F.coefficients[d],
            self.F.t, d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(
                self.FGG.coefficient_vector(self.F.coefficients[d],
                    self.FGG.t, d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)


    def test_scale_operators_00_FGG(self):
        d = (0,0)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
                self.F.coefficient_vector(self.F.coefficients[d], self.F.t,
                    d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(self.FGG.coefficient_vector(self.F.coefficients[d],
            self.FGG.t, d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)


    def test_scale_operators_1_FGG(self):
        d = (1,)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(self.F.coefficient_vector(self.F.coefficients[d],
            self.F.t, d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(self.FGG.coefficient_vector(self.F.coefficients[d],
            self.FGG.t, d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)


    def test_scale_operators_11_FGG(self):
        d = (1,1)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
                self.F.coefficient_vector(self.F.coefficients[d], self.F.t,
                    d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(self.FGG.coefficient_vector(self.F.coefficients[d],
            self.FGG.t, d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)


    def test_scale_operators_01_FGG(self):
        d = (0,1)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
                self.F.coefficient_vector(self.F.coefficients[d], self.F.t,
                    d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(self.FGG.coefficient_vector(self.F.coefficients[d],
            self.FGG.t, d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)
Ejemplo n.º 9
0
class HestonOption_test(unittest.TestCase):
    def setUp(self):
        DefaultHeston = HestonOption(spot=100,
                                     strike=100,
                                     interest_rate=0.06,
                                     volatility=0.2,
                                     tenor=1.0,
                                     mean_reversion=1,
                                     mean_variance=0.12,
                                     vol_of_variance=0.3,
                                     correlation=0.4)
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
        # mean_reversion=3, mean_variance=0.04,
        # vol_of_variance=0.6, correlation=-0.7)

        self.dt = 1.0 / 150.0
        self.F = HestonFiniteDifferenceEngine(option,
                                              nspots=150,
                                              nvols=80,
                                              force_bandwidth=None,
                                              flip_idx_var=False)

        self.F.init()
        self.F.operators[1].diagonalize()
        self.FG = FDG.HestonFiniteDifferenceEngine(option,
                                                   nspots=self.F.grid.shape[0],
                                                   nvols=self.F.grid.shape[1])
        self.FG.make_operator_templates()
        self.FG.set_zero_derivative()
        self.FG.scale_and_combine_operators()

    def test_implicit(self):
        t, dt = self.F.option.tenor, self.dt
        dt = 1 / 600.0
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_implicit(t / dt, dt,
                                   self.F.grid.domain[-1])[self.F.idx]
        V2 = self.F.solve_implicit(t / dt, dt,
                                   self.F.grid.domain[-1])[self.F.idx]
        ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V2, V, ans, V - ans
        npt.assert_array_almost_equal(V, V2, decimal=6)
        npt.assert_allclose(V, ans, rtol=0.001)

    def test_douglas(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_douglas(t / dt, dt,
                                  self.F.grid.domain[-1])[self.F.idx]
        ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot, self.F.spots[self.F.idx[0]]
        # print "Price:", V, ans, V - ans
        npt.assert_allclose(V, ans, rtol=0.001)

    def test_hundsdorferverwer(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_hundsdorferverwer(t / dt, dt,
                                            self.F.grid.domain[-1])[self.F.idx]
        V2 = self.F.solve_hundsdorferverwer(t / dt, dt,
                                            self.F.grid.domain[-1])[self.F.idx]
        ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V2, V, ans, V - ans
        npt.assert_allclose(V, ans, rtol=0.001)
        npt.assert_array_almost_equal(V, V2, decimal=7)

    def test_smooth(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.FG.solve_smooth(t / dt, dt,
                                 self.F.grid.domain[-1])[self.F.idx]
        ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V, ans, V - ans
        npt.assert_allclose(V, ans, rtol=0.001)
Ejemplo n.º 10
0
class HestonOptionConstruction_test(unittest.TestCase):
    def setUp(self):
        DefaultHeston = HestonOption(spot=100,
                                     strike=100,
                                     interest_rate=0.03125,
                                     volatility=0.2,
                                     tenor=1.0,
                                     mean_reversion=1,
                                     mean_variance=0.12,
                                     vol_of_variance=0.3,
                                     correlation=10.4)
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
        # mean_reversion=3, mean_variance=0.04,
        # vol_of_variance=0.6, correlation=-0.7)

        self.dt = 1.0 / 2.0
        self.F = HestonFiniteDifferenceEngine(option,
                                              nspots=5,
                                              nvols=5,
                                              force_bandwidth=None,
                                              flip_idx_var=False)

        # self.F = HestonFiniteDifferenceEngine(H, nspots=100,
        # nvols=100, spotdensity=10, varexp=4,
        # var_max=12, flip_idx_spot=False,
        # flip_idx_var=False, verbose=False,
        # force_bandwidth=None,
        # force_exact=False)
        self.F.init()
        self.FGG = FDG.HestonFiniteDifferenceEngine(
            option, nspots=self.F.grid.shape[0], nvols=self.F.grid.shape[1])
        self.FGG.set_zero_derivative()
        self.FGG.make_operator_templates()

    def test_scale_and_combine_FGG_0(self):
        self.FGG.scale_and_combine_operators(self.FGG.simple_operators)

        ref = self.F.operators[0]
        tst = self.FGG.operators[0].immigrate()

        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=14)
        tst.D *= 0
        ref.D *= 0
        npt.assert_array_almost_equal(tst.R, ref.R, decimal=12)
        tst.R *= 0
        ref.R *= 0
        npt.assert_equal(tst, ref)

    def test_scale_and_combine_FGG_1(self):
        self.FGG.scale_and_combine_operators()

        ref = self.F.operators[1]
        tst = self.FGG.operators[1]
        tst = tst.immigrate()

        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=14)
        tst.D *= 0
        ref.D *= 0
        npt.assert_equal(tst, ref)

    def test_scale_and_combine_FGG_01(self):
        self.FGG.scale_and_combine_operators()
        ref = self.F.operators[(0, 1)].copy()
        tst = self.FGG.operators[(0, 1)].immigrate()

        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=14)
        tst.D *= 0
        ref.D *= 0
        npt.assert_equal(tst, ref)

        dom = np.random.random(self.FGG.grid.shape)
        ref = self.FGG.operators[(0, 1)].apply(dom.copy())
        tst = self.F.operators[(0, 1)].apply(dom)
        fp(ref - tst, 'e')
        npt.assert_array_almost_equal(tst, ref, decimal=14)

    def test_verify_simple_operators_0_FGG(self):
        ref = self.F.simple_operators[(0, )].copy()
        tst = self.FGG.simple_operators[(0, )].copy().immigrate()

        npt.assert_equal(tst, ref)
        ref = self.F.simple_operators[(0, )].copy()
        tst = self.FGG.simple_operators[(0, )].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_equal(tst, ref)

    def test_verify_simple_operators_1_FGG(self):
        ref = self.F.simple_operators[(1, )].copy()
        tst = self.FGG.simple_operators[(1, )].copy().immigrate()
        npt.assert_equal(tst, ref)
        ref = self.F.simple_operators[(1, )].copy()
        tst = self.FGG.simple_operators[(1, )].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_equal(tst, ref)

    def test_verify_simple_operators_00_FGG(self):
        ref = self.F.simple_operators[(0, 0)].copy()
        tst = self.FGG.simple_operators[(0, 0)].copy().immigrate()
        npt.assert_equal(tst, ref)
        ref = self.F.simple_operators[(0, 0)].copy()
        tst = self.FGG.simple_operators[(0, 0)].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_equal(tst, ref)

    def test_verify_simple_operators_11_FGG(self):
        ref = self.F.simple_operators[(1, 1)].copy()
        tst = self.FGG.simple_operators[(1, 1)].copy()
        ref.diagonalize(), tst.diagonalize()
        tst = tst.immigrate()
        npt.assert_array_almost_equal(ref.bottom_factors, tst.bottom_factors)
        tst.bottom_factors *= 0
        ref.bottom_factors *= 0
        npt.assert_array_almost_equal(tst.D.data, ref.D.data, decimal=14)
        tst.D *= 0
        ref.D *= 0
        npt.assert_equal(tst, ref)

    def test_verify_simple_operators_01_FGG(self):
        ref = self.F.simple_operators[(0, 1)]
        tst = self.FGG.simple_operators[(0, 1)].immigrate()
        npt.assert_equal(tst, ref)

    def test_add_operators_0_FGG(self):
        fst = self.F.simple_operators[(0, )]
        snd = self.F.simple_operators[(0, 0)]
        ref = (snd + fst) + 0.5
        fst = self.FGG.simple_operators[(0, )]
        snd = self.FGG.simple_operators[(0, 0)]
        tst = (snd + fst) + 0.5
        tst = tst.immigrate()
        tst.derivative = ref.derivative
        npt.assert_array_almost_equal(ref.D.data, tst.D.data, decimal=12)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)

    def test_add_operators_1(self):
        fst = self.F.simple_operators[(1, )]
        snd = self.F.simple_operators[(1, 1)]
        ref = (snd + fst) + 0.5
        fst = self.FGG.simple_operators[(1, )]
        snd = self.FGG.simple_operators[(1, 1)]
        tst = (snd + fst) + 0.5
        tst = tst.immigrate()
        tst.derivative = ref.derivative
        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)

    def test_scale_operators_0_FGG(self):
        d = (0, )
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
            self.F.coefficient_vector(self.F.coefficients[d], self.F.t, d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(
            self.FGG.coefficient_vector(self.F.coefficients[d], self.FGG.t,
                                        d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)

    def test_scale_operators_00_FGG(self):
        d = (0, 0)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
            self.F.coefficient_vector(self.F.coefficients[d], self.F.t, d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(
            self.FGG.coefficient_vector(self.F.coefficients[d], self.FGG.t,
                                        d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)

    def test_scale_operators_1_FGG(self):
        d = (1, )
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
            self.F.coefficient_vector(self.F.coefficients[d], self.F.t, d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(
            self.FGG.coefficient_vector(self.F.coefficients[d], self.FGG.t,
                                        d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)

    def test_scale_operators_11_FGG(self):
        d = (1, 1)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
            self.F.coefficient_vector(self.F.coefficients[d], self.F.t, d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(
            self.FGG.coefficient_vector(self.F.coefficients[d], self.FGG.t,
                                        d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)

    def test_scale_operators_01_FGG(self):
        d = (0, 1)
        ref = self.F.simple_operators[d]
        ref.vectorized_scale(
            self.F.coefficient_vector(self.F.coefficients[d], self.F.t, d[0]))
        tst = self.FGG.simple_operators[d]
        tst.vectorized_scale_from_host(
            self.FGG.coefficient_vector(self.F.coefficients[d], self.FGG.t,
                                        d[0]))
        tst = tst.immigrate()

        npt.assert_array_almost_equal(ref.D.data, tst.D.data)
        tst.D.data *= 0
        ref.D.data *= 0
        npt.assert_equal(tst, ref)
Ejemplo n.º 11
0
def dt_convergence(nspots=100, nvols=100, scheme=None):
    # global F, vals, errs
    errors = []
    schemes = {
        'hv':
        lambda dt: F.solve_hundsdorferverwer(
            H.tenor / dt, dt, F.grid.domain[-1], theta=0.65),
        'i':
        lambda dt: F.solve_implicit(H.tenor / dt, dt, F.grid.domain[-1]),
        'd':
        lambda dt: F.solve_implicit(
            H.tenor / dt, dt, F.grid.domain[-1], theta=0.65),
        'smooth':
        lambda dt: F.smooth(
            H.tenor / dt, dt, F.grid.domain[-1], smoothing_steps=1)
    }
    for i in range(1, 11):
        schemes = {}
        schemes[(1, )] = [{"scheme": "forward"}]
        F = HestonFiniteDifferenceEngine(H,
                                         schemes=schemes,
                                         nspots=nspots,
                                         nvols=nvols,
                                         spotdensity=10,
                                         varexp=4,
                                         var_max=12,
                                         flip_idx_spot=True,
                                         flip_idx_var=True,
                                         verbose=False)
        if scheme is None:
            scheme = 'hv'
        dt = 1.0 / 2.0**i
        print dt, tuple("%.1e" % ((max(mesh) - min(mesh)) / len(mesh))
                        for mesh in F.grid.mesh)
        print map(len, F.grid.mesh), map(min,
                                         F.grid.mesh), map(max, F.grid.mesh)

        Vs = schemes[scheme](dt)

        xs = F.spots
        ys = F.vars
        trimx = (0.0 * H.spot <= xs) & (xs <= 2.0 * H.spot)
        trimy = ys <= 1.0
        tr = lambda x: x[trimx, :][:, trimy]

        xst = xs[trimx]
        yst = ys[trimy]
        res = tr(Vs)
        a = tr(F.grid_analytical)
        bad = F.BADANALYTICAL
        price_err = F.price - H.analytical
        inf_norm = max(abs(res - a).flat)
        norm2 = pylab.sqrt(sum(((res - a)**2).flat))
        err = norm2
        # err = abs(price_err[0,0])
        # print dt, price_err, err
        # pp(Vs, F.grid_analytical, xs, ys, label="$dt = %s$" % dt, bad=bad)
        # p(Vs, F.grid_analytical, xs, ys, label="$dt = %s$" % dt, bad=bad)
        p(res, a, xst, yst, label="$dt = %s$" % dt, bad=bad)
        errors.append((dt, err))
    print errors
    vals, errs = zip(*errors)
    pylab.plot(vals, errs)
    pylab.plot(vals, errs, 'ro')
    pylab.xlabel("dt")
    pylab.ylabel("Error")
    pylab.show()
    pylab.loglog(vals, errs)
    pylab.loglog(vals, errs, 'ro')
    pylab.xlabel("dt")
    pylab.ylabel("Error")
    pylab.show()

    return errors
Ejemplo n.º 12
0
        (0.0, lambda t, *dim: np.maximum(0.0, dim[0] - H.strike)),
    ),
    # Free boundary
    (1, 1): (
        (None, lambda *x: None),
        # D intrinsic value at high variance
        (0.0, lambda t, *dim: np.maximum(0.0, dim[0] - H.strike)),
    ),
}

# schemes = {(1,) : ({"scheme": "center"}, {"scheme": "backward", "from" : flip_idx_var})}


utils.tic("Building FDE Engine")
# F = FDE.FiniteDifferenceEngineADI(G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=(-2, 2))
F = HestonFiniteDifferenceEngine(H, nspots=nspots, nvols=nvols, flip_idx_spot=flip_idx_spot, flip_idx_var=flip_idx_var)
utils.toc()

L1_ = []
R1_ = []
utils.tic("Building As(s):\t")
print "(Up/Down)wind from:", flip_idx_spot
As_ = utils.nonuniform_complete_coefficients(dss, up_or_down=up_or_down_spot, flip_idx=flip_idx_spot)[0]
Ass_ = utils.nonuniform_complete_coefficients(dss)[1]
# As_, Ass_ = utils.nonuniform_forward_coefficients(dss)
assert not np.isnan(As_.data).any()
assert not np.isnan(Ass_.data).any()
mu_sfunc = mu_s
gamma2_sfunc = gamma2_s
for j, v in enumerate(vars):
    # Be careful not to overwrite our operators
Ejemplo n.º 13
0
class HestonOption_test(unittest.TestCase):

    def setUp(self):
        DefaultHeston = HestonOption(spot=100
                        , strike=100
                        , interest_rate=0.03
                        , volatility = 0.2
                        , tenor=1.0
                        , mean_reversion = 1
                        , mean_variance = 0.12
                        , vol_of_variance = 0.3
                        , correlation = 0.4
                        )
        option = DefaultHeston
        # option = HestonOption(tenor=1, strike=99.0, volatility=0.2,
                                        # mean_reversion=3, mean_variance=0.04,
                                        # vol_of_variance=0.6, correlation=-0.7)


        self.dt = 1.0/150.0
        self.F = HestonFiniteDifferenceEngine(option, nspots=150,
                                                   nvols=80,
                                                   force_bandwidth=None,
                                                   flip_idx_var=False)


        # self.F = HestonFiniteDifferenceEngine(H, nspots=100,
                                         # nvols=100, spotdensity=10, varexp=4,
                                         # var_max=12, flip_idx_spot=False,
                                         # flip_idx_var=False, verbose=False,
                                         # force_bandwidth=None,
                                         # force_exact=False)
        self.F.init()
        self.F.operators[1].diagonalize()


    def test_implicit(self):
        t, dt = self.F.option.tenor, self.dt
        dt = 1.0/600.0
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.F.solve_implicit(t/dt, dt)[self.F.idx]
        ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V, ans, V - ans
        npt.assert_allclose(V, ans, rtol=0.001)


    def test_douglas(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.F.solve_douglas(t/dt, dt)[self.F.idx]
        ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V, ans, V - ans
        npt.assert_allclose(V, ans, rtol=0.001)


    def test_smooth(self):
        t, dt = self.F.option.tenor, self.dt
        for d, o in self.F.operators.items():
            if type(d) != tuple:
                assert o.is_tridiagonal(), "%s, %s" % (d, o.D.offsets)
        V = self.F.solve_smooth(t/dt, dt)[self.F.idx]
        ans = self.F.option.analytical
        # print "Spot:", self.F.option.spot
        # print "Price:", V, ans, V - ans
        npt.assert_allclose(V, ans, rtol=0.001)
Ejemplo n.º 14
0
def create_cpu(nspots=30, nvols=30):
    F = HestonFiniteDifferenceEngine(H, nspots=nspots, nvols=nvols, spotdensity=10, varexp=4, var_max=12, verbose=False)
    F.init()
    F.operators[1].diagonalize()
    return F