I am trying to simulate Geometric Brownian Motion in Python, however the results that I get seem very strange and in my opinion they can't be correct. My goal is to simulate each day of 1 year. Basically, I used two slightly different approaches. Based on my research, it should be either possible to use daily drift and volatility with
dt = 1 or annualize drift and volatility and use
dt = 1/365. I computed the daily drift and volatility based on daily historical data for the first approach and annualized them for the second. Accordingly also
T is changed. Below is the code in Python which I partially got from this answer (Geometric Brownian Motion simulation in Python):
import numpy as np import matplotlib.pyplot as plt np.random.seed(1000) quandl.ApiConfig.api_key = "XXXXXX" def gen_paths(S0, r, sigma, T, M, I): dt = float(T) / M paths = np.zeros((M + 1, I), np.float64) paths = S0 for t in range(1, M + 1): rand = np.random.standard_normal(I) paths[t] = paths[t - 1] * np.exp((r - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * rand) return paths # Get data df = quandl.get(...) value = df['Value'] # Compute returns returns = value.pct_change(1) # Daily drift and volatility S0 = value[-1] # initial stock price r = np.mean(returns) # drift sigma = np.std(returns) # volatility T = 365 # time M = 365 # number of steps I = 100000 # number of simulations paths_1 = gen_paths(S0, r, sigma, T, M, I) print("Average: " + str(np.average(paths_1[-1]))) # Yearly drift and volatility r = np.mean(returns) * 365 sigma = np.std(returns) * np.sqrt(365) T = 1.0 paths_2 = gen_paths(S0, r, sigma, T, M, I) print("Average: " + str(np.average(paths_2[-1]))) # Visualize 5 simulated paths for each fig, axs = plt.subplots(2) axs.plot(paths_1[:, :5]) axs.plot(paths_2[:, :5]) plt.show()
Here is the result that I get:
For the averages I get
117183 for the approach with daily drift and volatility and
76145 for the approach with yearly drift and volatility. Here are my questions:
- Can these results be correct or what is wrong with my code?
- Shouldnt the averages be very similar for both approaches?
- Which approach is favorable to use?