1
$\begingroup$

In Python, I import NumPy module to generate Kou's a vector of Asymmetric Double Exponential Random Variables (ADERV). I attempt to apply Glasserman's method for simulating the aforementioned from his 2004 book Monte Carlo Methods in Financial Engineering on page 139, which is the following (with slight difference in notation):

  • generate $N \sim \text{Poisson}(\lambda (t_{i+1}-t_{i}))$ where $\lambda$ is the number of jumps per annum
  • generate $K \sim \text{Binomial(N,p)}$ where $p$ is the probability of upward jumps
  • generate $R_{1} \sim \text{Exponential}(K / \eta_{1})$ and $R_{2} \sim \text{Exponential}((N-K) / \eta_{2})$ where $1/\eta_{1}$ and $1/\eta_{2}$ are the magnitude of up and down jumps, respectively.
  • set $M=R_{1} - R_{2}$ where $M$ is the ADERV

Given $t_{i+1}-t_{i} = 10 / 252$, below is the code to generate ADERVs

import numpy as np import seaborn as sns import import matplotlib.pyplot as plt n = np.random.poisson(lam=20 * (10 / 252), size=100_000) k = np.random.binomial(n=n, p=0.50) r1 = np.random.exponential(scale=k / 25) r2 = np.random.exponential(scale=(n - k) / 25) m = r1 - r2 sns.displot(m, kind='kde') 

enter image description here

Question is is the above code a correct implementation?

-----Further discussion

I discretize $\frac{dS_{t}}{S_{t-}} = \left[r - \left(\frac{p}{\eta_{1}} - \frac{q}{\eta_{2}} \right) \lambda \right]dt + \sigma dW_{t}^{\mathbb{Q}} + d\left(\sum_{j=1}^{N_{t}} V_{j} - 1 \right)$ where $W_{t}^{\mathbb{Q}}$ is a Brownian motion under risk-neutral measure, $N_{t}$ is a Poisson process with intensity rate $\lambda > 0$, and $\{V_{j}\}$ is a series of IID non-negative r.v. s.t. $\Upsilon = \log(V_{j})$ has an asymmetric double exponential distribution to simulate MC paths to price a contingent claim $h(X)$.

As an easier pricing exercise and to sanity check, I define $h(X)$ to be an AtM Vanilla European put with $K=100$ and price it with $r=0$, $\lambda=20$, $p=q=0.5$, $\sigma=0.3$, $\eta_{1}=\eta_{2}=25$, and $T=10/252$. I use MC to simulate 100k paths. Lastly, I do the same thing but define $h(X)$ to be AtM Vanilla European call with same strike as the put. The random number generator is Mersenne Twister with seed number 20240101 in NumPy library.

The put price is 2.9566 and the call is 3.0876. Per put-call parity, I expect equivalent (or very close). However, if I assume $\lambda=0$, then the put price and call is roughly inline (call 2.3745 vs. put 2.3887). It could be I'm compensating for the jumps incorrectly (i.e., the drift).

$\endgroup$
2
  • 1
    $\begingroup$ Even if I add the obviously missing statements import seaborn as sns import matplotlib.pyplot as plt it is not running. So the answer is NO. $\endgroup$ Commented Dec 2, 2024 at 9:51
  • $\begingroup$ Thanks for pointing it out. I've edited and it should run successfully. $\endgroup$ Commented Dec 3, 2024 at 2:02

1 Answer 1

0
$\begingroup$

I think it is good (with the missing imports).

A good way to check is if the mean and variance of each r1 and r2 are what you expect them to be.

For the up-mean, you can do: lam * p_up * size_up, and print r1.mean() and so on.

With your values I get 0.015988326898183785 vs 0.015873015873015872 so pretty good.

And you can compute analytic variance for a full check. Make sure you test non symmetric cases too.

$\endgroup$
6
  • $\begingroup$ Thanks. The reason I asked is that when I calculate a Vanilla European AtM call and put option with risk free rate and dividend yield of zero for any expiry (e.g., 10 days), the put-call parity breaks where the call value is greater than put (e.g., call is greater by ~4%) when jump parameters introduce; I thought the implementation was incorrect. However, when there is no jump $\lambda = 0$ the put-call parity holds. $\endgroup$ Commented Dec 3, 2024 at 2:19
  • $\begingroup$ @AnonymousJ Is the call value not greater than put in any model whenever the call is ITM? If you still have doubts with those jumps you should post a mathematical description of that model plus the code that values the options. $\endgroup$ Commented Dec 3, 2024 at 9:10
  • $\begingroup$ If your problem is the P/C parity, I wonder if your process is an exact martingale (in discrete time I mean). Are you compensating for jumps correctly? Look at (14) in columbia.edu/~sk75/MagSci02.pdf I guess you are taking the exponential of "m", check its expected value is 1 (after compensation). $\endgroup$ Commented Dec 3, 2024 at 19:39
  • $\begingroup$ @KurtG. I was pricing AtM with risk-free rate equal to zero. I edit to add mathematical description of the model and the AtM put and call option values. $\endgroup$ Commented Dec 4, 2024 at 4:15
  • $\begingroup$ @Andrea That is what I'm wondering as well. I edited in the main to provide a mathematical description of what I'm simulating. It could be that I'm not correctly compensating for the jumps. $\endgroup$ Commented Dec 4, 2024 at 4:17

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.