Skip to content
All library documents

Why Correlated Brownian Motion Simulations Differ Across Methods

Article Quant Q&A · Author: Whitebeard13

Summary

The document compares two ways to generate paired Brownian increments with a specified negative correlation and time-step variance. One approach draws independent standard normal samples and transforms one using the target correlation; the other draws directly from a bivariate normal distribution with the corresponding covariance matrix. Although both target the same theoretical distribution, the example produces different sample values despite resetting the random seed to the same value.

The key distinction is that a seed initializes a pseudorandom number generator, but different sampling routines can consume or transform its draws differently. The two methods therefore need not produce matching paths, even when their distributional assumptions agree. The displayed means and standard deviations are finite-sample outcomes, not proof that either implementation is wrong. The document poses the discrepancy but does not include an answer or investigate the particular NumPy algorithms and version behavior, so it leaves the implementation diagnosis open.

Key ideas

  • Both approaches aim to produce increments with the same bivariate normal distribution and correlation.
  • Resetting a random seed does not guarantee identical samples when different sampling routines are used.
  • The two methods can transform or consume pseudorandom draws differently while preserving the target distribution.
  • Finite-sample means and standard deviations can differ from their theoretical values.
  • The document presents the discrepancy but does not establish whether either implementation is faulty.

Tags

Full text
# Generation of two correlated Brownian Motions using two different approaches in numpy Python


# Generation of two correlated Brownian Motions using two different approaches in numpy Python












Consider two correlated Brownian Motions $W_{1,t}$ and $W_{2,t}$ for which it holds: $$dW_{1,t}\sim N(0, \sqrt{dt})$$ $$dW_{2,t}\sim N(0, \sqrt{dt})$$ $$Cov(dW_{1,t},dW_{2,t}) = E[dW_{1,t}dW_{2,t}] = \rho dt$$

Assuming the correlation value $\rho = -0.744755$, the time increment $dt = \frac{7}{365}$, and the same seed value of $100$, I would expect that the following two approaches in `numpy` would produce the same simulated figures:

Approach 1:

```
import numpy as np

# Define parameters
r = -0.744755
dt = 7/365

np.random.seed(100)
x = np.random.normal(size=(100, 2))
x1 = x[:, 0]
x2 = r * x[:, 0] + np.sqrt(1 - r ** 2) * x[:, 1]
x1 = x1 * np.sqrt(dt)
x2 = x2 * np.sqrt(dt)
```

Approach 2:

```
import numpy as np

# Define parameters
r = -0.744755
dt = 7/365

# Approach 2
np.random.seed(100)
cov = np.array([[1, r], [r, 1]]) * dt
x1_, x2_ = np.random.multivariate_normal([0, 0], cov, 100).T
```

Outcome examples (first 5 values):

```
 x1      x1_     x2      x2_
-0.2423  0.2433  0.2121 -0.2094
 0.1597 -0.1616 -0.1423  0.1367
 0.1359 -0.1015 -0.0537  0.1524
 0.0306 -0.0815 -0.1217 -0.0243
-0.0262  0.0371  0.0431 -0.0119
```

Means & standard deviations:

```
      x1             x1_             x2              x2_
mean -0.002731633   -0.005101412    -0.012261188    -0.010204166
std   0.151998354    0.151263783     0.145546227     0.147439093
```

Despite the use of the same seed and the rest of the inputs, the outcomes deviate, and I would like to understand whether this is a matter of incorrect implementation of the methodology in any of the two approaches, or if it is just a matter of the algorithm generating the random figures.

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.