Skip to content

Instantly share code, notes, and snippets.

@erwinvaneyk
Last active December 23, 2015 04:39
Show Gist options
  • Save erwinvaneyk/6581462 to your computer and use it in GitHub Desktop.
Save erwinvaneyk/6581462 to your computer and use it in GitHub Desktop.
Simple "Binomial Non-Arbitrage Pricing model (BNPM)" simulator, based upon the first 2 paragraphs of the book of Steven Shreve.
# A simple "Binomial Non-Arbitrage Pricing model (BNPM)" simulator. Requires python 2.x
import sys;
steps = ("--steps" in sys.argv); # if --steps is included, BNPM.py will show all V-values.
PUT = "p"; CALL = "c";
class Stock:
tail = head = None;
val = -1.0;
period = 0;
def __init__(self,price):
self.price = price;
def delta(self):
return (self.head.val-self.tail.val)/(self.head.price-self.tail.price);
def eval(self):
if self.val < 0.0:
p = float(((1.0+r)-(self.tail.price/self.price))/((self.head.price-self.tail.price)/self.price))
q = 1.0 - p
self.val = 1.0/(1.0+r)*(p*self.head.eval()+q*self.tail.eval());
if steps: print "V" + str(self.period) + ": " + str(self.val) + " with p = " + str(p) + ", q = " + str(q) + ", delta = " + str(self.delta()) + " and price = " + str(self.price);
return self.val
# input ###############
r = (1.0/4.0);
model = Stock(10.0);
u = d = None;
## If only the above is specified, BNPM.py will ask for up/down-factors.
model.head = Stock(20.0);
model.tail = Stock(5.0);
model.head.head = Stock(35.0);
model.head.tail = Stock(15.0);
model.tail.head = Stock(10.0);
model.tail.tail = Stock(2.5);
#######################
# Setup option
assert model
type = raw_input("(c)all or (p)ut?: ");
assert type == CALL or type == PUT;
K = float(raw_input("Strike price: "))
e = int(raw_input("Expiration time: "));
if not model.head and (u == None or d == None):
u = float(raw_input("up-factor: "));
d = float(raw_input("down-factor: "));
# find leafs of the model.
tmp = []; stocks = [model]; # starting point
for i in range(1,e+1):
for s in stocks:
assert s.head and s.tail;
if u is not None:
s.head = Stock(s.price * u)
s.tail = Stock(s.price * d)
s.head.period = s.tail.period = i;
tmp += [s.head,s.tail];
stocks = tmp;
tmp = [];
# Calculate Ve
for s in stocks:
s.val = max(s.price - K,0.0) if type == CALL else max(K - s.price,0.0);
if steps: print "V" + str(str(s.period)) + ": " + str(s.val) + " (leaf)";
if not steps: print "\nV0: " + str(model.eval()) + " and delta: " + str(model.delta());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment