def main(): N = 80 S0 = 100 Sl = 0 Su = 200 model = BinomialModel(N, dS, payoff) P = model.price(S0) fig = plt.figure() ax = fig.add_subplot(111, projection="3d") plot_H(ax, Sl, Su, model, P) ax.set_ylim(Sl, Su) ax.set_xlabel("Time") ax.set_ylabel("Stock Price") ax.set_zlabel("Default Cost after Hedging ($H^{c}_t$)")
def test_call(self): """Test that the binomial model correctly prices a call option.""" def price(r): d1 = (np.log(100. / K) + r + 0.0005) / 0.1 d2 = d1 - 0.1 price = stats.norm.cdf(d1) * 100 price -= stats.norm.cdf(d2) * K * np.exp(-r) return price dS = WienerJumpProcess(0.1, 0.1) dSdq = WienerJumpProcess(0.1, 0.1, 0.1) accuracy = 10 step_down = set((59, 61, 64, 68, 72, 78, 83, 89, 100, 119)) step_up = set((136, 158, 172, 183, 193)) for K in range(1, 200): if K in step_down: accuracy -= 1 elif K in step_up: accuracy += 1 V = CallE(1, K) model = BinomialModel(128, dS, V) self.assertAlmostEqual(float(model.price(100)), price(0.1), accuracy) model = BinomialModel(128, dSdq, V) self.assertAlmostEqual(float(model.price(100)), price(0.2), accuracy)
def test_value(self): """Test the value object for the binomial model.""" dS = WienerJumpProcess(0.1, 0.1, 0.02, 0) N = 16 T = 1 ct = np.linspace(0, T, N // 2 + 1) c = 1 S = 100 model = BinomialModel(N, dS, Stack([CallA(T, S), Annuity(T, ct, c)])) P = model.price(S) # Test N self.assertEqual(P.N, N) # Test time series self.assertEqual(P.t[0], 0) self.assertEqual(P.t[-1], T) self.assertEqual(len(P.t), N + 1) # Test Coupon sequence self.assertTrue((P.C[::2] == c).all()) self.assertTrue((P.C[1::2] == 0).all()) # Test price sequence self.assertEqual(P.S[0][0], S) self.assertEqual(len(P.S), N + 1) for i in range(1, N + 1): self.assertGreaterEqual(P.S[i][0], P.S[i - 1][0]) self.assertLessEqual(P.S[i][-1], P.S[i - 1][-1]) self.assertTrue((P.S[i][:-1] > P.S[i][1:]).all()) # Test default sequence self.assertEqual(len(P.V), N + 1) for i in range(1, N + 1): self.assertGreaterEqual(P.V[i][0] - P.C[i], P.V[i - 1][0]) self.assertLessEqual(P.V[i][-1] - P.C[i], P.V[i - 1][-1]) self.assertTrue((P.V[i][:-1] >= P.V[i][1:]).all()) self.assertEqual(len(P.X), N) for i in range(1, N): self.assertGreaterEqual(P.X[i][0], P.X[i - 1][0]) self.assertLessEqual(P.X[i][-1], P.X[i - 1][-1]) self.assertTrue((P.X[i][:-1] >= P.X[i][1:]).all())
def test_forward(self): """Test that the binomial model correctly prices a forward contract.""" dS = WienerJumpProcess(0.1, 0.1) dSdq = WienerJumpProcess(0.1, 0.1, 0.02) for K in range(200): V = Forward(1, K) model = BinomialModel(2, dS, V) self.assertAlmostEqual(float(model.price(100)), 100 - K * np.exp(-0.1)) model = BinomialModel(2, dSdq, V) self.assertAlmostEqual(float(model.price(100)), 100 - K * np.exp(-0.12))
def main(): S0 = 100 Sl = 0 Su = 200 X = range(11) N = lambda x: 2**(x + 1) * T K = lambda x: 2**((x + 1) // 2) * (Su - Sl) fig = plt.figure() fig.set_figwidth(1.8 * fig.get_figwidth()) plt_x = fig.add_subplot(1, 2, 1) plt_t = fig.add_subplot(1, 2, 2) p = [] t = [] for x in X: start = time.time() p.append(float(BinomialModel(N(x), dS, payoff).price(S0))) t.append(time.time() - start) plt_x.plot(X, p) plt_t.plot(t, p) print p[-1] for scheme in (ImplicitScheme, CrankNicolsonScheme, PenaltyScheme): p = [] t = [] for x in X: k = K(x) Sk = k * (S0 - Sl) / (Su - Sl) start = time.time() p.append(FDEModel(N(x), dS, payoff).price(Sl, Su, k, scheme=scheme).V[0][Sk]) t.append(time.time() - start) plt_x.plot(X, p[:len(X)]) plt_t.plot(t, p) print p[-1] label(plt_x, "$\\delta_t = 2^{-(x + 1)}$; $\\delta_S = 2^{-\\frac{x + 1}{2}}$") label(plt_t, "Computational Time (seconds)") #plt_t.set_xlim(0, 2.5) plt_t.set_xscale('log')
def test_annuity(self): """Test the pricing of a series of payments.""" def price(r): erdt = np.exp(-r) i = 1 / erdt - 1 return (1 - erdt**(T * 2)) / i + 10 * erdt**(T * 2) dS = WienerJumpProcess(0.1, 0.1) dSdq = WienerJumpProcess(0.1, 0.1, 0.02) # Semi-annual payments of 1 T = 10 V = Annuity(T, np.arange(0.5, T + 0.5, 0.5), 1, 10) model = BinomialModel(T * 2, dS, V) self.assertAlmostEqual(float(model.price(100)), price(0.05)) model = BinomialModel(T * 2, dSdq, V) self.assertAlmostEqual(float(model.price(100)), price(0.06))