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
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 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()
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 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)
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)
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)
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
(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
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)