# How to determine the order of convergence of the Euler-Maruyama method?

This question is originally posted in Quant.StackExchange but has been unanswered for some time so I ask in here.

To make this simple let us consider the Geometric Brownian Motions (GBM).

My questions:

• 1. How can I show that the Euler-Maruyama Method is convergent using GBM?
• 2. How can I determine the order of convergence?

Background and the Problems I am facing:

According to Numerical Analysis theory An SDE solver has order $$p$$ if the expected value of the error is of $$p$$th order in the time step size

Now letting $$S_t$$ be a GBM with $$S_0=1,$$ $$\mu=0.1$$ and $$\sigma=0.15$$ then $$E[S_{10}] =e$$

When I run the solver $$10,000$$ times for different sizes $$dt$$, I would expect that the difference between my sample mean and true mean, $$e$$, will decrease as $$dt$$ gets smaller. However, when I run these simulations this is what I get: This does not indicate that the error converges to zero as $$dt$$ goes to zero?

Why is that ..... Is this because of the randomness? I have actually tried for $$1 \,000$$, $$10\,000$$, and $$20\,000$$ simulations. In general, $$10\,000$$ simulations should be enough to remove much of variance.

Please suggest how I can determine/show the order of convergence.

If anyone is interested in the code

import matplotlib.pyplot as plt
import numpy as np

T = 10
mu = 0.1
sigma = 0.15
S0 = 1
ns = 10000

solution = S0*np.exp( mu*T )

dt_ = np.array([0.1,0.05,0.01,0.005])
err = np.zeros( len(dt_ ));
for j in range ( len(dt_ )):
dt = dt_[j]
Sn = np.zeros( (ns) )
for i in range(ns):
N = int(round(T/dt))
t = np.linspace(0, T, N)
ex= np.linspace(0, T, N)
W = np.random.standard_normal(size = N)
W = np.cumsum(W)*np.sqrt(dt) ### standard brownian motion ###
X = (mu-0.5*sigma**2)*t + sigma*W
S = S0*np.exp(X) ### geometric brownian motion ###
Sn[i]= S[-1]

mn          = np.mean(Sn)
print(mn)
err[j]      = abs( mn - solution)

plt.clf();
plt.loglog(dt_,err, color ="black", label = "Error (abs)");plt.xlabel("dt",fontsize = 20); plt.ylabel("Error (abs)",fontsize = 20)
plt.loglog(dt_,err, 'o', color ="black" , label = "x")
plt.title("loglog-plot",fontsize = 30);
plt.loglog(dt_,0.05*dt_**0.5, linestyle = ":")


The code is mostly just copy-pasted from StackOverflow