def setUp(self): k = 3.0 nspots = 8 spot_max = 1500.0 spotdensity = 7.0 # infinity is linear? spots = utils.sinh_space(k, spot_max, spotdensity, nspots) self.flip_idx = 4 self.vec = spots self.C1 = FD.BO.for_vector(self.vec, scheme='center', derivative=1, order=2)
def setUp(self): spot_max = 1500.0 var_max = 13.0 nspots = 50 nvols = 30 spotdensity = 7.0 # infinity is linear? varexp = 4 self.strike = spot_max / 4.0 self.spots = utils.sinh_space(self.strike, spot_max, spotdensity, nspots) self.vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) self.Grid = Grid.Grid((self.spots, self.vars), initializer=lambda x0,x1: np.maximum(x0-self.strike,0))
def setUp(self): k = 3.0 nspots = 7 spot_max = 1500.0 spotdensity = 7.0 # infinity is linear? vec = utils.sinh_space(k, spot_max, spotdensity, nspots) self.vec = vec def coeff(high,low=None): if low is not None: high, low = low, high return np.linspace(0, 1, len(vec))[low:high] def fcoeff(i): return np.linspace(0, 1, len(vec))[i] def f0(x): return x*0.0 def fx(x): return x+2.0 data = np.ones((5,len(vec))) data[0][:2] = 0 data[1][0] = 0 data[3][-1] = 0 data[4][-2:] = 0 offsets = [2,1,0,-1,-2] res = np.ones_like(vec) oldB = FD.BandedOperator((data, offsets), res) self.oldB = oldB manualB = oldB.copy() # newB = oldB.copy() # vecB = oldB.copy() manualB.D.data[0][2:] *= coeff(len(vec)-2) manualB.D.data[1][1:] *= coeff(len(vec)-1) manualB.D.data[2] *= coeff(len(vec)) manualB.D.data[3][:-1] *= coeff(1, len(vec)) manualB.D.data[4][:-2] *= coeff(2, len(vec)) manualB.R *= coeff(len(vec)) self.manualB = manualB self.coeff = coeff self.fcoeff = fcoeff self.f0 = f0 self.fx = fx
mean_variance=0.04, vol_of_variance=0.4, correlation=0.6, ) dt = 1 / 100.0 spot_max = 1500.0 var_max = 10.0 nspots = 100 nvols = 100 spotdensity = 7.0 # infinity is linear? varexp = 4 spots = utils.sinh_space(H.strike, spot_max, spotdensity, nspots) vars = utils.exponential_space(0.00, H.variance.value, var_max, varexp, nvols) # vars = [v0] # spots = np.linspace(0.0, spot_max, nspots) # vars = np.linspace(0.0, var_max, nvols) # plot(spots); title("Spots"); show() # plot(vars); title("Vars"); show() # H.strike = spots[min(abs(spots - H.strike)) == abs(spots - H.strike)][0] # H.spot = spots[min(abs(spots - H.spot)) == abs(spots - H.spot)][0] def init(spots, vars): return np.maximum(0, spots - H.strike) Gi = Grid(mesh=(spots, vars), initializer=init) G = Gi.copy()
def setUp(self): s1_enable = 1 s2_enable = 1 v1_enable = 1 v2_enable = 1 r_enable = 1 dirichlet_s = 1 dirichlet_v = 1 kappa = 1 r = 0.06 theta = 0.04 sigma = 0.4 rho = 0.6 spot_max = 1500.0 var_max = 13.0 nspots = 5 nvols = 5 spotdensity = 7.0 # infinity is linear? varexp = 5 up_or_down_spot = 'up' up_or_down_var = 'down' flip_idx_spot = nspots // 2 flip_idx_var = nvols // 2 k = spot_max / 4.0 # spots = np.linspace(0, spot_max, nspots) # vars = np.linspace(0, var_max, nvols) spots = utils.sinh_space(k, spot_max, spotdensity, nspots) vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) def mu_s(t, *dim): return r * dim[0] * s1_enable def gamma2_s(t, *dim): return 0.5 * dim[1] * dim[0]**2 * s2_enable def mu_v(t, *dim): return kappa * (theta - dim[1]) * v1_enable def gamma2_v(t, *dim): return 0.5 * sigma**2 * dim[1] * v2_enable coeffs = { (): lambda t: -r * r_enable, (0, ): mu_s, (0, 0): gamma2_s, (1, ): mu_v, (1, 1): gamma2_v, (0, 1): lambda t, *dim: dim[0] * dim[1] * rho * sigma } coeffs = {k: lambda *x: 1 for k in coeffs} bounds = { (0, ): ((0, lambda *args: 0), (1, lambda *args: 1)), (0, 0): ((0, lambda *args: 0), (None, lambda *args: 1)), (1, ): ((None, lambda *args: None), (None, lambda *args: None)), (1, 1): ((1, lambda *args: 0.0), (None, lambda *args: None)), } schemes = {} # G = Grid.Grid((spots, vars), initializer=lambda x0,x1: np.maximum(x0-k,0)) self.G = Grid.Grid((spots, vars), initializer=lambda x0, x1: x0 * x1) # print G self.F = FD.FiniteDifferenceEngineADI(self.G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=None) self.F.init() # self.F.operators[1].diagonalize() self.FG = FDG.FiniteDifferenceEngineADI() self.FG.from_host_FiniteDifferenceEngine(self.F)
def setUp(self): s1_enable = 1 s2_enable = 1 v1_enable = 1 v2_enable = 1 r_enable = 1 dirichlet_s = 1 dirichlet_v = 1 kappa = 1 r = 0.06 theta = 0.04 sigma = 0.4 rho = 0.6 spot_max = 1500.0 var_max = 13.0 nspots = 5 nvols = 5 spotdensity = 7.0 # infinity is linear? varexp = 5 # TODO:!!!!XXX TODO XXX # var_max = nvols-1 # spot_max = nspots-1 up_or_down_spot = 'up' up_or_down_var = 'down' flip_idx_spot = nspots // 2 flip_idx_var = nvols // 2 k = spot_max / 4.0 # spots = np.linspace(0, spot_max, nspots) # vars = np.linspace(0, var_max, nvols) spots = utils.sinh_space(k, spot_max, spotdensity, nspots) vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) def mu_s(t, *dim): return r * dim[0] * s1_enable def gamma2_s(t, *dim): return 0.5 * dim[1] * dim[0]**2 * s2_enable def mu_v(t, *dim): return kappa * (theta - dim[1]) * v1_enable def gamma2_v(t, *dim): return 0.5 * sigma**2 * dim[1] * v2_enable coeffs = { (): lambda t: -r * r_enable, (0, ): mu_s, (0, 0): gamma2_s, (1, ): mu_v, (1, 1): gamma2_v, (0, 1): lambda t, *dim: dim[0] * dim[1] * rho * sigma } bounds = { # D: U = 0 VN: dU/dS = 1 ( 0, ): ((0 if dirichlet_s else 1, lambda *args: 0.0), (1, lambda *args: 1.0)), # D: U = 0 Free boundary (0, 0): ((0 if dirichlet_s else 1, lambda *args: 0.0), (None, lambda *x: 1.0)), # Free boundary at low variance ( 1, ): ( (None, lambda *x: None), # (0.0, lambda t, *dim: 0), # D intrinsic value at high variance # (None, lambda *x: None) (0 if dirichlet_v else 1, lambda t, *dim: np.maximum(0.0, dim[0] - k))), # # Free boundary (1, 1): ( (1, lambda *x: 0), # D intrinsic value at high variance # (None, lambda *x: None) (0 if dirichlet_v else 1, lambda t, *dim: np.maximum(0.0, dim[0] - k))) } schemes = {} schemes[(0, )] = ({ "scheme": "center" }, { "scheme": up_or_down_spot, "from": flip_idx_spot }) schemes[(1, )] = ({ "scheme": "center" }, { "scheme": up_or_down_var, "from": flip_idx_var }) dss = np.hstack((np.nan, np.diff(spots))) dvs = np.hstack((np.nan, np.diff(vars))) 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] L1_ = [] R1_ = [] # As_, Ass_ = utils.nonuniform_forward_coefficients(dss) assert (not np.isnan(As_.data).any()) assert (not np.isnan(Ass_.data).any()) for j, v in enumerate(vars): # Be careful not to overwrite operators As, Ass = As_.copy(), Ass_.copy() m = 2 mu_s = r * spots * s1_enable gamma2_s = 0.5 * v * spots**2 * s2_enable for i, z in enumerate(mu_s): # print z, coeffs[0,](0, spots[i]) assert z == coeffs[0, ](0, spots[i]) for i, z in enumerate(gamma2_s): # print z, coeffs[0,0](0, spots[i], v) assert z == coeffs[0, 0](0, spots[i], v) Rs = np.zeros(nspots) Rs[-1] = 1 As.data[m - 2, 2:] *= mu_s[:-2] As.data[m - 1, 1:] *= mu_s[:-1] As.data[m, :] *= mu_s As.data[m + 1, :-1] *= mu_s[1:] As.data[m + 2, :-2] *= mu_s[2:] Rs *= mu_s Rss = np.zeros(nspots) Rss[-1] = 2 * dss[-1] / dss[-1]**2 Ass.data[m + 1, -2] = 2 / dss[-1]**2 Ass.data[m, -1] = -2 / dss[-1]**2 Ass.data[m - 2, 2:] *= gamma2_s[:-2] Ass.data[m - 1, 1:] *= gamma2_s[:-1] Ass.data[m, :] *= gamma2_s Ass.data[m + 1, :-1] *= gamma2_s[1:] Ass.data[m + 2, :-2] *= gamma2_s[2:] Rss *= gamma2_s L1_.append(As.copy()) L1_[j].data += Ass.data L1_[j].data[m, :] -= 0.5 * r * r_enable L1_[j].data[m, 0] = 1 * dirichlet_s R1_.append((Rs + Rss).copy()) R1_[j][0] = 0 L2_ = [] R2_ = [] Av_ = utils.nonuniform_complete_coefficients(dvs, up_or_down=up_or_down_var, flip_idx=flip_idx_var)[0] Avv_ = utils.nonuniform_complete_coefficients(dvs)[1] assert (not np.isnan(Av_.data).any()) assert (not np.isnan(Avv_.data).any()) for i, s in enumerate(spots): mu_v = kappa * (theta - vars) * v1_enable gamma2_v = 0.5 * sigma**2 * vars * v2_enable # for j, z in enumerate(mu_v): # assert z == coeffs[1,](0, 0, vars[j]) # for j, z in enumerate(gamma2_v): # assert z == coeffs[1,1](0, 0, vars[j]) # Be careful not to overwrite our operators Av, Avv = Av_.copy(), Avv_.copy() m = 2 Av.data[m - 2, 2] = -dvs[1] / (dvs[2] * (dvs[1] + dvs[2])) Av.data[m - 1, 1] = (dvs[1] + dvs[2]) / (dvs[1] * dvs[2]) Av.data[m, 0] = (-2 * dvs[1] - dvs[2]) / (dvs[1] * (dvs[1] + dvs[2])) Av.data[m - 2, 2:] *= mu_v[:-2] Av.data[m - 1, 1:] *= mu_v[:-1] Av.data[m, :] *= mu_v Av.data[m + 1, :-1] *= mu_v[1:] Av.data[m + 2, :-2] *= mu_v[2:] Rv = np.zeros(nvols) Rv *= mu_v Avv.data[m - 1, 1] = 2 / dvs[1]**2 Avv.data[m, 0] = -2 / dvs[1]**2 Avv.data[m - 2, 2:] *= gamma2_v[:-2] Avv.data[m - 1, 1:] *= gamma2_v[:-1] Avv.data[m, :] *= gamma2_v Avv.data[m + 1, :-1] *= gamma2_v[1:] Avv.data[m + 2, :-2] *= gamma2_v[2:] Rvv = np.zeros(nvols) Rvv[0] = 2 * dvs[1] / dvs[1]**2 Rvv *= gamma2_v L2_.append(Av.copy()) L2_[i].data += Avv.data L2_[i].data[m, :] -= 0.5 * r * r_enable L2_[i].data[ m, -1] = 1 * dirichlet_v # This is to cancel out the previous value so we can # set the dirichlet boundary condition using R. # Then we have U_i + -U_i + R R2_.append(Rv + Rvv) R2_[i][-1] = 0 # np.maximum(0, s - k) def flatten_tensor(mats): diags = np.hstack([x.data for x in mats]) flatmat = scipy.sparse.dia_matrix( (diags, mats[0].offsets), shape=(diags.shape[1], diags.shape[1])) return flatmat L1 = flatten_tensor(L1_) L2 = flatten_tensor(L2_) R1 = np.array(R1_).T R2 = np.array(R2_) self.As_ = As_ self.Ass_ = Ass_ self.L1_ = L1 self.R1_ = R1 self.L2_ = L2 self.R2_ = R2 # G = Grid.Grid((spots, vars), initializer=lambda x0,x1: np.maximum(x0-k,0)) self.G = Grid.Grid((spots, vars), initializer=lambda x0, x1: x0 * x1) # print G self.F = FD.FiniteDifferenceEngineADI(self.G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=None) self.F.init()
def setUp(self): s1_enable = 1 s2_enable = 1 v1_enable = 1 v2_enable = 1 r_enable = 1 dirichlet_s = 1 dirichlet_v = 1 kappa = 1 r = 0.06 theta = 0.04 sigma = 0.4 rho = 0.6 spot_max = 1500.0 var_max = 13.0 nspots = 5 nvols = 5 spotdensity = 7.0 # infinity is linear? varexp = 5 up_or_down_spot = 'up' up_or_down_var = 'down' flip_idx_spot = nspots//2 flip_idx_var = nvols//2 k = spot_max / 4.0 # spots = np.linspace(0, spot_max, nspots) # vars = np.linspace(0, var_max, nvols) spots = utils.sinh_space(k, spot_max, spotdensity, nspots) vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) def mu_s(t, *dim): return r * dim[0] * s1_enable def gamma2_s(t, *dim): return 0.5 * dim[1] * dim[0]**2 * s2_enable def mu_v(t, *dim): return kappa * (theta - dim[1]) * v1_enable def gamma2_v(t, *dim): return 0.5 * sigma**2 * dim[1] * v2_enable coeffs = {() : lambda t: -r * r_enable, (0,) : mu_s, (0,0): gamma2_s, (1,) : mu_v, (1,1): gamma2_v, (0,1): lambda t, *dim: dim[0] * dim[1] * rho * sigma } coeffs = {k: lambda *x: 1 for k in coeffs} bounds = { (0,) : ((0, lambda *args: 0), (1, lambda *args: 1)), (0,0) : ((0, lambda *args: 0), (None, lambda *args: 1)), (1,) : ((None, lambda *args: None), (None, lambda *args: None)), (1,1) : ((1, lambda *args: 0.0), (None, lambda *args: None)), } schemes = {} # G = Grid.Grid((spots, vars), initializer=lambda x0,x1: np.maximum(x0-k,0)) self.G = Grid.Grid((spots, vars), initializer=lambda x0,x1: x0*x1) # print G self.F = FD.FiniteDifferenceEngineADI(self.G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=None) self.F.init() # self.F.operators[1].diagonalize() self.FG = FDG.FiniteDifferenceEngineADI() self.FG.from_host_FiniteDifferenceEngine(self.F)
def setUp(self): s1_enable = 1 s2_enable = 1 v1_enable = 1 v2_enable = 1 r_enable = 1 dirichlet_s = 1 dirichlet_v = 1 kappa = 1 r = 0.06 theta = 0.04 sigma = 0.4 rho = 0.6 spot_max = 1500.0 var_max = 13.0 nspots = 5 nvols = 5 spotdensity = 7.0 # infinity is linear? varexp = 5 # TODO:!!!!XXX TODO XXX # var_max = nvols-1 # spot_max = nspots-1 up_or_down_spot = "up" up_or_down_var = "down" flip_idx_spot = nspots // 2 flip_idx_var = nvols // 2 k = spot_max / 4.0 # spots = np.linspace(0, spot_max, nspots) # vars = np.linspace(0, var_max, nvols) spots = utils.sinh_space(k, spot_max, spotdensity, nspots) vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) def mu_s(t, *dim): return r * dim[0] * s1_enable def gamma2_s(t, *dim): return 0.5 * dim[1] * dim[0] ** 2 * s2_enable def mu_v(t, *dim): return kappa * (theta - dim[1]) * v1_enable def gamma2_v(t, *dim): return 0.5 * sigma ** 2 * dim[1] * v2_enable coeffs = { (): lambda t: -r * r_enable, (0,): mu_s, (0, 0): gamma2_s, (1,): mu_v, (1, 1): gamma2_v, (0, 1): lambda t, *dim: dim[0] * dim[1] * rho * sigma, } bounds = { # D: U = 0 VN: dU/dS = 1 (0,): ((0 if dirichlet_s else 1, lambda *args: 0.0), (1, lambda *args: 1.0)), # D: U = 0 Free boundary (0, 0): ((0 if dirichlet_s else 1, lambda *args: 0.0), (None, lambda *x: 1.0)), # Free boundary at low variance (1,): ( (None, lambda *x: None), # (0.0, lambda t, *dim: 0), # D intrinsic value at high variance # (None, lambda *x: None) (0 if dirichlet_v else 1, lambda t, *dim: np.maximum(0.0, dim[0] - k)), ), # # Free boundary (1, 1): ( (1, lambda *x: 0), # D intrinsic value at high variance # (None, lambda *x: None) (0 if dirichlet_v else 1, lambda t, *dim: np.maximum(0.0, dim[0] - k)), ), } schemes = {} schemes[(0,)] = ({"scheme": "center"}, {"scheme": up_or_down_spot, "from": flip_idx_spot}) schemes[(1,)] = ({"scheme": "center"}, {"scheme": up_or_down_var, "from": flip_idx_var}) dss = np.hstack((np.nan, np.diff(spots))) dvs = np.hstack((np.nan, np.diff(vars))) 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] L1_ = [] R1_ = [] # As_, Ass_ = utils.nonuniform_forward_coefficients(dss) assert not np.isnan(As_.data).any() assert not np.isnan(Ass_.data).any() for j, v in enumerate(vars): # Be careful not to overwrite operators As, Ass = As_.copy(), Ass_.copy() m = 2 mu_s = r * spots * s1_enable gamma2_s = 0.5 * v * spots ** 2 * s2_enable for i, z in enumerate(mu_s): # print z, coeffs[0,](0, spots[i]) assert z == coeffs[0,](0, spots[i]) for i, z in enumerate(gamma2_s): # print z, coeffs[0,0](0, spots[i], v) assert z == coeffs[0, 0](0, spots[i], v) Rs = np.zeros(nspots) Rs[-1] = 1 As.data[m - 2, 2:] *= mu_s[:-2] As.data[m - 1, 1:] *= mu_s[:-1] As.data[m, :] *= mu_s As.data[m + 1, :-1] *= mu_s[1:] As.data[m + 2, :-2] *= mu_s[2:] Rs *= mu_s Rss = np.zeros(nspots) Rss[-1] = 2 * dss[-1] / dss[-1] ** 2 Ass.data[m + 1, -2] = 2 / dss[-1] ** 2 Ass.data[m, -1] = -2 / dss[-1] ** 2 Ass.data[m - 2, 2:] *= gamma2_s[:-2] Ass.data[m - 1, 1:] *= gamma2_s[:-1] Ass.data[m, :] *= gamma2_s Ass.data[m + 1, :-1] *= gamma2_s[1:] Ass.data[m + 2, :-2] *= gamma2_s[2:] Rss *= gamma2_s L1_.append(As.copy()) L1_[j].data += Ass.data L1_[j].data[m, :] -= 0.5 * r * r_enable L1_[j].data[m, 0] = 1 * dirichlet_s R1_.append((Rs + Rss).copy()) R1_[j][0] = 0 L2_ = [] R2_ = [] Av_ = utils.nonuniform_complete_coefficients(dvs, up_or_down=up_or_down_var, flip_idx=flip_idx_var)[0] Avv_ = utils.nonuniform_complete_coefficients(dvs)[1] assert not np.isnan(Av_.data).any() assert not np.isnan(Avv_.data).any() for i, s in enumerate(spots): mu_v = kappa * (theta - vars) * v1_enable gamma2_v = 0.5 * sigma ** 2 * vars * v2_enable # for j, z in enumerate(mu_v): # assert z == coeffs[1,](0, 0, vars[j]) # for j, z in enumerate(gamma2_v): # assert z == coeffs[1,1](0, 0, vars[j]) # Be careful not to overwrite our operators Av, Avv = Av_.copy(), Avv_.copy() m = 2 Av.data[m - 2, 2] = -dvs[1] / (dvs[2] * (dvs[1] + dvs[2])) Av.data[m - 1, 1] = (dvs[1] + dvs[2]) / (dvs[1] * dvs[2]) Av.data[m, 0] = (-2 * dvs[1] - dvs[2]) / (dvs[1] * (dvs[1] + dvs[2])) Av.data[m - 2, 2:] *= mu_v[:-2] Av.data[m - 1, 1:] *= mu_v[:-1] Av.data[m, :] *= mu_v Av.data[m + 1, :-1] *= mu_v[1:] Av.data[m + 2, :-2] *= mu_v[2:] Rv = np.zeros(nvols) Rv *= mu_v Avv.data[m - 1, 1] = 2 / dvs[1] ** 2 Avv.data[m, 0] = -2 / dvs[1] ** 2 Avv.data[m - 2, 2:] *= gamma2_v[:-2] Avv.data[m - 1, 1:] *= gamma2_v[:-1] Avv.data[m, :] *= gamma2_v Avv.data[m + 1, :-1] *= gamma2_v[1:] Avv.data[m + 2, :-2] *= gamma2_v[2:] Rvv = np.zeros(nvols) Rvv[0] = 2 * dvs[1] / dvs[1] ** 2 Rvv *= gamma2_v L2_.append(Av.copy()) L2_[i].data += Avv.data L2_[i].data[m, :] -= 0.5 * r * r_enable L2_[i].data[m, -1] = 1 * dirichlet_v # This is to cancel out the previous value so we can # set the dirichlet boundary condition using R. # Then we have U_i + -U_i + R R2_.append(Rv + Rvv) R2_[i][-1] = 0 # np.maximum(0, s - k) def flatten_tensor(mats): diags = np.hstack([x.data for x in mats]) flatmat = scipy.sparse.dia_matrix((diags, mats[0].offsets), shape=(diags.shape[1], diags.shape[1])) return flatmat L1 = flatten_tensor(L1_) L2 = flatten_tensor(L2_) R1 = np.array(R1_).T R2 = np.array(R2_) self.As_ = As_ self.Ass_ = Ass_ self.L1_ = L1 self.R1_ = R1 self.L2_ = L2 self.R2_ = R2 # G = Grid.Grid((spots, vars), initializer=lambda x0,x1: np.maximum(x0-k,0)) self.G = Grid.Grid((spots, vars), initializer=lambda x0, x1: x0 * x1) # print G self.F = FD.FiniteDifferenceEngineADI( self.G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=None ) self.F.init()