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[0] = 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[0].plot(paths_1[:, :5])
axs[1].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?