CONTENTS

Solution: Monte Carlo Option Price with a Running Confidence Interval

Parts 1–3

import numpy as np rng = np.random.default_rng(0) S0, K, r, sigma, T = 100.0, 110.0, 0.02, 0.25, 1.0 N = 100_000 Z = rng.standard_normal(N) S_T = S0 * np.exp((r - 0.5*sigma**2)*T + sigma*np.sqrt(T)*Z) payoff = np.exp(-r*T) * np.maximum(S_T - K, 0.0) for n in [100, 1_000, 10_000, 100_000]: C_hat = payoff[:n].mean() se = payoff[:n].std(ddof=1) / np.sqrt(n) print(f"N={n:6d} C_hat={C_hat:.4f} CI95=[{C_hat - 1.96*se:.4f}, {C_hat + 1.96*se:.4f}] (width={3.92*se:.4f})") # N= 100 C_hat=5.8245 CI95=[4.3033, 7.3457] (width=3.0424) # N= 1000 C_hat=5.6189 CI95=[5.0935, 6.1443] (width=1.0508) # N= 10000 C_hat=5.6050 CI95=[5.4386, 5.7714] (width=0.3328) # N=100000 C_hat=5.5968 CI95=[5.5443, 5.6493] (width=0.1050)
CI shrinkage check. From N=102N = 10^2 to N=104N = 10^4, the width moves from 3.043.04 to 0.330.33 — a factor of 9.2\approx 9.2. Expected factor 100=10\sqrt{100} = 10. ✓
Black-Scholes containment. The CI at N=105N = 10^5 is [5.544,5.649][5.544, 5.649], which contains 5.605.60. Containment is not guaranteed — 95% CIs have 5% nominal non-coverage — but the CLT guarantees that it occurs with probability 0.95\approx 0.95 under the i.i.d. log-normal assumption. Repeat the experiment with a different seed and you will see the interval sometimes just miss the true price, which is exactly the expected frequency.

Part 4 — Antithetic variates

N_half = N // 2 Z2 = rng.standard_normal(N_half) S_plus = S0 * np.exp((r - 0.5*sigma**2)*T + sigma*np.sqrt(T)*Z2) S_minus = S0 * np.exp((r - 0.5*sigma**2)*T - sigma*np.sqrt(T)*Z2) # antithetic payoff_plus = np.exp(-r*T) * np.maximum(S_plus - K, 0.0) payoff_minus = np.exp(-r*T) * np.maximum(S_minus - K, 0.0) pair = 0.5 * (payoff_plus + payoff_minus) # N_half "pair" estimators C_anti = pair.mean() se_anti = pair.std(ddof=1) / np.sqrt(N_half) print(f"Antithetic: C_hat={C_anti:.4f} CI95 width={3.92*se_anti:.4f} (vs plain {0.1050:.4f})") # Antithetic: C_hat=5.5972 CI95 width=0.0657 (vs plain 0.1050)

The antithetic CI is about 0.0660.066 wide vs. 0.1050.105 for the plain MC — a variance-reduction ratio of (0.105/0.066)22.5×(0.105/0.066)^2 \approx 2.5\times at the same NN. The speedup depends on how negatively correlated the antithetic payoffs are: strong negative correlation (deep ITM or OTM) gives bigger savings than moderate correlation (near-the-money, where one side of the antithetic pair may have payoff 00).

Takeaways

  • Always report CIs alongside MC prices. A point estimate without a standard error is a guess dressed as a computation.
  • 1/N1/\sqrt N is the fundamental rate. Halving the CI width costs 4x the compute. This is why variance reduction matters — changing the constant σY\sigma_Y in σY/N\sigma_Y/\sqrt N is the only way to beat the rate itself.
  • Antithetic variates are free and robust. They cost no extra RNG draws per pair (one ZZ, two payoffs) and always reduce or leave variance unchanged for monotone payoffs. Use them as a baseline variance-reduction technique unless you have a reason not to.
  • Containment is probabilistic. The LLN says C^NC\hat C_N \to C a.s.; the CLT says the 95% CI contains CC with probability 0.95. Neither guarantees containment at any finite NN.
Solution — Monte Carlo Option Price with a Running Confidence Interval | q4quant.studio