Skip to content

Jump Processes (qfn)

Background

Jump Processes

Exploration of jump processes in continuous-time finance, covering Poisson processes, compound Poisson processes, and the Merton jump-diffusion model. Includes both Euler-Maruyama and analytical (vectorized) simulation methods for the Merton jump-diffusion process.

Theory is based on Chapter 11 of Stochastic Calculus for Finance II Continuous-Time Models (Shreve, 2008).

Source: From the "quantitative-finance-notebooks" collection.


Code

```python """ Jump Processes ==============

Exploration of jump processes in continuous-time finance, covering Poisson processes, compound Poisson processes, and the Merton jump-diffusion model. Includes both Euler-Maruyama and analytical (vectorized) simulation methods for the Merton jump-diffusion process.

Theory is based on Chapter 11 of Stochastic Calculus for Finance II Continuous-Time Models (Shreve, 2008).

Source: From the "quantitative-finance-notebooks" collection. """

import numpy as np import matplotlib.pyplot as plt import scipy.stats as ss

=============================================================================

1. Poisson Process

=============================================================================

In the way that Brownian motion is the basic building block for

continuous-path processes, the Poisson process serves as the starting point

for jump processes.

To construct a Poisson process, we begin with a sequence tau_1, tau_2, ...

of independent exponential random variables, all with the same mean 1/lambda.

An event ("jump") occurs from time to time:

- The first jump occurs at time tau_1.

- The second occurs tau_2 time units after the first.

- The third occurs tau_3 time units after the second, etc.

The tau_k are called the interarrival times. The arrival times are:

S_n = sum_{k=1}^{n} tau_k

The Poisson process N(t) counts the number of jumps at or before time t:

N(t) = 0 if 0 <= t < S_1,

1 if S_1 <= t < S_2,

...

n if S_n <= t < S_{n+1},

...

At the jump times N(t) is right-continuous: N(t) = lim_{s -> t+} N(s).

Because the expected time between jumps is 1/lambda, jumps arrive at an

average rate of lambda per unit time. We say N(t) has intensity lambda.

=============================================================================

Compound Poisson Process

=============================================================================

When a Poisson process jumps, it always jumps up one unit. For financial

models, we need random jump sizes.

Let N(t) be a Poisson process with intensity lambda, and let Y_1, Y_2, ...

be i.i.d. random variables with mean beta = E[Y_i], independent of N(t).

The compound Poisson process is:

Q(t) = sum_{i=1}^{N(t)} Y_i, t >= 0.

Jumps in Q(t) occur at the same times as in N(t), but with random sizes

Y_1, Y_2, .... The increments of Q(t) are independent:

Q(s) = sum_{i=1}^{N(s)} Y_i

Q(t)-Q(s) = sum_{i=N(s)+1}^{N(t)} Y_i (independent of Q(s))

Q(t)-Q(s) has the same distribution as Q(t-s).

The mean of the compound Poisson process is:

E[Q(t)] = beta * lambda * t

On average there are lambda*t jumps in [0,t], the average jump size is beta,

and the number of jumps is independent of the jump sizes.

=============================================================================

2. Jump Processes and Their Integrals

=============================================================================

We define the stochastic integral int_0^t Phi(s) dX(s) where X can have

jumps. The integrators are right-continuous and of the form:

X(t) = X(0) + I(t) + R(t) + J(t), (2.1)

where:

- X(0) is a nonrandom initial condition.

- I(t) = int_0^t Gamma(s) dW(s) is the Ito integral part.

- R(t) = int_0^t Theta(s) ds is the Riemann integral part.

- J(t) is an adapted, right-continuous pure jump process with J(0)=0.

The continuous part of X(t) is:

X^c(t) = X(0) + I(t) + R(t)

= X(0) + int_0^t Gamma(s) dW(s) + int_0^t Theta(s) ds

with quadratic variation:

X^c, X^c = int_0^t Gamma^2(s) ds

or in differential form: dX^c(t) dX^c(t) = Gamma^2(t) dt.

J(t) is a pure jump process: it has only finitely many jumps on each

finite interval (0,T] and is constant between jumps. A Poisson process and

a compound Poisson process have this property. A compensated Poisson process

does not because it decreases between jumps.

The Ito-Doeblin formula for jump processes is not covered here but can be

found on pages 483-492 (Shreve, 2008).

=============================================================================

3. Merton Jump-Diffusion Process

=============================================================================

The Merton jump-diffusion process is described by the SDE:

dX_t = mu * S_t dt + sigma * S_t dW + S_t dJ_t,

where J = {J_t, t in [0,T]} is an adapted compound Poisson process:

J_t = sum_{i=1}^{N_t} Y_i,

N = {N_t, t in [0,T]} is a standard Poisson process with intensity lambda,

and Y_i ~ N(alpha, xi^2) are the jump sizes with mean alpha and variance xi^2.

Define parameters

if name == "main": T = 1.0 # time horizon N = 252 # number of steps within time horizon time = np.linspace(0, T, N + 1) # from 0 to T with N+1 points (inclusive of T) dt = T / N # time step increment M = 1000 # number of simulations mu = 0.1 # drift coefficient per unit T sigma = 0.3 # volatility per unit T lambda_jump = 0.18 # mean number of jumps per unit T mu_jump = 0.2 # mean jump size per unit T sigma_jump = 0.5 # jump size volatility per unit T S0 = 100.0 # initial asset price

# -----------------------------------------------------------------------------
# 3.1 Euler-Maruyama Method
# -----------------------------------------------------------------------------
# Simulates the Merton jump-diffusion process step-by-step.

# Initialize an array to store the simulated paths
S = np.zeros((N + 1, M))
S[0, :] = S0

# Simulate the GBM and jump process
Z = ss.norm.rvs(loc=0, scale=1, size=(N, M), random_state=42)
J_size = ss.norm.rvs(loc=mu_jump, scale=sigma_jump, size=(N, M), random_state=43)
J_occur = ss.poisson.rvs(mu=lambda_jump * dt, size=(N, M), random_state=44)

# Simulate the paths
for t in range(1, N + 1):
    S[t, :] = S[t-1, :] * np.exp(
        (mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * Z[t-1, :] + J_size[t-1, :] * J_occur[t-1, :]
    )

# Plot the simulated price paths
plt.figure(figsize=(6, 4))
plt.plot(time, S)
plt.title('Merton Jump-Diffusion Simulated Price Paths')
plt.xlabel('Time')
plt.ylabel('Price')
plt.grid(True)
plt.show()


# -----------------------------------------------------------------------------
# 3.2 Analytical Method
# -----------------------------------------------------------------------------
# Utilizes vectorized operations to compute cumulative sums of log return
# and jump increments.

# Initialize an array to store the simulated paths
S = np.zeros((N + 1, M))
S[0, :] = S0

# Simulate the Merton Jump Diffusion process
Z = ss.norm.rvs(loc=(mu - 0.5 * sigma**2) * dt, scale=sigma * np.sqrt(dt), size=(N, M), random_state=42)
J_size = ss.norm.rvs(loc=mu_jump, scale=sigma_jump, size=(N, M), random_state=43)
J_occur = ss.poisson.rvs(mu=lambda_jump * dt, size=(N, M), random_state=44)

# Calculate the asset price paths
S[1:, :] = S0 * np.exp(np.cumsum(Z, axis=0) + np.cumsum(J_size * J_occur, axis=0))

# Plot the simulated price paths
plt.figure(figsize=(6, 4))
plt.plot(time, S)
plt.title('Merton Jump-Diffusion Simulated Price Paths')
plt.xlabel('Time')
plt.ylabel('Price')
plt.grid(True)
plt.show()

```

Exercises

Exercise 1. Distinguish between a Poisson process, compound Poisson process, and Merton jump-diffusion.

Solution to Exercise 1

Poisson: counting process \(N(t)\) with intensity \(\lambda\). Compound Poisson: \(X_t = \sum_{i=1}^{N(t)} J_i\) with i.i.d. jump sizes. Merton: adds Gaussian diffusion to compound Poisson: \(dS/S = (r-\lambda\bar{k})dt + \sigma dW + (e^J-1)dN\).


Exercise 2. Compare Euler-Maruyama and analytical simulation for the Merton model.

Solution to Exercise 2

Euler: \(S_{t+\Delta t} = S_t + \ldots\) has \(O(\Delta t)\) bias. Analytical: \(S_T = S_0\exp(\ldots)\) is exact. Analytical is more accurate and faster (one step for terminal values). Euler is needed only for intermediate path values.


Exercise 3. Explain the difference between finite-activity and infinite-activity Levy processes.

Solution to Exercise 3

Finite activity (compound Poisson): finitely many jumps per unit time, \(\int \nu(dx) < \infty\). Infinite activity (VG, NIG): infinitely many small jumps, \(\int \nu(dx) = \infty\). Infinite activity better captures high-frequency microstructure.


Exercise 4. Why do jump processes make markets incomplete?

Solution to Exercise 4

With jumps, there are two risk sources (\(W_t\) and \(N_t\)) but only one risky asset. The jump risk cannot be hedged, making some claims non-replicable. Multiple equivalent martingale measures exist, and option prices are not unique without additional assumptions.