This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

Notebooks · posts/black-scholes-by-monte-carlo

Black-Scholes by Monte Carlo, against the closed form

The price of a one-year call option on a $100 stock with strike $100, 5% interest and 20% volatility is $10.4506 by the Black-Scholes formula. Simulating the stock price 131072 times and averaging the discounted payoff gives $10.371, 1.95 standard errors away. The error shrinks as : its measured slope on a log-log plot is , against , and the standard error comes from an exact formula for the payoff's spread.

The reference, posts/refs/black-scholes-by-monte-carlo.py, evaluates the closed form with scipy.stats.norm, derives the payoff's exact standard deviation, replays this run's random numbers in Python, and repeats the whole simulation 2000 times with numpy's generator to measure how much each result varies from run to run. The tests' tolerances are multiples of those spreads.

Look inside this program

  • Atlas

    The program’s map: every function and which calls which.

  • There’s no recorded run of this program yet.

Shift+Enter in a cell runs it and moves to the next. Running a cell runs every cell above it too, as one program.

The option and its price

A call option is the right, not the obligation, to buy a stock at a fixed price , the strike, on a fixed date years away. If the stock then trades at the holder buys at and gains ; otherwise the option expires unused. Its payoff is .

What should that right cost today? Black, Scholes and Merton (1973) showed that if the stock price follows geometric Brownian motion (random percentage changes, with volatility per square-root year), a portfolio of the stock and cash can reproduce the option's payoff exactly, so the option must cost what that portfolio costs. The answer is the formula above, with the standard normal cumulative distribution and

The same argument gives a second way to compute it: the price is the average payoff, discounted at the interest rate , over stock prices that grow on average at rather than at the stock's actual expected return:

The first cell evaluates the formula, and checks it against put-call parity: a call minus a put (the right to sell at ) is worth exactly , by any model.

[1]lines 47–74

The Monte Carlo estimate and its error

Draw independent values of , compute the discounted payoff for each, and average. The average is an unbiased estimate of the price, and by the central limit theorem its error is close to normal with standard deviation , the standard error, where is the standard deviation of one payoff. Quadrupling halves the error, whatever the dimension of the problem; that rate is the reason Monte Carlo is used for options on many assets, where grids cannot be.

has a closed form too. The payoff's second moment needs , and , and . Here : one payoff varies by more than the price itself, since 44% of the time it is zero.

The cell simulates payoffs and keeps the running average at every power of two from 16 on. At each it compares the estimate with the formula. Before running: at , how far off should the estimate be? About , a third of the price.

[2]lines 100–189

The rate, measured

One run's error at each is a single random number, so it cannot show a rate by itself: at this run happens to be 0.12 standard errors off and at 131072 it is 1.95 off. To see the rate, cut the 131072 payoffs into batches of consecutive ones, average each batch, and take the root-mean-square (RMS) error of the batch averages against the formula. For there are 8192 batches, for there are 32.

The fitted slope of against for should be . The reference repeated this with 2000 runs of numpy's generator and found slopes of , so the test allows .

[3]lines 207–250

The points follow the line from 3.67 at to 0.245 at . Getting one more correct digit takes 100 times as many paths, which is why practical Monte Carlo pricing adds variance reduction (antithetic draws, control variates) that lowers rather than the exponent.

[4]lines 259–260