Black-Scholes Formula
Can't derive Black-Scholes to save my life, but coding up the call and put pricing formula in VBA? That part's actually not hard at all.
The title is flashy, so let me cut to the chase real quick.
I cannot derive Black-Scholes!!! lol lol lol
If you came here to learn how the derivation works — please, leave, immediately, lol lol lol
I’m just gonna focus on coding the Black-Scholes model. That’s what this post is about.
So first, let me throw down the “Black-Scholes PDE (partial differential equation)” — yeah, the one that won the Nobel Prize in Economics.

That right there is the Black-Scholes partial differential equation, the Nobel-Prize-in-Economics one.
But — the formula I’m actually going to use here? Not that one.
The thing you can get by solving that PDE — using some seriously advanced math — is the Black-Scholes option pricing formula…
So really, the Black-Scholes option pricing formula is more like a Fields Medal kind of thing — the Fields Medal being the “Nobel of math,” not the actual Nobel —


Alright, so let’s run through the assumptions baked into the Black-Scholes model,
and then I’ll go ahead and crunch a call and a put using the formula above.
i) There is no arbitrage opportunity
(no way to make a riskless profit)
······· “no arbitrage opportunity”
ii) You can borrow and lend any amount
(even fractional, of cash, at the riskless rate)
······· any amount of cash, you can borrow or lend it, no problem
iii) You can buy and sell any amount
(even fractional, of cash, at the riskless rate)
······· buying or selling any amount of stock is also fine
iv) The above transactions don’t incur any fees or costs
······· no transaction costs, no fees (perfect market)
v) The rate of return on the riskless asset is constant
······· the riskless rate is a constant
vi) The stock price follows a geometric Brownian motion,
and we’ll assume its drift and volatility are constant
······· the stock price is Brownian, with drift and volatility taken as constants
(how should I think of “drift” here — like the current pulling the stock along, or the stock’s tendency to move? I’m not totally sure what to call it.)
Oh, and one more important thing in BS: you only need the volatility of the stock, not its expected return. That’s apparently the big insight… heh?
OK, now let’s just go ahead and
use the dang thing.
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
Deriving the formula is hard. Coding it once you have the formula? Not hard at all.
If you think real loosely about what $N(d_1)$ even is —
what $N(x)$ means is:

That’s the definition,
so it’s the probability that a standard normal $N(0,1)$ spits out a value less than or equal to $x$.
Then $N(d_1)$ is, like… weirdly:

The cumulative probability of getting a value less than or equal to that number is $N(d_1)$? OK?
But like… what does that even do for us T_T I don’t know what the numbers $d_1$ and $d_2$ actually mean T_T
For now I just gotta remember it like this,,, T_T T_T T_T



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)
Originally written in Korean on my Naver blog (2016-10). Translated to English for gdpark.blog.