Ejemplo n.º 1
0
def main():
    S = np.linspace(0, 200, 200 * 8 + 1)
    Sl = 0
    Su = 250
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)
    legend = []
    label = "$\\Omega^v = [%i, 5]$"

    model = FDEModel(N, dS, payoff)
    fig = plt.figure()
    fig.set_figwidth(1.8 * fig.get_figwidth())

    ax = fig.add_subplot(1, 2, 1)
    for i in range(1, 5):
        Conv.times = [(i, 5)]
        ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
        legend.append(label % i)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(legend)

    ax = fig.add_subplot(1, 2, 2, projection="3d")
    plot_model(ax, dS, payoff)
Ejemplo n.º 2
0
 def test_table20_5(self):
     """Test Example 20.1 using explicit finite difference method."""
     model = FDEModel(10, self.dS, self.V)
     P = model.price(0, 100, 20, scheme=ExplicitScheme, boundary="ignore")
     for i in reversed(range(len(P.V))):
         self.assertTrue(
             (np.abs(self.table20_5[::-1, i] - P.V[i]) < 0.01).all())
Ejemplo n.º 3
0
def main():
    S = np.linspace(0, 200, 200 * 8 + 1)
    Sl = 0
    Su = 250
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)
    legend = []
    label = "$\\Omega^v = [%i, 5]$"

    model = FDEModel(N, dS, payoff)
    fig = plt.figure()
    fig.set_figwidth(1.8 * fig.get_figwidth())

    ax = fig.add_subplot(1, 2, 1)
    for i in range(1, 5):
        Conv.times = [(i, 5)]
        ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
        legend.append(label % i)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(legend)

    ax = fig.add_subplot(1, 2, 2, projection="3d")
    plot_model(ax, dS, payoff)
Ejemplo n.º 4
0
def plot_model(ax, dS, payoff):
    N = 40
    model = FDEModel(N, dS, payoff)
    P = model.price(0, 250, 125, scheme=CrankNicolsonScheme)
    colours = choices(P)
    plot_strips(ax, P.t, P.S[:100], np.array(P.V)[:, :100].T, facecolors=colours[:100])
    ax.set_xlabel("Time")
    ax.set_ylabel("Stock Price")
    ax.set_zlabel("Portfolio Value")
    legend(ax)
Ejemplo n.º 5
0
def main():
    S = np.arange(24, 121)
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = K * (S - Sl) / (Su - Sl)
    dS1 = copy.copy(dS)
    dS1.lambd_ = lambda S: 0.02 * (S / 100)**-1.2
    dS1.cap_lambda = True
    dS2 = copy.copy(dS)
    dS2.lambd_ = lambda S: 0.02 * (S / 100)**-2.0
    dS2.cap_lambda = True
    model1 = FDEModel(N, dS, payoff)
    model2 = FDEModel(N, dS1, payoff)
    model3 = FDEModel(N, dS2, payoff)
    plt.plot(S, model1.price(Sl, Su, K).V[0][Sk])
    plt.plot(S, model2.price(Sl + 1, Su, K - 8).V[0][Sk - 8])
    plt.plot(S, model3.price(Sl + 1, Su, K - 8).V[0][Sk - 8])
    plt.xlim(S[0], S[-1])
    plt.ylim(50, 150)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(
        ["Constant hazard rate", "$\\alpha = -1.2$", "$\\alpha = -2.0$"],
        loc=2)
Ejemplo n.º 6
0
def main():
    N = 128 * T
    S = np.arange(24, 121)
    model1 = FDEModel(N, dS, payoff)
    model2 = FDEModel(N, dS_var12, payoff)
    model3 = FDEModel(N, dS_var20, payoff)
    plt.plot(S, delta(S, model3))
    plt.plot(S, delta(S, model2))
    plt.plot(S, delta(S, model1))
    plt.xlim(S[0], S[-1])
    plt.ylim(-1, 1)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["$\\alpha = -2.0$", "$\\alpha = -1.2$", "Constant hazard rate"], loc=4)
Ejemplo n.º 7
0
def plot_model(ax, dS, payoff):
    N = 40
    model = FDEModel(N, dS, payoff)
    P = model.price(0, 250, 125, scheme=CrankNicolsonScheme)
    colours = choices(P)
    plot_strips(ax,
                P.t,
                P.S[:100],
                np.array(P.V)[:, :100].T,
                facecolors=colours[:100])
    ax.set_xlabel("Time")
    ax.set_ylabel("Stock Price")
    ax.set_zlabel("Portfolio Value")
    legend(ax)
Ejemplo n.º 8
0
def main():
    S = np.linspace(0, 120, 120 * 8 + 1)
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)
    model1 = FDEModel(N, dS, payoff)
    model2 = FDEModel(N, dS_var, payoff)
    plt.plot(S, model1.price(Sl, Su, K).V[0][Sk])
    plt.plot(S, np.append(A.R * A.N, model2.price(Sl + 1, Su, K - 8).V[0][Sk[:-1]]))
    plt.ylim([40, 160])
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["Constant $\\lambda$", "Synthesis $\\lambda$"], loc=2)
Ejemplo n.º 9
0
def main():
    S = np.arange(80, 121)
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = K * (S - Sl) / (Su - Sl)
    model1 = FDEModel(N, dS, payoff)
    model2 = FDEModel(N, dS_partial, payoff)
    model3 = FDEModel(N, dS_total, payoff)
    plt.plot(S, model1.price(Sl, Su, K).V[0][Sk])
    plt.plot(S, model2.price(Sl, Su, K).V[0][Sk])
    plt.plot(S, model3.price(Sl, Su, K).V[0][Sk])
    plt.ylim(100, 150)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["No default", "Partial default", "Total Default"], loc=2)
Ejemplo n.º 10
0
def main():
    S = np.linspace(0, 100, 100 * 8 + 1)
    Sl = 0
    Su = 150
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)
    legend = []
    label = "$\\Omega^p = \\{%i\\}$"

    model = FDEModel(N, dS, payoff)
    fig = plt.figure()

    ax = fig.add_subplot(111)
    for i in range(1, 5):
        P.times = [i]
        ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
        legend.append(label % i)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(legend)
Ejemplo n.º 11
0
def main():
    S = np.linspace(0, 200, 200 * 8 + 1)
    Sl = 0
    Su = 250
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)
    legend = []
    label = "$\\Omega^c = \\{%i\\}$"

    model = FDEModel(N, dS, payoff)
    fig = plt.figure()

    ax = fig.add_subplot(111)
    for i in range(1, 5):
        C.times = [i]
        ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
        legend.append(label % i)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(legend)
Ejemplo n.º 12
0
    def test_call(self):
        """Test that the finite difference model correctly prices a call option."""
        K = 100
        def price(r, S):
            d1 = (np.log(S / K) + r + 0.0005) / 0.1
            d2 = d1 - 0.1
            price = stats.norm.cdf(d1) * S
            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)

        S = np.linspace(0, 200, 41)
        V = CallE(1, K)
        model = FDEModel(64, dS, V)
        model2 = FDEModel(64, dSdq, V)
        accuracy = np.array((15, 15, 15, 14, 12, 11, 9, 8, 6, 5, 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2))
        accuracy2 = np.array((15, 15, 11, 10, 9, 8, 7, 5, 4, 3, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1))
        for scheme in SCHEMES:
            P = model.price(0, 200, 40, scheme=scheme)
            self.assertTrue((abs(P.V[0] - price(0.1, S)) < 10.0**-accuracy).all())
            P = model2.price(0, 200, 40, scheme=scheme)
            self.assertTrue((abs(P.V[0] - price(0.2, S)) < 10.0**-accuracy2).all())
        return
Ejemplo n.º 13
0
def main():
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    S = 100
    Sk = K * (S - Sl) / (Su - Sl)
    ETA = np.linspace(0, 1, 65)
    name = ["No default"]
    fde = FDEModel(N, dS, payoff)
    plt.plot(ETA, [fde.price(Sl, Su, K).V[0][Sk]] * len(ETA))
    for lambd_ in (0.01, 0.02, 0.03):
        dS.lambd_ = lambd_
        V = []
        for eta in ETA:
            dS.eta = eta
            V.append(fde.price(Sl, Su, K).V[0][Sk])
        plt.plot(ETA, V)
        name.append("$\\lambda = %i\\%%$" % (lambd_ * 100))
    plt.xlabel("$\\eta$")
    plt.ylabel("Price at $S=100$")
    plt.legend(name, loc=3)
Ejemplo n.º 14
0
 def test_value(self):
     """Test the value object for the finite difference model."""
     dS = WienerJumpProcess(0.1, 0.1, 0.02, 0)
     N = 16
     T = 1
     ct = np.linspace(0, T, N // 2 + 1)
     c = 1
     Sl = 0
     Su = 200
     K = 40
     model = FDEModel(N, dS, Stack([CallA(T, 100), Annuity(T, ct, c)]))
     P = model.price(Sl, Su, K)
     S = P.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 K
     self.assertEqual(P.K, K)
     # Test Stock series
     self.assertEqual(P.S[0], Sl)
     self.assertEqual(P.S[-1], Su)
     self.assertEqual(len(P.S), K + 1)
     # Test default sequence
     self.assertEqual(len(P.V), N + 1)
     for i in range(1, N + 1):
         self.assertLessEqual(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] - 1e14 <= 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())
Ejemplo n.º 15
0
def main():
    S = np.linspace(0, 200, 200 * 8 + 1)
    Sl = 0
    Su = 250
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)

    model = FDEModel(N, dS, payoff)
    fig = plt.figure()
    fig.set_figwidth(1.8 * fig.get_figwidth())

    ax = fig.add_subplot(1, 2, 1)
    ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
    C.times = [2]
    ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["$\\Omega^c = [2, 5)$", "$\\Omega^c = \\{2\\}$"])

    ax = fig.add_subplot(1, 2, 2, projection="3d")
    plot_model(ax, dS, payoff)
Ejemplo n.º 16
0
def main():
    S = np.linspace(0, 200, 200 * 8 + 1)
    Sl = 0
    Su = 250
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)

    model = FDEModel(N, dS, payoff)
    fig = plt.figure()
    fig.set_figwidth(1.8 * fig.get_figwidth())

    ax = fig.add_subplot(1, 2, 1)
    ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
    A.N = -A.C
    ax.plot(S, model.price(Sl, Su, K).V[0][Sk])
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["$R = 104$", "$R = 0$"])

    ax = fig.add_subplot(1, 2, 2, projection="3d")
    plot_model(ax, dS, payoff)
Ejemplo n.º 17
0
def main():
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    S = 100
    Sk = K * (S - Sl) / (Su - Sl)
    ETA = np.linspace(0, 1, 65)
    name = ["No default"]
    fde = FDEModel(N, dS, payoff)
    plt.plot(ETA, [fde.price(Sl, Su, K).V[0][Sk]] * len(ETA))
    for lambd_ in (0.01, 0.02, 0.03):
        dS.lambd_ = lambd_
        V = []
        for eta in ETA:
            dS.eta = eta
            V.append(fde.price(Sl, Su, K).V[0][Sk])
        plt.plot(ETA, V)
        name.append("$\\lambda = %i\\%%$" % (lambd_ * 100))
    plt.xlabel("$\\eta$")
    plt.ylabel("Price at $S=100$")
    plt.legend(name, loc=3)
Ejemplo n.º 18
0
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')
Ejemplo n.º 19
0
def main():
    S = np.linspace(0, 120, 120 * 8 + 1)
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = (K * (S - Sl) / (Su - Sl)).astype(int)
    model1 = FDEModel(N, dS, payoff)
    model2 = FDEModel(N, dS_var, payoff)
    plt.plot(S, model1.price(Sl, Su, K).V[0][Sk])
    plt.plot(
        S, np.append(A.R * A.N,
                     model2.price(Sl + 1, Su, K - 8).V[0][Sk[:-1]]))
    plt.ylim([40, 160])
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["Constant $\\lambda$", "Synthesis $\\lambda$"], loc=2)
Ejemplo n.º 20
0
def main():
    S = np.arange(80, 121)
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = K * (S - Sl) / (Su - Sl)
    model1 = FDEModel(N, dS, payoff)
    model2 = FDEModel(N, dS_partial, payoff)
    model3 = FDEModel(N, dS_total, payoff)
    plt.plot(S, model1.price(Sl, Su, K).V[0][Sk])
    plt.plot(S, model2.price(Sl, Su, K).V[0][Sk])
    plt.plot(S, model3.price(Sl, Su, K).V[0][Sk])
    plt.ylim(100, 150)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["No default", "Partial default", "Total Default"], loc=2)
Ejemplo n.º 21
0
    def test_forward(self):
        """Test that the finite difference model correctly prices a forward contract."""
        dS = WienerJumpProcess(0.1, 0.1)
        dSdq = WienerJumpProcess(0.1, 0.1, 0.02)

        S = np.linspace(0, 200, 41)
        V = Forward(1, 100)
        model = FDEModel(64, dS, V)
        model2 = FDEModel(64, dSdq, V)
        for scheme in SCHEMES:
            if isinstance(scheme, CrankNicolsonScheme):
                accuracy = 5
            else:
                accuracy = 2
            P = model.price(0, 200, 40, scheme=scheme)
            self.assertTrue((abs(P.V[0] - (S - 100 * np.exp(-0.1))) < 10.0**-accuracy).all())
            P = model2.price(0, 200, 40, scheme=scheme)
            self.assertTrue((abs(P.V[0] - (S - 100 * np.exp(-0.12))) < 10.0**-accuracy).all())
Ejemplo n.º 22
0
    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 = FDEModel(T * 8, dS, V)
        model2 = FDEModel(T * 8, dSdq, V)
        for scheme in SCHEMES:
            P = model.price(0, 200, 25, scheme=scheme)
            self.assertTrue((np.abs(P.V[0] - price(0.05)) < 1e-1).all())
            P = model2.price(0, 200, 25, scheme=scheme)
            self.assertTrue((np.abs(P.V[0] - price(0.06)) < 1e-1).all())
Ejemplo n.º 23
0
def main():
    S = np.arange(24, 121)
    Sl = 0
    Su = 200
    N = 128 * T
    K = 8 * (Su - Sl)
    Sk = K * (S - Sl) / (Su - Sl)
    dS1 = copy.copy(dS)
    dS1.lambd_ = lambda S: 0.02 * (S / 100)**-1.2
    dS1.cap_lambda = True
    dS2 = copy.copy(dS)
    dS2.lambd_ = lambda S: 0.02 * (S / 100)**-2.0
    dS2.cap_lambda = True
    model1 = FDEModel(N, dS, payoff)
    model2 = FDEModel(N, dS1, payoff)
    model3 = FDEModel(N, dS2, payoff)
    plt.plot(S, model1.price(Sl, Su, K).V[0][Sk])
    plt.plot(S, model2.price(Sl + 1, Su, K - 8).V[0][Sk - 8])
    plt.plot(S, model3.price(Sl + 1, Su, K - 8).V[0][Sk - 8])
    plt.xlim(S[0], S[-1])
    plt.ylim(50, 150)
    plt.xlabel("Stock Price")
    plt.ylabel("Convertible Bond Price")
    plt.legend(["Constant hazard rate", "$\\alpha = -1.2$", "$\\alpha = -2.0$"], loc=2)
Ejemplo n.º 24
0
 def test_table20_5(self):
     """Test Example 20.1 using explicit finite difference method."""
     model = FDEModel(10, self.dS, self.V)
     P = model.price(0, 100, 20, scheme=ExplicitScheme, boundary="ignore")
     for i in reversed(range(len(P.V))):
         self.assertTrue((np.abs(self.table20_5[::-1, i] - P.V[i]) < 0.01).all())