All projects

Options pricing and Greeks engine

Black-Scholes, binomial and Monte Carlo option pricers in Python, checked against each other.

  • Role Sole author — implementation and validation
  • Stack Python, NumPy, SciPy, pandas, Matplotlib, Plotly
  • Completed
  • Jul–Sep 2026

Live demo

Three methods, one price

The notebook's Black-Scholes, binomial, Monte Carlo and implied-volatility code, ported to run here.

Price and Greeks

Move any input. Call and put update together, and put-call parity is checked on every change.

MeasureCallPut
Price10.45065.5735
Delta0.6368−0.3632
Gamma0.0187620.018762
Vega37.524037.5240
Theta−6.4140−1.6579
Rho53.2325−41.8905

Vega and rho per 1.00 change in σ and r (÷100 for one point); theta per year.

C − P
4.8771
S − K·e−rT
4.8771
Parity residual
0.0000000000

Two numerical methods converging on the analytical price

The baseline call: S = K = 100, σ = 20%, T = 1 year, r = 5%.

Binomial tree, 5 to 500 stepsOdd step counts land above the line, even counts belowodd even
10.210.410.610.85102550100250500Black-Scholes 10.4506

500 steps: 10.4466, −0.04% against Black-Scholes. The error flips sign with the step count's parity and shrinks as the tree grows.

Monte Carlo, 1k to 500k pathsEach point with its 95% error bar, from one run of paths
9.510.010.511.011.51k2k5k10k20k50k100k200k500k
Estimate
10.4665
Standard error
0.0209
Off Black-Scholes by
+0.0159 (0.76 SE)

The error bar shrinks as 1/√n, but any single estimate can sit further from the line than one with fewer paths. Draw new paths to see it move.

Implied volatility, solved backwards

Give a market price for the baseline call and the solver finds the volatility that reproduces it, then prices it back as a check.

Implied volatility
0.241117
Iterations
7
Priced back
12.000000

Bracket 0.0001 to 5.0, as in the notebook. A call here has a volatility in that bracket only if its price is between 4.8771 and 98.79.

  1. 14.9999
  2. 20.3792
  3. 30.1607
  4. 40.1383
  5. 58.6e−5
  6. 68.1e−8
  7. 71.0e−12

Problem

A learning project: implement the standard textbook ways of pricing a European option, and check that they agree. Black-Scholes gives a closed-form answer; a binomial tree and a Monte Carlo simulation get there numerically. If all three land on the same number, the implementations are probably right. If they don’t, one of them isn’t.

Approach

Python with NumPy and SciPy, in one notebook. Black-Scholes prices calls and puts and gives the five Greeks: delta, gamma, vega, theta and rho. The Cox-Ross-Rubinstein tree prices the call by backward induction over up to 500 steps. The Monte Carlo pricer simulates terminal prices under risk-neutral geometric Brownian motion and discounts the average payoff. Implied volatility is solved backwards from a market price with Brent’s method on a bracket of 0.0001 to 5.0.

Every method is checked against the same baseline option: spot and strike 100, volatility 20%, one year, rate 5%.

Result

Black-Scholes prices the baseline call at 10.4506 and the put at 5.5735, and put-call parity holds exactly: call minus put and spot minus the discounted strike both come to 4.8771. The binomial tree reaches 10.4466 at 500 steps, 0.04% below. Its error flips sign with the number of steps, odd counts landing above and even counts below, and shrinks as the tree grows. Monte Carlo with 500,000 paths gives 10.4500, within 0.005%, though its standard error at that size is about 0.2% of the price, so the closeness is partly the luck of the seed.

Brent’s method recovers an implied volatility of 24.11% from a market price of 12.00 in 7 iterations, and pricing back at that volatility returns 12.000000.

Checking the Greeks turned up a bug: a loop that sweeps the stock price left d2 holding its value at S = 150, so theta and rho were first computed from the wrong d2 (−8.4385 and 93.7220). With d2 rebuilt they are −6.4140 and 53.2325.

These are textbook methods implemented to learn them, not a trading tool.

Next project

Keep reading

Cooped Up

A campus social app in React Native and Supabase. I ran user testing and planned a Figma redesign around a bottom tab bar.