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