I am struggling with implementing trinomial tree in Python. I have found very nice solution (and vectorized version) for binomial tree and I am trying to change it for a trinomial case.
Here is what I've got:
def Trinomial(type, S0, K, r, sigma, T, N=2000):
import numpy as np
t = float(T) / N
#fixed lambda
lam = np.sqrt(5)
# up and down factor will be constant for the tree so we calculate outside the loop
u = np.exp(lam * sigma * np.sqrt(t))
d = 1.0 / u
#to work with vector we need to init the arrays using numpy
fs = np.asarray([0.0 for i in xrange(2*N + 1)])
#we need the stock tree for calculations of expiration values
fs2 = np.asarray([(S0 * u**j) for j in xrange(-N, N+1)])
#we vectorize the strikes as well so the expiration check will be faster
fs3 =np.asarray( [float(K) for i in xrange(2*N + 1)])
#formulas, that can be found in the pdf document
a = np.exp(r*t/2.0)
b = np.exp(-sigma * np.sqrt(t/2.0))
c = np.exp(sigma * np.sqrt(t/2.0))
p_u = ( ( a - b ) / ( c - d ) )**2
p_d = ( ( c - a ) / ( c - b ) )**2
p_m = 1 - p_u - p_d
# Compute the leaves, f_{N, j}
if type =="C":
fs[:] = np.maximum(fs2-fs3, 0.0)
else:
fs[:] = np.maximum(-fs2+fs3, 0.0)
#calculate backward the option prices
for i in xrange(N-1, -1, -1):
fs[:-1] = np.exp(-r * t) * (p_u * fs[1:] + p_d * fs[:-1] + p_m*fs[-1])
return fs[0]
Of course, it dosen't work as intended, for example a call
print Trinomial("C",100, 100, 0.1, 0.1, 5, 3)
Should output something between 39 and 40.
I am most concerned about lines:
fs2 = np.asarray([(S0 * u**j) for j in xrange(-N, N+1)])
and
fs[:-1] = np.exp(-r * t) * (p_u * fs[1:] + p_d * fs[:-1] + p_m*fs[-1])
I'm not sure if I'm populating initial tree correctly, and I'm 100% sure, that reverse computing option price is not working. I don't know how to implement formula [10] from pdf I linked at the beginning.
Maybe it can't be done on a vectorized version, but I tried with simple tree and failed aswell.
I'm not using binomial or BS price in this case, because my assigment is to do it with trinomial tree.