for the geometric Brownian motion, it is biased for the majority of other stochastic
processes. Even if there is an exact scheme available — one for the square-root diffusion
will be presented shortly — the use of an Euler scheme might be desirable due to
numerical and/or computational reasons. Defining s ≡ t – Δt and x
+
≡ max(x,0),
Equation 10-5 presents such an Euler scheme. This particular one is generally called full
truncation in the literature (cf. Hilpisch (2015)).
Equation 10-5. Euler discretization for square-root diffusion
We parameterize the model for the simulations to follow with values that could represent
those of a short rate model:
In [ 21 ]: x0 = 0.05
kappa = 3.0
theta = 0.02
sigma = 0.1
The square-root diffusion has the convenient and realistic characteristic that the values of
xt remain strictly positive. When discretizing it by an Euler scheme, negative values
cannot be excluded. That is the reason why one works always with the positive version of
the originally simulated process. In the simulation code, one therefore needs two ndarray
objects instead of only one:
In [ 22 ]: I = 10000
M = 50
dt = T / M
def srd_euler():
xh = np.zeros((M + 1 , I))
x1 = np.zeros_like(xh)
xh[ 0 ] = x0
x1[ 0 ] = x0
for t in range( 1 , M + 1 ):
xh[t] = (xh[t - 1 ]
+ kappa * (theta - np.maximum(xh[t - 1 ], 0 )) * dt
+ sigma * np.sqrt(np.maximum(xh[t - 1 ], 0 )) * np.sqrt(dt)
* npr.standard_normal(I))
x1 = np.maximum(xh, 0 )
return x1
x1 = srd_euler()
Figure 10-7 shows the result of the simulation graphically as a histogram:
In [ 23 ]: plt.hist(x1[- 1 ], bins= 50 )
plt.xlabel(‘value’)
plt.ylabel(‘frequency’)
plt.grid(True)