Skip to content

Instantly share code, notes, and snippets.

@rgardner
Created July 8, 2014 14:49
Show Gist options
  • Save rgardner/18c50b5ee0e0d08af896 to your computer and use it in GitHub Desktop.
Save rgardner/18c50b5ee0e0d08af896 to your computer and use it in GitHub Desktop.
Bermudan Swaptions
# Leif Andersen - A simple Approach to the pricing of Bermudan swaptions
# in the multifactor LIBOR market model - 1999 - Journal of computational finance.
# Replication of Table 1 p. 16 - European Payer Swaptions.
import util
B = util.Benchmark()
if B.bohrium:
import bohrium as np
else:
import numpy as np
verbose = False # Set to true to output the computed prices
N = B.size[0] # Number of paths.
B.start()
delta = 0.5 # Parameter values.
f_0 = 0.06
theta = 0.06
# Start dates for a series of swaptions.
Ts_all = [[1,2,3],[2,3,4],[5,6,7,8,9],[10,12,14,16,18]]
# End dates for a series of swaptions.
Te_all = [4,5,10,20]
# Parameter values for a series of swaptions.
lamb_all = [0.2,0.2,0.15,0.1]
# Container for the value and std for the series of swaptions.
swaptions = np.zeros((2,1))
# Auxiliary function.
def mu(F):
tmp = lamb*(delta*F[1:,:])/(1+delta*F[1:,:]) # Andreasen style
mu = np.zeros((tmp.shape))
mu[0,:] +=tmp[0,:]
for i in xrange(mu.shape[0]-1):
mu[i+1,:] = mu[i,:] + tmp[i+1,:]
return mu
# Range over a number of independent products
for i in xrange(len(Te_all)):
Te = Te_all[i]
lamb = lamb_all[i]
Ts = Ts_all[i]
for ts in Ts:
time_structure = np.arange(0,ts+delta,delta)
maturity_structure = np.arange(0,Te,delta)
############### MODEL #######################
# Variance reduction technique - Antithetic Variates.
eps_tmp = np.random.normal(loc = 0.0, scale = 1.0, size = ((len(time_structure)-1),N))
eps = np.concatenate((eps_tmp,-eps_tmp), axis = 1)
# Forward LIBOR rates for the construction of the spot measure.
F_kk = np.zeros((len(time_structure),2*N))
F_kk[0,:] += f_0
# Plane kxN of simulated LIBOR rates.
F_kN = np.ones((len(maturity_structure),2*N))*f_0
# Simulations of the plane F_kN for each time step.
for t in xrange(1,len(time_structure),1):
F_kN_new = np.ones((len(maturity_structure)-t,2*N))
F_kN_new = F_kN[1:,:]*np.exp(lamb*mu(F_kN)*delta-0.5*lamb*lamb*delta+lamb*eps[t-1,:]*np.sqrt(delta))
F_kk[t,:] = F_kN_new[0,:]
F_kN = F_kN_new
############### PRODUCT #####################
# Value of zero coupon bonds.
zcb = np.ones((int((Te-ts)/delta)+1,2*N))
for j in xrange(len(zcb)-1):
zcb[j+1,:] = zcb[j,:]/(1+delta*F_kN[j,:])
# Swaption price at maturity.
swap_Ts = np.maximum(1-zcb[-1,:]-theta*delta*np.sum(zcb[1:,:], axis = 0),0)
# Spot measure used for discounting.
B_Ts = np.ones((2*N))
for j in xrange(int(ts/delta)):
B_Ts *= (1+delta*F_kk[j,:])
# Swaption price at time 0.
swaption = swap_Ts/B_Ts
# Save expected value in bps and std.
swaptions = np.append(swaptions,[[np.average( (swaption[0:N] + swaption[N:])/2) *10000],\
[np.std((swaption[0:N] + swaption[N:])/2)/np.sqrt(N)*10000]], axis=1)
B.stop()
B.pprint()
if verbose: # Print values.
k=1
for i in xrange(len(Te_all)):
Te = Te_all[i]
Ts = Ts_all[i]
for j in xrange(len(Ts)):
print "Ts %i" %Ts[j] + " Te %i " %Te + " price %.2f" % swaptions[0,k]\
+ "(%.2f)" %swaptions[1,k]
k +=1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment