Black-Scholes Monte Carlo Pricer

Options Pricing · Hard · Free problem

You are building a simple Monte Carlo pricer for a European call option. The underlying stock follows geometric Brownian motion:

$$dS_t = \mu S_t \, dt + \sigma S_t \, dW_t$$

with initial price $S_0$, constant volatility $\sigma$, and risk-free rate $r$. The call has strike $K$ and maturity $T$.

  1. Derive the risk-neutral distribution of $S_T$. Write an expression for the option price as $e^{-rT} \, E^Q[(S_T - K)^+]$.
  1. Describe an algorithm that approximates this expectation via Monte Carlo using $M$ simulation paths. Specify exactly how you generate $S_T$ on each path. Analyze the time complexity in terms of $M$.
  1. How would you reduce the variance of your Monte Carlo estimator? Discuss at least two techniques (e.g., antithetic variates, control variates) and explain how you would empirically verify that the pricer is converging correctly.

Example

``` bs_mc_call(100, 100, 1.0, 0.05, 0.2, 20000, 1) ≈ 10.45058 ```

The result is a Monte-Carlo estimate that converges to 10.45058 as the sample count grows (deterministic for a fixed seed).

Hints

  1. Start by applying Ito's lemma to $\ln S_t$ under the risk-neutral measure to get the exact distribution of $S_T$ -- you can sample it directly without path discretization.
  2. Since you only need $S_T$ (not the full path), each Monte Carlo draw is just one standard normal plugged into the lognormal formula -- giving $O(M)$ total complexity.
  3. For variance reduction, think about what quantities you know the exact expectation of. The stock price itself has $E^Q[S_T] = S_0 e^{rT}$, which makes it a natural control variate.

Worked Solution

How to Think About It: This is the bread-and-butter of quant interview take-homes. The interviewer is checking three things: (1) you know what risk-neutral pricing means and can apply Ito's lemma to get the terminal distribution, (2) you can translate a mathematical formula into a clean simulation, and (3) you understand that naive Monte Carlo is noisy and know practical tricks to fix it. Think of this as three mini-problems stacked together -- derivation, implementation, engineering.

Part (a): Risk-Neutral Distribution of $S_T$

Under the risk-neutral measure $Q$, the drift $\mu$ is replaced by $r$, so:

$$dS_t = r S_t \, dt + \sigma S_t \, dW_t^Q$$

Apply Ito's lemma to $\ln S_t$. Let $f(S) = \ln S$. Then $f'(S) = 1/S$ and $f''(S) = -1/S^2$, so:

$$d(\ln S_t) = \left(r - \frac{\sigma^2}{2}\right) dt + \sigma \, dW_t^Q$$

Integrating from $0$ to $T$:

$$\ln S_T = \ln S_0 + \left(r - \frac{\sigma^2}{2}\right) T + \sigma \sqrt{T} \, Z, \quad Z \sim N(0,1)$$

Equivalently:

$$S_T = S_0 \exp\!\left[\left(r - \frac{\sigma^2}{2}\right) T + \sigma \sqrt{T} \, Z\right]$$

So $\ln S_T$ is normally distributed with mean $\ln S_0 + (r - \sigma^2/2)T$ and variance $\sigma^2 T$, meaning $S_T$ is lognormal. The option price is:

$$C = e^{-rT} \, E^Q[(S_T - K)^+]$$

Part (b): Monte Carlo Algorithm and Code

The algorithm is direct sampling from the exact terminal distribution -- no need to discretize the path since we only care about $S_T$.

Algorithm: 1. For each path $i = 1, \ldots, M$: draw $Z_i \sim N(0,1)$ and compute $S_T^{(i)} = S_0 \exp[(r - \sigma^2/2)T + \sigma \sqrt{T} \, Z_i]$. 2. Compute the payoff $V_i = (S_T^{(i)} - K)^+$. 3. Estimate $\hat{C} = e^{-rT} \frac{1}{M} \sum_{i=1}^{M} V_i$.

```python import numpy as np from scipy.stats import norm

def bs_mc_call(S0, K, T, r, sigma, M, seed=42): rng = np.random.default_rng(seed) Z = rng.standard_normal(M) ST = S0 * np.exp((r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * Z) payoffs = np.maximum(ST - K, 0.0) price = np.exp(-r * T) * np.mean(payoffs) se = np.exp(-r * T) * np.std(payoffs, ddof=1) / np.sqrt(M) return price, se ```

Complexity: Each path requires $O(1)$ work (one random draw, one exp, one max). Summing over $M$ paths gives $O(M)$ total time and $O(M)$ space (or $O(1)$ space if you accumulate online). The standard error of the estimator decreases as $O(1/\sqrt{M})$, so getting one more decimal digit of accuracy requires $100\times$ more paths.

Part (c): Variance Reduction

Antithetic variates. For each $Z_i$, also compute the payoff using $-Z_i$. The pair $(S_T(Z_i), S_T(-Z_i))$ shares the same random draw but covers both tails. Your estimator becomes:

$$\hat{C}_{\text{AV}} = e^{-rT} \frac{1}{M} \sum_{i=1}^{M} \frac{V(Z_i) + V(-Z_i)}{2}$$

This works because the payoff is a monotone function of $Z$, so $V(Z)$ and $V(-Z)$ are negatively correlated, reducing variance. In practice this cuts variance by roughly 20-30% for vanilla options.

Control variates. Use $S_T$ itself as a control. We know $E^Q[S_T] = S_0 e^{rT}$ exactly. Define:

$$\hat{C}_{\text{CV}} = \hat{C} - \beta \left(\frac{1}{M}\sum_{i=1}^{M} S_T^{(i)} - S_0 e^{rT}\right)$$

The optimal $\beta$ is $\text{Cov}(V, S_T) / \text{Var}(S_T)$, estimated from the same sample. Since the call payoff and terminal stock price are highly correlated, this typically reduces variance by 50-80%.

Empirical convergence verification: - Benchmark against Black-Scholes closed form. For a European call, the BS formula gives the exact answer. Run your MC pricer for increasing $M$ (e.g., $10^3, 10^4, 10^5, 10^6$) and confirm the MC estimate converges to the BS price and that the standard error shrinks proportional to $1/\sqrt{M}$. - Confidence intervals. At each $M$, compute a 95% CI as $\hat{C} \pm 1.96 \cdot \text{SE}$. The BS price should fall inside the CI roughly 95% of the time across repeated runs. - Log-log plot. Plot $\log(\text{SE})$ vs. $\log(M)$. You should see a slope of $-1/2$. If the slope is flatter, something is wrong (e.g., correlated draws, a bug in the payoff).

Answer: The option price is $C = e^{-rT} E^Q[(S_T - K)^+]$ where $S_T = S_0 \exp[(r - \sigma^2/2)T + \sigma\sqrt{T} Z]$ with $Z \sim N(0,1)$. The Monte Carlo estimator averages $M$ i.i.d. discounted payoffs in $O(M)$ time, converging at rate $O(1/\sqrt{M})$. Antithetic variates exploit monotonicity to pair $Z$ and $-Z$ for negative correlation; control variates use the known mean of $S_T$ to correct the estimator. Both can be verified by benchmarking against the Black-Scholes closed-form price.

Intuition

Monte Carlo pricing is one of the most important tools in quantitative finance, and this problem tests whether you truly understand the mechanics rather than just calling a library function. The key insight is that risk-neutral pricing converts an economics problem into a pure probability problem: replace the real-world drift with the risk-free rate, sample from the resulting distribution, average the discounted payoffs. For European options on a single underlying, you can sample the terminal price directly from the lognormal distribution -- no path simulation needed -- which makes the implementation trivially simple.

The real practical skill this tests is variance reduction. Naive Monte Carlo converges painfully slowly -- halving your error requires quadrupling your paths. In production, nobody runs plain vanilla MC. Antithetic variates are nearly free (you already generated the random number, just negate it) and control variates are the workhorse technique for any payoff correlated with the underlying. The deeper lesson: always look for quantities whose expectations you know analytically and use them to anchor your noisy estimate. This principle extends far beyond option pricing -- it is the core idea behind importance sampling, stratification, and quasi-Monte Carlo methods used across quant finance.

Open the full interactive solver →