Exact Vasicek Simulation Versus Euler Discretization
Summary
The document compares two ways to simulate short rate paths under the Vasicek model. One uses the model’s exact conditional transition over each time step, while the other applies an Euler approximation to the mean-reverting stochastic differential equation. The questioner reports that the exact-transition paths produce a zero-coupon bond price closer to the analytical Vasicek price, with the discretized paths showing a somewhat larger spread.
The comparison highlights why discretization can introduce approximation error, particularly as the step size changes, whereas exact transitions avoid that specific time-stepping approximation for Vasicek. The post also asks whether CIR paths require discretization, but supplies no answer. It gives no controlled comparison of step sizes, parameter settings, or convergence, so the observed pricing difference is an illustration rather than general empirical evidence.
Key ideas
- The Vasicek process has an exact conditional transition that can generate rates at discrete time points.
- Euler discretization approximates the drift and diffusion over each time step.
- The questioner reports closer analytical bond-price agreement from exact Vasicek simulation in their example.
- The document leaves open whether CIR simulation has an equivalent exact-transition approach.
Tags
Full text
# Vasicek Short rate simulation - analytical formula vs discretization
# Vasicek Short rate simulation - analytical formula vs discretization
I've been using two approaches to simulate Vasicek short rate paths and I'm wondering if one of them is more correct than the other.
The first approach is based on the analytical formula (see code below, "OU_processes"), whereby every next simulated rate along a path is calculated from the previously simulated rate one timestep ago as follows:
```
def OU_processes(years, timestep, num_sims, startRate, kappa, theta, sigma):
"""
timestep has to be defined in years or a fraction of years
e.g. 0.1 => 1/10th of a year; 2 => 2 years
"""
times = np.arange(0,years+timestep,timestep)
epsilon = np.random.normal(0, 1, (num_sims, len(times)-1))
elt = 0.5 / kappa * (1.0 - np.exp (-2.0 * kappa * timestep))
V = elt * sigma ** 2
sqrt_V = np.sqrt(V)
ou = np.zeros((num_sims, len(times)))
ou[:,0] = startRate
ou[:, 1:] = np.kron(sqrt_V, np.ones((num_sims, 1))) * epsilon
for i in range(1, ou.shape[1]):
ou[:, i] += theta * (1 - np.exp(-kappa * timestep))
ou[:, i] += np.exp (-kappa * timestep) * ou[:, i-1]
ou = pd.DataFrame(np.transpose(ou))
ou.index = times
return ou
```
The second approach uses Euler discretization (see code below, "discretized_OU"):
```
def discretized_OU(years, timestep, num_sims, startRate, kappa, theta, sigma):
times = np.arange(0,years+timestep,timestep)
epsilon = np.random.normal(0, 1, (num_sims, len(times)-1))
ou=np.zeros((num_sims,len(times)))
ou[:,0] = startRate
for step in np.arange(1,int(years/timestep)+1,1):
ou[:,step]=ou[:,step-1]+kappa*(theta-ou[:,step-1])*timestep+sigma*np.sqrt(timestep)*epsilon[:,step-1]
ou = pd.DataFrame(np.transpose(ou))
ou.index = times
return ou
```
Could anyone tell me what the difference is between both methods? The paths simulated using the analytical method lead to a ZCB price that is very close to the price found using the analytical Vasicek ZCB formula, while the paths simulated using the discretized approach lead to a price that is somewhat further from the analytical price (although still very close to it) and with a seemingly larger standard deviation:
Moreover, is it correct that only the second approach is available for simulating CIR paths?
Many thanks in advance.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.