I want to simulate a path for certain a stochastic process in continuous time using Python. I wrote the following function to simulate it (np
refers to numpy
of course):
def simulate_V(v0, psi, theta, dt, xsi, sample, diff = False):
_, dB = independent_brownian(dt, 1, sample, diff = True)
path_lenght = len(dB) + 1
V = np.zeros(path_lenght)
dV = np.zeros(len(dB))
V[0] = v0
for i in range(len(dV)):
dV[i] = psi * (theta - V[i]) * dt + xsi * np.sqrt(V[i]) * dB[i]
V[i+1] = V[i] + dV[i]
if diff == True:
return(V, dV)
else:
return(V)
The independent_brownian
function just creates a path for a standard Brownian motion. For completeness, here it is:
def independent_brownian(dt, n, sample, diff=False):
'''
Creates paths of independent Brownian motions. Returns increments if diff == True.
--------
dt -> variance of increments\\
n -> how many paths\\
sample -> length of sampled path\\
diff -> return increments or not?\\
Returns a (n, sample)-shaped array with the paths
'''
increments = np.sqrt(dt) * np.random.randn(n, sample)
paths = np.cumsum(increments, axis=1)
b = np.zeros((n, sample + 1))
b[:, 1:] = paths
if n==1:
b = b.flatten()
increments = increments.flatten()
if diff == True:
return(b, increments)
else:
return(b)
It happens that the math behind my model implies that the process $V_t$, which is represented by its discretization V
in the code above, must be positive. However, it might be the case where the array dB
contains negative elements which are big in absolute value. I would like to automate the following "choice" procedure:
- Try to follow the loop described inside
simulate_V
; - At some point, if
V[i]
falls below zero, interrupt the process, sample another sequencedB
and start over; - Stop when all elements of
V
are positive;
What is a good way to automate this procedure? Right now, I understand that, as it is, if V[i]
goes below zero, I will get a nan
in numpy but it will throw no error or stop the process.