Three ways to price an option, and the surface to price it on
Black-Scholes, a binomial tree and Monte Carlo that agree within their error bars, Greeks computed four ways, and arbitrage-free SVI volatility surfaces fitted to SPY and QQQ option chains.
By Mizan Nurani
Data as of October 9, 2026
Built with Python, NumPy, SciPy, TypeScript
European (Black-Scholes)
$15.07
intrinsic $0.00, time value $15.07
American (binomial tree)
$15.07
early-exercise premium $0.000
Implied vol used
12.61%
off the surface at 99.7% of the forward
Probability in the money
52.1%
risk-neutral; breakeven $795.07
Greeks, per share (a listed contract is 100 shares)
- Delta
- 0.5390
- per $1 of spot
- Gamma
- 0.01152
- delta per $1
- Vega
- $1.0854
- per vol point
- Theta
- −$0.1987
- per calendar day
- Rho
- $0.4988
- per point of rates
- Vanna
- −0.00169
- delta per vol point
- Volga
- $0.00045
- vega per vol point
- Dollar gamma
- $0.349
- P&L for a 1% move
Black-Scholes Greeks with the vol held fixed. The American price is the closed form plus the gap between American and European 400-step trees, which cancels most of the tree’s own error.
Put-call parity
C − P = 2.605643
S e−qT − K e−rT = 2.605643
Gap below 5e-14
Monte Carlo, 200,000 paths
Antithetic pairs, seed 2026, one step to expiry.
σ = 12.609%
Exhibit 1Value against spot
Per share, today, with 23 days left and at expiry. Vol re-read from the surface at each spot.
- Today
- 23 days left
- At expiry
Black-Scholes on the fitted surface. Author’s calculations.
Exhibit 2How the risk moves with spot
Delta per share
Greek
- Today
- 23 days left
- 7 days left
Analytical Black-Scholes Greeks. Author’s calculations.
Exhibit 3Scenario grid
Change in value per share for a spot move (rows) and a parallel vol shift (columns), the same day. The outlined cell is today.
| Spot / Vol | −5 pts | −2 pts | 0 pts | +2 pts | +5 pts |
|---|---|---|---|---|---|
| −10% ($701) | −15.07 | −15.06 | −14.99 | −14.82 | −14.28 |
| −5% ($740) | −15.04 | −14.54 | −13.78 | −12.73 | −10.76 |
| −2% ($763) | −12.75 | −10.07 | −8.13 | −6.13 | −3.06 |
| 0% ($779) | −5.42 | −2.17 | 0.00 | +2.17 | +5.43 |
| +2% ($794) | +6.46 | +9.16 | +11.10 | +13.09 | +16.16 |
| +5% ($817) | +27.89 | +29.59 | +30.99 | +32.54 | +35.06 |
| +10% ($856) | +66.00 | +66.87 | +67.67 | +68.64 | +70.36 |
Black-Scholes on the fitted surface, under the spot rule chosen above. Author’s calculations.
The SPY surface
Moving spot in the pricer moves this surface under the rule you chose (spot 0.0%). Shocks act on implied vol by moneyness, and the pricer reads the shocked vol.
Fades with a three-month time constant
- No butterfly arbitrage
- No calendar arbitrage
Checked live at every fitted expiry: the butterfly condition over the quoted strikes plus 10%, and total variance against the previous expiry where both are quoted.
Exhibit 4The smile at 45 days
Implied vol by strike as a share of the forward, over the strikes quoted near that expiry
- Fitted
- Your option
SVI fits to SPY option quotes; Mizan Nurani, options-engine. Author’s calculations.
Exhibit 5At-the-money vol by expiry
Implied vol at the forward, from a week to two years, log scale in time
- SPY
- QQQ
SVI fits to SPY and QQQ option quotes; Mizan Nurani, options-engine. Author’s calculations.
Exhibit 6The surface, expiry by strike
Implied vol (%) at every other fitted expiry, by strike as a share of the forward. Blank where that expiry has no quotes.
| Expiry / K/F | 80% | 85% | 90% | 95% | 100% | 105% | 110% |
|---|---|---|---|---|---|---|---|
| 2026-10-16 (7d) | 30.9 | 18.2 | 9.5 | ||||
| 2026-10-30 (21d) | 37.4 | 30.1 | 22.8 | 16.1 | 11.1 | 10.2 | |
| 2026-11-13 (35d) | 33.4 | 27.5 | 21.7 | 16.4 | 12.1 | 10.5 | 12.3 |
| 2026-11-30 (52d) | 30.2 | 25.3 | 20.4 | 15.9 | 12.3 | 10.4 | 11.2 |
| 2026-12-31 (83d) | 27.9 | 23.8 | 19.9 | 16.3 | 13.3 | 11.3 | 11.0 |
| 2027-01-29 (112d) | 26.6 | 23.0 | 19.6 | 16.4 | 13.8 | 11.9 | 11.2 |
| 2027-03-19 (161d) | 25.0 | 22.0 | 19.2 | 16.7 | 14.6 | 13.0 | 12.0 |
| 2027-06-17 (251d) | 23.8 | 21.4 | 19.2 | 17.2 | 15.5 | 14.1 | 13.1 |
| 2027-09-17 (343d) | 23.1 | 21.0 | 19.2 | 17.5 | 16.0 | 14.9 | 13.9 |
| 2027-12-17 (434d) | 22.5 | 20.8 | 19.1 | 17.7 | 16.4 | 15.4 | 14.5 |
| 2028-06-16 (616d) | 21.9 | 20.4 | 19.1 | 17.9 | 16.8 | 15.9 | 15.1 |
| 2028-12-15 (798d) | 21.6 | 20.3 | 19.1 | 18.0 | 17.0 | 16.2 | 15.5 |
SVI fits to SPY option quotes; Mizan Nurani, options-engine. Author’s calculations.
Three pricers, one answer
The engine prices a European option three independent ways and treats any disagreement as a bug. Black-Scholes-Merton with a continuous dividend yield is the closed form:
The Cox-Ross-Rubinstein tree moves the stock up by or down by with risk-neutral probability , then rolls the payoff back to today. An American option takes the larger of holding and exercising at every node. The tree oscillates as the strike falls between nodes at a position that shifts with the number of steps; averaging N and N+1 steps removes most of it (Exhibit 7). With the same inputs, the tree values the American put at 10.390 against 10.056 for the European, an early-exercise premium of 0.334.
Exhibit 7The binomial tree converges to Black-Scholes, with a sawtooth
Call price by number of steps (S 100, K 105, nine months, 25% vol, 4% rate, 1% yield)
- Average of N and N+1 steps
- Tree at N steps, even and odd
Cox-Ross-Rubinstein tree, run on this page’s engine. Author’s calculations.
Monte Carlo draws the terminal price exactly in one step and reports every estimate with its standard error, so agreement is judged in standard errors rather than digits. On a million paths, antithetic pairs cut the variance by only 1.4x, because an out-of-the-money call’s payoff is far from linear in the normal draw. A control variate on the discounted terminal price, whose expectation is known, cuts it by 4.2x (Exhibit 8).
Exhibit 8Monte Carlo, with and without variance reduction
The call in Exhibit 7, a million paths, seed 2026
| Method | Estimate | Standard error | Distance from closed form | Variance reduction |
|---|---|---|---|---|
| Plain | 7.4126 | 0.0134 | 0.07 SE | 1.0x |
| Antithetic variates | 7.4117 | 0.0112 | 0.01 SE | 1.4x |
| Control variate | 7.4137 | 0.0066 | 0.31 SE | 4.2x |
Closed form 7.4117.
Mizan Nurani, options-engine (results/mc_variance_reduction.csv).
Greeks four ways
Each Greek is computed four ways: the closed form, central differences on the closed form, central differences on Monte Carlo, and pathwise Monte Carlo, which differentiates the payoff along each simulated path:
That works because a call or put payoff is Lipschitz. It fails for gamma: is a step at the strike, so its derivative is a spike the simulation never samples. Gamma uses the likelihood-ratio estimator instead, which differentiates the density rather than the payoff:
The bumped Monte Carlo reuses the same draws for the up and down bumps, so most of the noise cancels path by path. Every estimate in Exhibit 9 sits within 0.63 standard errors of the closed form.
Exhibit 9Greeks four ways
The option in Exhibit 7. Monte Carlo on 500,000 paths, seed 2026; z is the pathwise estimate’s distance from the closed form in standard errors. Vega and rho per unit.
Option
| Greek | Closed form | Bumped closed form | Bumped Monte Carlo | Pathwise Monte Carlo | z |
|---|---|---|---|---|---|
| Delta | 0.49105 | 0.49102 | 0.49103 ± 0.00084 | 0.49113 ± 0.00085 | +0.10 |
| Gammalikelihood ratio | 0.01829 | 0.01828 | 0.01823 ± 0.00016 | 0.01839 ± 0.00016 | +0.63 |
| Vega | 34.288 | 34.288 | 34.302 ± 0.092 | 34.303 ± 0.092 | +0.16 |
| Theta, a year | −6.891 | −6.891 | −6.894 ± 0.017 | −6.894 ± 0.017 | −0.16 |
| Rho | 31.270 | 31.270 | 31.273 ± 0.053 | 31.275 ± 0.053 | +0.09 |
Mizan Nurani, options-engine (results committed in the repository). Author’s calculations.
What discrete hedging leaves behind
The engine sells a six-month at-the-money call for $6.37, hedges it at Black-Scholes delta, and lets the stock drift at 8% a year in the real world. The P&L is centered on zero whatever the drift, which is the replication argument at work. What is left is the error from hedging at intervals: with 26 rebalances, about weekly, its standard deviation is $0.93, 15% of the premium; with 126, about daily, it falls to $0.44 (7%). The fitted slope of −0.49 in Exhibit 10 is close to the theoretical one half.
Exhibit 10Hedging error shrinks with the square root of the rebalances
Standard deviation of the P&L of a short six-month at-the-money call hedged at Black-Scholes delta (premium $6.37). Log scales; fitted slope −0.49.
- Simulated, 20,000 paths
- One over the square root of n
Mizan Nurani, options-engine (results committed in the repository). Author’s calculations.
From option chains to a surface
The second half of the engine builds the SPY and QQQ surfaces in the lab above from a snapshot of their option chains at the October 9, 2026 close. Every filter counts what it drops (Exhibit 11): expiries under a week or over 800 days, zero bids, crossed markets, prices under five cents, spreads wider than half the mid, no open interest, and the in-the-money side of each strike, which keeps the early-exercise bias small.
Exhibit 11Every dropped quote is counted
Option quotes at the October 9, 2026 close, filters applied in order
| Step | SPY dropped | QQQ dropped |
|---|---|---|
| Raw quotes | 8,646 | 7,810 |
| Expiry outside window | 620 | 755 |
| Zero or missing bid | 494 | 303 |
| Crossed or locked market | 2 | 1 |
| Mid below 0.05 | 297 | 205 |
| Relative spread above 50% | 49 | 191 |
| No open interest | 371 | 333 |
| OTM selection (ITM side dropped) | 2,730 | 2,699 |
| Out-of-the-money quotes used | 4,083 | 3,323 |
| Isolated stale quotes removed before fitting | 46 | 21 |
Mizan Nurani, options-engine (results/cleaning_*.csv); quotes from Yahoo Finance.
Discount rates from the right options
Put-call parity gives each expiry’s discount factor and forward without assuming a rate: regressing on the strike gives slope and intercept . On SPY and QQQ that regression is biased, because the early-exercise premium in in-the-money puts lowers at high strikes; it implies rates as low as −35%. European SPX options carry no such premium, so the curve comes from SPX (Exhibit 12). Fitted as , it gives 4.42% at three months and 4.88% at a year.
Exhibit 12Discount rates from European SPX options
Zero rate implied by put-call parity at each SPX expiry, and the curve r(T) = c₀ + c₁ ln T fitted through them
- Fitted curve
- Implied by one expiry
Mizan Nurani, options-engine (results committed in the repository). Author’s calculations.
De-Americanizing the quotes
Each quote is then inverted on the American tree rather than the closed form. The bias from treating it as European is small in the middle of the chain (a median of 0.04 vol points for SPY) but reaches 4.3 vol points for long-dated puts near the forward. With rates well above the dividend yield the forward sits far above spot, so a long-dated put can be out of the money against the forward and in the money against spot, where early exercise is worth something.
A first attempt took the dividend yield from the parity forward and over-corrected, because that forward came from American prices and already carried the put’s premium. The fix calibrates the yield per expiry so that American-model put and call vols agree at the six strikes nearest the money. Checked out of sample at strikes further out, the median put-call gap falls from 0.65 to 0.04 vol points for SPY, and from 0.56 to 0.02 for QQQ. The calibrated yields also recover SPY’s quarterly dividend without being told about it (Exhibit 13): within 0.15% of zero for the November expiries, then 0.6% for December 18 and 1.1% for December 31, after the mid-December ex-dividend date. The yield also absorbs any cost of borrowing the ETF.
Exhibit 13Calibrated dividend yields find the ex-dividend dates
The continuous yield per expiry at which American-model put and call vols agree near the money
- SPY
- QQQ
Mizan Nurani, options-engine (results committed in the repository). Author’s calculations.
An arbitrage-free fit
Each expiry is fitted with raw SVI, in total variance against log-moneyness :
The fit minimizes implied-vol errors scaled by the bid-ask half-spread, with three no-arbitrage conditions as penalties: the Gatheral-Jacquier butterfly function over the quoted strikes plus a margin (a non-negative density), total variance that never falls with maturity where adjacent expiries are both quoted, and Roger Lee’s wing bound . Fitted freely, the SPY surface had butterfly arbitrage in 4 slices (QQQ 0) and 1 calendar violation (QQQ 1). With the constraints there are none, and the median fit error for SPY is unchanged at 0.13 vol points.
The constraints hold the fitted slices right at their boundary, which is why the live check in the surface section flags arbitrage after only a small change: a skew 5% steeper than fitted is enough for SPY. At the money, vol rises with maturity, from 9.5% at a week to 17.0% at 2.2 years for SPY (14.6% to 22.1% for QQQ), and QQQ carries 5.1 to 6.1 vol points more than SPY at every expiry both list (Exhibit 5).
How it is checked
- Known values. Hull’s textbook examples, including the five-step American put, and the standard at-the-money reference call.
- Invariants. Put-call parity on thousands of random inputs, prices inside the model-free bounds, the call and put deltas a dividend discount apart, an American call without dividends worth exactly the European, and an American put never below intrinsic value.
- Inversion. Implied vol reprices every option it inverts, and returns nothing rather than a wrong answer outside the no-arbitrage bounds.
- Simulation. Monte Carlo within four standard errors of the closed form for every variance-reduction choice, a standard error that falls with the square root of the paths, and results that repeat from a seed.
- The surface pipeline, on synthetic chains with known answers. The parity regression recovers the forward and discount factor and ignores a stale quote, each cleaning rule drops exactly its target, the American inversion recovers a known vol, and the dividend calibration recovers a known yield.
- Two implementations. The TypeScript engine on this page reproduces the closed-form Greeks committed in the Python repository to twelve significant digits (the bumped ones to nine), and recomputes every fitted slice’s at-the-money vol, butterfly minimum, wing slope and calendar gap from its parameters.
What it leaves out
- The pricers assume constant volatility and rates; the tree is plain Cox-Ross-Rubinstein.
- The hedging experiment ignores transaction costs, which would penalize frequent rebalancing.
- The surface is one snapshot of end-of-day quotes, with no check that calls and puts were quoted at the same moment. Your numbers would differ on another day.
- Dividends are a continuous yield per expiry rather than cash amounts on known ex-dates.
- Raw SVI has five parameters per expiry and cannot follow the steepest short-dated put wings: the worst slice is QQQ at 42 days, 0.74 vol points of fit error. SSVI or eSSVI would give a jointly arbitrage-free surface with fewer slice-by-slice compromises.
- Next steps: price an exotic off the fitted surface, a Dupire local-volatility model, and a cross-check against QuantLib.
Model, data pipeline and fits from Mizan Nurani’s options-engine (commit f4376f5, October 11, 2026). Option chains from Yahoo Finance at the October 9, 2026 close. This is a study, not a recommendation.