
The nice approach proposed by Surkov is built on the fact that instead of computing the convolution and get the expectation in one step, one can divide the time and perform a serie of convolutions. One obviously needs to adjust the characteristic function.
From a computational point of view this is slower but we can check early exercise at these steps. Globally speaking we go to the Fourier space, perform product, inverse the fourier transform. This gives us option prices for that time step, we calculate early exercise as for the pde or the tree.
Then we perform another step: fourier transform, convolution, inverse transform. We do so until we reach now (we go backward in time, one step at the time)
The code is straightforward:
- def FourierST2(option,params):
- N=params.NAS
- NTS=params.NTS
- [S0,K,sigma,T,r,divi,american]=[option.S0,option.K,option.sigma,option.T,option.r,option.divi,option.american]
- j=complex(0,1)
- #create vector in the real space
- x_min = -7.5
- x_max = 7.5
- dx=(x_max-x_min)/(N-1)
- x=np.array([(dx*i+x_min) for i in range(N+1)])
- #create vector in the fourier space
- w_max=np.pi/dx;
- dw=2*w_max/(N);
- w1=np.array([(dw*i) for i in range(N/2+1)])
- w2=np.array([(dw*i-w_max) for i in range(N/2)])
- w=np.concatenate((w1,w2))
- # Option payoff
- s = S0*np.exp(x);
- VC = np.maximum(s-K,0)
- VP = np.maximum(K-s,0)
- # FST method
- char_exp_factor = np.exp((j*(r-0.5*sigma**2)*w - 0.5*sigma**2*(w**2)-r)*T/NTS)
- for m in range(NTS):
- VC = np.real(np.fft.ifft(np.fft.fft(VC)*char_exp_factor))
- VC=earlyCall(VC,s,K)
- VP = np.real(np.fft.ifft(np.fft.fft(VP)*char_exp_factor))
- VP=earlyPut(VP,s,K)
- #Interpolate option prices
- tck=si.splrep(s,VC)
- option.call.price=si.splev(S0,tck,der=0)
- tck=si.splrep(s,VP)
- option.put.price=si.splev(S0,tck,der=0)
Aucun commentaire:
Enregistrer un commentaire