Skip to content

Instantly share code, notes, and snippets.

@jdunkerley
Last active April 27, 2021 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdunkerley/323b0d1d2a9b7f96d570778402389566 to your computer and use it in GitHub Desktop.
Save jdunkerley/323b0d1d2a9b7f96d570778402389566 to your computer and use it in GitHub Desktop.
Barrier Pricer
from random import random
from math import sqrt, log, exp
def box_muller_rand():
while True:
x = random() * 2.0 - 1
y = random() * 2.0 - 1
d = x * x + y * y
if d < 1:
return x * sqrt(-2 * log(d) / d)
def create_path(initial, time, steps, volatility, risk_free):
dt = time / steps
sdt = sqrt(dt)
path = []
current = initial
for i in range(steps):
path.append(current)
current = current * exp((risk_free - 0.5 * volatility * volatility) * dt + volatility * sdt * box_muller_rand())
return path
def price_option(strike, spot, time, volatility, risk_free, call_or_put='c', knockin=None, knockout=None, simulations=2000, steps_per_unit = 365):
if knockin and knockout:
raise Exception("Unable to cope with 2 barriers!")
cp = 1 if call_or_put == 'c' else -1
premiums = []
for i in range(simulations):
path = create_path(spot, time, time * steps_per_unit, volatility, risk_free)
if knockin and knockin > spot and max(path) < knockin: # Up and In
premiums.append(0)
elif knockin and knockin < spot and min(path) > knockin: # Down and In
premiums.append(0)
elif knockout and knockout < spot and min(path) < knockin: # Down and Out
premiums.append(0)
elif knockout and knockout > spot and max(path) > knockout: # Up and Out
premiums.append(0)
else:
premiums.append(max(0, cp * (path[-1] - strike)))
return sum(premiums) / simulations * exp(-time * risk_free)
spot=100
strike=105
vol=0.2
risk_free=0.05
price_option(strike, spot, 1, vol, risk_free, simulations=50000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment