Sei sulla pagina 1di 3

MATH 60093 Monte Carlo Modeling

The Crank-Nicolson Finite Dierence Method


The idea behind nite dierence methods is to numerically solve a partial dierential equation (PDE) by
replacing the partial dierentials with nite dierences. Our focus is on the Black-Scholes PDE
@C 1 @2C @C
! = S 2 % 2 2 + (r ! ') S ! rC (1)
@t 2 @S @S
where C = C (t; S) is the price a nancial option, which depend on the underlying asset price S at time t:
We assume the (underlying) asset pays a continuous dividend yield of ' per annum. The parameters % is
the volatility of the asset and r is the continuously compounded riskless interest rate. This PDE governs
the price of all European and American options whose pay-o depends on the asset price S that follow the
risk-neutral geometric Brownian motion (GBM)
dS = (r ! ') Sdt + %Sdz:
We reformulate the PDE in (1) in terms of the natural logarithm of the asset price by letting x = ln (S) :
By applying Its lemma, the continuous time risk-neutral process for x can be shown to be
dx = -dt + %dz
where - = r ! ' ! 12 % 2 : In terms x = ln (S) ; we have
@C @C
S =
@S @x
and
@2C @2C @C
S2 = ! :
@S 2 @x2 @x
Therefore, the PDE in (1) becomes
@C 1 @2C @C
! = %2 2 + - ! rC: (2)
@t 2 @x @x
The PDE in (2) is a PDE with constant coecients. It makes the application of nite dierence methods
much easier.
When implementing nite dierence methods, we imagine time and space (i.e. the asset price) are divided
up into discrete intervals whose widths are 4t and 4x; respectively. We let i be the time step and j be
the level of the asset price relative to the initial asset price S0 (we denote S0 by S in the algorithm below).
Hence, at each node (i; j) on the grid, we have time t = i4t; and the asset
! price Sj"= S0 ej4x : We represent
the value of an option at node (i; j) by Ci;j : In other words, Ci;j = C i4t; S0 ej4x : The nal time step N
corresponds to the maturity date of the option, i.e. T = N 4t: We consider the grid where
i = 0; 1; 2; :::; N
and
j = !M; !M + 1; :::; !1; 0; 1; :::; M ! 1; M:
Note that the textbook (Clewlow and Strickland) uses the notation N j instead of M: The values of the
option at the nal time step are determined by its payo, for example for call option
CN;j = max (0; Sj ! K)
where K is the strike price of the option.
For Crank-Nicolson method, we discretize the PDE in (2) into the following nite dierence equation
# $
Ci+1;j ! Ci;j 1 2 (Ci+1;j+1 ! 2Ci+1;j + Ci+1;j"1 ) + (Ci;j+1 ! 2Ci;j + Ci;j"1 )
! = % (3)
4t 2 24x2
# $
(Ci+1;j+1 ! Ci+1;j"1 + Ci+1;j"1 ) + (Ci;j+1 ! Ci;j"1 )
+-
44x
% &
Ci+1;j + Ci;j
!r
2

1
We may rewrite equation (3) as
pu Ci;j+1 + pm Ci;j + pd Ci;j"1 = !pu Ci+1;j+1 ! (pm ! 2) Ci+1;j ! pd Ci+1;j"1 (4)
where
% &
1 %2 -
pu = ! 4t +
4 4x2 4x
2
% r4t
pm = 1 + 4t 2
+
24x 2
% 2 &
1 % -
pd = ! 4t !
4 4x2 4x
By working backward in time, the right-hand side of equation (4) is made up of known option values and
the known constant coecients pu ; pm and pd : Therefore, the right-hand side of the equation (4) can be
considered as a known constant.
Each equation (4) for j = !M + 1; :::; M ! 1 cannot be solved individually for the option values at time
step i. Instead, they must be considered, together with the boundary conditions,
Ci;M ! Ci;M "1 = 6U
Ci;"M +1 ! Ci;"M = 6L
to be a system of 2M + 1 linear equations which implicitly determine the 2M + 1 option values at time step
i:
The boundary condition parameters 6U and 6L are determined by the type of option being valued. For
example, for valuing call option, we have
6U = SM ! SM "1
6L = 0
For put option, we have
6U = 0
6L = S"M ! S"M +1
The set of equations in (4) makes up a tridiagonal system of linear equations for each xed time index i:
0 10 1
1 !1 0 ::: ::: ::: 0 Ci;M
B pu p m pd 0 ::: ::: 0 C B C
B C B Ci;M "1 C
B 0 p p p 0 ::: 0 C B C C
B u m d C B i;M "2 C
B ::: ::: ::: ::: ::: ::: ::: C B ::: C
B CB C
B 0 ::: 0 p p p 0 C B C C
B u m d C B i;"M +2 C
@ 0 ::: ::: 0 pu pm pd A @ Ci;"M +1 A
0 ::: ::: ::: 0 1 !1 Ci;"M
0 1
6U
B !pu Ci+1;M ! (pm ! 2) Ci+1;M "1 ! pd Ci+1;M "2 C
B C
B !pu Ci+1;M "1 ! (pm ! 2) Ci+1;M "2 ! pd Ci+1;M "3 C
B C
B
= B ::: C
C
B !pu Ci+1;"M +3 ! (pm ! 2) Ci+1;"M +2 ! pd Ci+1;"M +1 C
B C
@ !pu Ci+1;"M +2 ! (pm ! 2) Ci+1;"M +1 ! pd Ci+1;"M A
6L
which can be solved eciently.

The pseudo-code implementation of the Crank-Nicolson nite dierence method for pricing an American
put option is given below. In our implementation, we have introduced a storage eciency improvement. The
option value array C[i,j] only has two time indices, namely i=0,1. The time index i=1 is used to temporar-
ily store the discounted expectation. The boundary conditions and early exercise test store the appropriate
value in the time index i=0. The range of space index remained to be j=-M,-M+1,...,-1,0,1,...,M-1,M.

2
ALGORITHM (American Put Option by the Crank-Nicolson Finite Dierence Method)
initialize_parameters { K, T, S, sig, r, div, N, M, dx }

{ precompute constants }
dt = T/N
nu = r - div - 0.5 * sig^2
edx = exp(dx)
pu = -0.25*dt*( (sig/dx)^2 + nu/dx )
pm = 1.0 + 0.5*dt*(sig/dx)^2 + 0.5*r*dt
pd = -0.25*dt*( (sig/dx)^2 - nu/dx )

{ initialize asset prices at maturity }


St[-M] = S*exp(-M*dx)
for j = -M+1 to M do St[j] = St[j-1]*edx

{ initialize option values at maturity }


for j = -M to M do C[0,j] = max( 0 , K-St[j] )

{ compute boundary condition }


lambda_L = St[-M] - St[-M+1]
lambda_U = 0.0

{ step back through lattice }


for i = N-1 downto 0 do
solve_Crank_Nicolson_system( C, pu, pm, pd, lambda_L, lambda_U )
{ apply early exeercise condition }
for j = -M to M do
C[0,j] = max( C[1,j] , K - St[j] )
next i

American_put = C[0,0]
{ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
subroutine solve_Crank_Nicolson_system( C, pu, pm, pd, lambda_L, lambda_U )

{ substitute boundary condition at j = -M into j = -M+1 }


pmp[-M+1] = pm + pd
pmp[-M+1] = -pu*C[0,-M+2]-(pm-2)*C[0,-M+1]-pd*C[0,-M] + pd*lambda_L

{ eliminate upper diagonal }


for j = -M+2 to M-1 do
pmp[j] = pm - pu*pd/pmp[j-1]
pp[j] = -pu*C[0,j+1]-(pm-2)*C[0,j]-pd*C[0,j-1]-pp[j-1]*pd/pmp[j-1]
next j

{ use boundary condition at j = M and equation at j = M-1 }


C[1,M] = (pp[M-1] + pmp[M-1]*lambda_U)/(pu + pmp[M-1])
C[1,M-1] = C[1,M] - lambda_U

{ back-substitution }
for j = M-2 downto -M+1 do
C[i,j] = ( pp[j] - pu*C[1,j+1] )/pmp[j]
next j

C[1,-M] = C[1,-M+1] - lambda_L


return

Potrebbero piacerti anche