def Simulating_Stochastic_Volatility():
    print("Enter inital stock price (S0)")
    S = float(input())
    print("Enter initial volatility (sigma)")
    sigma = float(input())
    print("Enter risk-free rate (r)")
    r = float(input())
    print("Enter dividend yield (q)")
    q = float(input())
    print("Enter length of each time period (Delta t)")
    dt = float(input())
    print("Enter number of time periods (N)")
    n = int(input())
    print("Enter theta")
    theta = float(input())
    print("Enter kappa")
    kappa = float(input())
    print("Enter Gamma")
    gamma = float(input())
    print("Enter Rho")
    rho = float(input())

    logS = math.log(S)
    var = sigma * sigma
    sqrdt = math.sqrt(dt)
    sqrrho = math.sqrt(1 - rho * rho)

    GARCH = np.zeros((n, 3))
    GARCH[0, 1] = S
    GARCH[0, 2] = sigma

    for i in range(1, n):
        GARCH[i, 0] = i * dt
        z1 = RandN()
        logS = logS + (r - q - 0.5 * sigma * sigma) * dt + sigma * sqrdt * z1
        S = math.exp(logS)
        GARCH[i, 1] = S
        z2 = RandN()
        zStar = rho * z1 + sqrrho * z2
        var = max(0, var + kappa * (theta - var) * dt + gamma * sigma * sqrdt * zStar)
        sigma = math.sqrt(var)
        GARCH[i, 2] = sigma

    plt.subplot(1, 2, 1)
    plt.plot(GARCH[0:, 0], GARCH[0:, 1])
    plt.grid(True)
    plt.title('Stock Price Price')
    plt.xlabel('Time')

    plt.subplot(1, 2, 2)
    plt.plot(GARCH[0:, 0], GARCH[0:, 2])
    plt.grid(True)
    plt.title('Volatility')
    plt.xlabel('Time')

    plt.show()
def Simulating_Geometric_Brownian_Motion():
    print("Enter the length of the time period (T)")
    T = float(input())
    print("Enter the number of periods (N)")
    N = int(input())
    print("Enter the initial stock price (S)")
    S = float(input())
    print("Enter the expected rate of return (mu)")
    mu = float(input())
    print("Enter the volatility (sigma)")
    sigma = float(input())

    dt = T / N
    sigSqrdt = sigma * math.sqrt(dt)
    drift = (mu - 0.5 * sigma * sigma) * dt
    GBM = np.zeros((N, 2))
    GBM[0, 1] = S

    for i in range(1, N):
        GBM[i, 0] = i * dt
        GBM[i, 1] = math.exp(
            math.log(GBM[i - 1, 1]) + drift + sigSqrdt * RandN())

    plt.plot(GBM[0:, 0], GBM[0:, 1])
    plt.grid(True)
    plt.title('Strock Price')
    plt.ylabel('S(T)')
    plt.xlabel('Time')
    plt.show()
    return GBM
Пример #3
0
def European_Call_MC(S, K, r, sigma, q, T, M):
    # inputs
    """S = initial stock price
       K = strike price
       r = risk-free rate
       sigma = volatility
       q = dividend yield
       T = time to maturity
       M = number of simulations"""
    logS0 = math.log(S)
    drift = (r - q - 0.5 * sigma * sigma) * T
    sigSqrt = sigma * math.sqrt(T)
    UpChange = math.log(1.01)
    DownChange = math.log(0.99)
    SumCall = 0
    SumCallChange = 0
    SumPathwise = 0
    for i in range(1, M):
        logS = logS0 + drift + sigSqrt * RandN()
        callV = max(0, math.exp(logS) - K)
        SumCall = SumCall + callV
        logSu = logS + UpChange
        CallVu = max(0, math.exp(logSu) - K)
        logSd = logS + DownChange
        CallVd = max(0, math.exp(logSd) - K)
        SumCallChange = SumCallChange + CallVu - CallVd
        if math.exp(logS) > K:
            SumPathwise = SumPathwise + math.exp(logS) / S
    CallV = math.exp(-r * T) * SumCall / M
    Delta1 = math.exp(-r * T) * SumCallChange / (M * 0.02 * S)
    Delta2 = math.exp(-r * T) * SumPathwise / M
    results = [CallV, Delta1, Delta2]
    print(results)
    return results
def Simulated_Delta_Hedge_Profit(S0, K, r, sigma, q, T, mu, M, N, pct):
    # inputs
    """ S0 = initial stock price
        K = strike price
        r = risk-free rate
        sigma = volatility
        q = dividend yield
        T = time to maturity
        mu = expected rate of return
        N = number of time periods
        M = number of simulations
        pct = percentile to be returned"""
    dt = T / N
    sigSqrdt = sigma * math.sqrt(dt)
    drift = (mu - q - 0.5 * sigma * sigma) * dt
    comp = math.exp(r * dt)
    div = math.exp(q * dt) - 1
    logS0 = math.log(S0)
    call0 = Black_Scholes_Call(S0, K, r, sigma, q, T)
    delta0 = Black_Scholes_Call_Delta(S0, K, r, sigma, q, T)
    cash0 = call0 - delta0 * S0  # initial cash position
    profit = np.zeros(M)
    for i in range(0, M):
        logS = logS0
        cash = cash0
        S = S0
        delta = delta0
        for j in range(1, N - 1):
            logS = logS + drift + sigSqrdt * RandN()
            newS = math.exp(logS)
            newDelta = Black_Scholes_Call_Delta(newS, K, r, sigma, q,
                                                T - j * dt)
            cash = comp * cash + delta * S * div - (newDelta - delta) * newS
            S = newS
            delta = newDelta
        logS = logS + drift + sigSqrdt * RandN()
        newS = math.exp(logS)
        hedgeValue = comp * cash + delta * S * div + delta * newS
        profit[i] = hedgeValue - max(newS - K, 0)

    for i in profit:
        print(i)

    return np.percentile(profit, pct)
def Simulating_GARCH():
    print("Enter inital stock price (S0)")
    S = float(input())
    print("Enter initial volatility (sigma)")
    sigma = float(input())
    print("Enter risk-free rate (r)")
    r = float(input())
    print("Enter dividend yield (q)")
    q = float(input())
    print("Enter length of each time period (Delta t)")
    dt = float(input())
    print("Enter number of time periods (N)")
    n = int(input())
    print("Enter theta")
    theta = float(input())
    print("Enter kappa")
    kappa = float(input())
    print("Enter lambda")
    lambda1 = float(input())

    logS = math.log(S)
    sqrdt = math.sqrt(dt)
    a = kappa * theta
    b = (1 - kappa) * (1 - lambda1)
    c = (1 - kappa) * lambda1
    GARCH = np.zeros((n, 3))
    GARCH[0, 1] = S
    GARCH[0, 2] = sigma

    for i in range(1, n):
        GARCH[i, 0] = i * dt
        y = sigma * RandN()
        logS = logS + (r - q - 0.5 * sigma * sigma) * dt + sqrdt * y
        S = math.exp(logS)
        GARCH[i, 1] = S
        sigma = math.sqrt(a + b * y * y + c * sigma * sigma)
        GARCH[i, 2] = sigma

    plt.subplot(1, 2, 1)
    plt.plot(GARCH[0:, 0], GARCH[0:, 1])
    plt.grid(True)
    plt.title('Stock Price Price')
    plt.xlabel('Time')

    plt.subplot(1, 2, 2)
    plt.plot(GARCH[0:, 0], GARCH[0:, 2])
    plt.grid(True)
    plt.title('Volatility')
    plt.xlabel('Time')

    plt.show()
def Simulating_Brownian_Motion():
    print("Enter the length of the time period (T)")
    T = float(input())
    print("Enter the number of periods (N)")
    N = int(input())

    dt = T / N
    sqrdt = math.sqrt(dt)
    BM = np.zeros((N, 2))

    for i in range(1, N):  # Simulating Brownian Motion
        BM[i, 0] = i * dt
        BM[i, 1] = BM[i - 1, 1] + sqrdt * RandN()

    plt.plot(BM[0:, 0], BM[0:, 1])
    plt.grid(True)
    plt.title('Brownian Motion')
    plt.ylabel('B(T)')
    plt.xlabel('Time')
    plt.show()
    return BM
Пример #7
0
def Eur_Call_GARCH_MC(S, K, r, sigma0, q, T, N, kappa, theta, lambda1, M):
    # inputs
    """S = initial stock price
       K = strike price
       r = risk-free rate
       sigma0 = initial volatility
       q = dividend yield
       T = time to maturity
       N = number of time periods
       kappa = GARCH parameter
       theta = GARCH parameter
       lambda = GARCH parameter
       M = number of simulations"""
    dt = T / N
    sqrdt = math.sqrt(dt)
    a = kappa * theta
    b = (1 - kappa) * (1 - lambda1)
    c = (1 - kappa) * (1 - lambda1)
    logS0 = math.log(S)
    SumCall = 0
    SumCallSq = 0
    for i in range(1, M):
        logS = logS0
        sigma = sigma0
        for j in range(1, N):
            y = sigma * RandN()
            logS = logS + (r - q - 0.5 * sigma * sigma) * dt + sqrdt * y
            sigma = math.sqrt(a + b * y * y + c * sigma * sigma)
        CallV = max(0, math.exp(logS) - K)
        SumCall = SumCall + CallV
        SumCallSq = SumCallSq + CallV * CallV
    CallV = math.exp(-r * T) * SumCall / M
    StdError = math.exp(-r * T) * math.sqrt(
        (SumCallSq - SumCall * SumCall / M) / (M * (M - 1)))
    results = [CallV, StdError]
    print(results)
    return results