Black-Scholes Formula

Can't derive it (lmao), but we can totally code it up — walking through the Black-Scholes pricing formula and computing actual call and put prices.

OK real talk — the title was a little misleading. Let me just come out and say it up front.

I cannot derive Black-Scholes. lmao

If you’re here for that, close the tab lmao

What I am going to do is code up the Black-Scholes Model. That’s the whole point. That’s all this is.

So first, let me just throw the thing at you — the Black-Scholes PDE (Partial Differential Equation), the one that literally won the Nobel Prize in Economics.

Equation from the original notes

That right there is the Black-Scholes partial differential equation. The Nobel one.

But here’s the thing — we’re not actually using that one directly.

What we will use is the option pricing formula you get when you take that PDE and grind through it with some seriously heavy-duty math. That result — the Black-Scholes option pricing equation — is honestly the kind of thing that could’ve taken home a Fields Medal, which is basically the Nobel Prize of math, not of economics.

Anyway, here it is:

Equation from the original notes

Equation from the original notes

OK so before we just start plugging numbers in, let me walk through the assumptions baked into the Black-Scholes model. Then we’ll actually try computing a call price and a put price using those formulas above.

i) There is no arbitrage opportunity

(no way to make a riskless profit)

······· ’no arbitrage opportunity'

ii) It is possible to borrow and lend any amount

(even fractional amounts) of cash at the riskless rate

······· you can borrow or lend any amount of cash

iii) It is possible to buy and sell any amount

(even fractional amounts) of stock

······· you can also buy or sell any amount of stock

iv) None of these transactions incur any fees or costs

······· no transaction costs, no commissions — perfectly frictionless market

v) The rate of return on the riskless asset is constant

······· the riskless rate is just a fixed number, always

vi) The stock price follows geometric Brownian motion,

and we assume its drift and volatility are both constant

······· stock price follows Brownian motion with constant drift and constant volatility

(What’s the right way to think about “drift” here — like, the general prevailing direction of the stock price? I’m honestly not totally sure.)

Oh and — one thing that’s apparently a huge deal about BS: you only need the volatility of the stock. Not the expected return of the stock. That’s the key insight, supposedly… heh

Anyway. Let’s just use it.

S = 800: k = 850: r = 0.05: T = 0.5: v = 0.2:

d_1 = (log( s / k ) + (r + 0.5*v*v)*T) / (v*sqr(T))
d_2 = d_1 - v*sqr(T)

with worksheetfunction

c = S*.NormSDist(d_1) - k*exp(-r*T)*.NormSDist(d_2)

p = k*exp(-r*T)*.NormSDist(-d_2) - S*.NormSDist(-d_1)

End with

debug.print "call option price is : " & c

debug.print "put option price is : " & p

End sub

The derivation behind the formula is brutal, sure. But actually coding it up from the formula? Not that bad at all.

Let me at least think through the $N(d_1)$ piece a little.

What $N(x)$ means is:

Equation from the original notes

So it’s the probability that a value drawn from the standard normal $N(0,1)$ comes out below $x$.

And $N(d_1)$ is, weirdly enough:

Equation from the original notes

So $N(d_1)$ is the cumulative probability of getting a value below $d_1$ from the standard normal distribution.

But then what? T_T Because I genuinely don’t know what $d_1$ and $d_2$ are actually supposed to represent T_T

For now I just have to hold onto it and remember it like this… T_T T_T T_T

Equation from the original notes

(Heads up: this screenshot was generated before the d1 fix above — the original code was missing the parentheses around v*math.sqrt(T) (Python reads d1 / v*math.sqrt(T) as (d1/v)*sqrt(T), not d1/(v*sqrt(T))), so the numbers in this image are off by a factor of T. Trust the corrected code above, not the screenshot. T_T)

Equation from the original notes

Equation from the original notes

import numpy as np
import scipy as sp
import scipy.stats
import math
import matplotlib.pyplot as plt
import os
path = r'C:\Users\GD Park\Desktop\financial-engineering'
os.chdir(path)
def BS_Formula(S=800, k=850, r=0.05, T=0.5, v=0.2):
    d1 = math.log(S/k) + (r + (v*v)*0.5)*T
    d1 = d1 / (v*math.sqrt(T))
    d2 = d1 - v*math.sqrt(T)
    norm = sp.stats.norm(loc=0, scale=1)
    c = S*norm.cdf(d1) - k*math.exp(-r*T)*norm.cdf(d2)
    p = k*math.exp(-r*T)*norm.cdf(-d2) - S*norm.cdf(-d1)
    return c, p
SS = np.linspace(700, 900, 1000)
C = np.zeros(len(SS))
P = np.zeros(len(SS))
for i in range(len(SS)):
    C[i], P[i] = BS_Formula(S=SS[i])
plt.figure(figsize=(6, 4))
plt.plot(SS, C)
plt.xlabel('S')
plt.ylabel('Price')
plt.title('BS_Formula_c')
plt.savefig('BS_Formula_c', dpi=200)
plt.figure(figsize=(6, 4))
plt.plot(SS, P)
plt.xlabel('S')
plt.ylabel('Price')
plt.title('BS_Formula_p')
plt.savefig('BS_Formula_p', dpi=200)

Comments

Discussion happens via GitHub Discussions. You'll need a GitHub account to comment.