previous up next SYLLABUS  Previous: 4.4.1 Naive implementation using  Up: 4.4 Methods for European  Next: 4.5 Methods for European


4.4.2 Improved scheme using log-normal variables $ \spadesuit$


[ SLIDE scheme - BC/TC - interpolation - code - run || same VIDEO as previous section: modem - LAN - DSL)]


Instead of solving Black-Scholes (3.4#eq.4) with finite differences in the financial variables $ (S,t)$ , apply the transformations (4.3.1#eq.1, 4.3.1#eq.4) and solve the normalized equation (4.3.1#eq.5) with finite differences in log-normal variables $ (x,\tau)$ .
Apart from a numerical accuracy in $ \mathcal{O}(\Delta x^2)$ , which gets independent of the underlying value $ S$ , the transformation has the additional advantage of evolving the numerical solution everywhere at the same rate, so that the time step is everywhere limited by the condition for the normalized diffusion equation:

$\displaystyle \frac{\Delta \tau}{\Delta x^2}<\frac{1}{2}$ (4.4.2#eq.1)


The finite difference solution is extremely simple to calculate using a difference forward from the time level $ \tau$ (4.4.1#eq.1 since a scheme backward in $ t$ runs forward in $ \tau$ ) and a second derivative centered on $ x_j$ (4.4.1#eq.4):

$\displaystyle \frac{u_{j}^{\tau+\Delta\tau}-u_{j}^{\tau}}{\Delta \tau} -\frac{u_{j+1}^\tau-2u_j^\tau+u_{j-1}^\tau}{\Delta x^2}=0$ (4.4.2#eq.2)

$\displaystyle u_{j}^{\tau+\Delta\tau}=u_{j}^{\tau} + \Delta \tau \frac{u_{j+1}^\tau-2u_j^\tau+u_{j-1}^\tau}{\Delta x^2}$ (4.4.2#eq.3)


The only difficulty (which results in quite a bit of coding) is that the regular spacing $ x_j=j\Delta x$ assumed for the finite differencing becomes exponential in financial variable $ S=K\exp(x)$ . This is not a problem for the put and call options (exercise 4.08), since the terminal and boundary conditions are known explicitly in log-normal variables
$\displaystyle u_\mathrm{put}(x,0)$ $\displaystyle =$ $\displaystyle \max\left(\exp\left[\frac{1}{2}(k_2-1)x\right]-
\exp\left[\frac{1}{2}(k_2+1)x\right],0\right)$ (4.4.2#eq.4)
$\displaystyle u_\mathrm{put}(x,\tau)$ $\displaystyle =$ $\displaystyle \left\{\begin{array}{ll}
\exp\left[\frac{1}{2}(k_2-1)x +\frac{1}{...
...&\quad x\rightarrow -\infty\\
0 &\quad x\rightarrow +\infty
\end{array}\right.$ (4.4.2#eq.5)


The transformation is however an additional source of imprecision when a general payoff from a binary option has first to be transformed from regularly spaced financial variables $ V(S_j,0)$ to log-normal variables on an inhomogeneous grid $ u(x_j,0)$ , before it is interpolated onto a regular grid $ u(x_j,0)$ using a linear approximation

$\displaystyle u(x)=u_{k-1} + (x-x_{k-1})\frac{u_k-u_{k-1}}{x_k-x_{k-1}}$ (4.4.2#eq.6)


The evolution can be calculated keeping only financial variables, but an interpolation is again needed when the solution is finally plotted in the financial world. This finally yields a rather clumsy scheme that has been implemented in the VMARKET class FDSolution.java
      double x0, x1, f0, f1, xk;                         //Change variables
      double tau = 0.5*sigmaSq*time;                     // f(x,t) ->
      double dtau= 0.5*sigmaSq*timeStep;                 //    fm(xk,tau)
      double xk0 = Math.log(x[1]/strike);                // lognormal mesh
      double xkn = Math.log(x[n]/strike);
      double dxk =(xkn-xk0)/(n-1);
      double k1  = 2*rate/sigmaSq; 
      double k2  = 2*(rate-divid)/sigmaSq; 
      double k2m1= k2-1.;
      double k2p1= k2+1.;
      int    j,k;
      //=== Interpolate only once from (x,t) to lognormal variables (xk,tau)
      if (time<=timeStep) {
        if(isPut) { //Initialize fm[] directly as put-option
          for (k=1; k<=n; k++) {
            xk=xk0+(k-1)*dxk;
            fm[k]=Math.max(0., Math.exp(0.5*k2m1*xk) -
                               Math.exp(0.5*k2p1*xk)  );
          }
        } else if (isCall) { //Left as an exercise
        } else { //Interpolate fm[] from IC in f[]
          j=1; ; x0=xk0;
          f0=f[1]/strike*Math.exp(0.5*k2m1*xk0);
          x1=x0; f1=f0;
          for (k=1; k<n; k++) { //Loop over lognormal mesh index
            xk=xk0+(k-1)*dxk;   // given xk, find x0,x1 | x[j] < xk < x[j+1]
            while (xk>=x1) { j++; x0=x1; f0=f1; x1=Math.log(x[j]/strike); }
            f1=f[j]/strike*Math.exp(0.5*k2m1*x1);
            fm[k]= f0 + (xk-x0)*(f1-f0)/(x1-x0);
          }
          fm[n]= fm[n-1] + dxk*(fm[n-1]-fm[n-2]);
        }
      } else { //Retrieve fm[] from previous time step
      }    
      //===== Solve diffusion equation with an explicit 2 levels scheme
      double D = dtau/(dxk*dxk);
      for (j=2; j<n; j++) 
        f[j]= fm[j] + D*(fm[j+1]-2.*fm[j]+fm[j-1]);
      if (isPut) {
        f[1]= Math.exp(0.5*k2m1*xk0+0.25*k2m1*k2m1*tau);
        f[n]= f[n-1];
        fp[0]=strike*Math.exp(-rate*time);
//    } else if (isCall) { //Left as an exercise
      } else {
        f[1]= f[2];
        f[n]= f[n-1];
        fp[0]=fp[1];
      }
      //===== Interpolate rest from lognormal to financial mesh variables
      k=1; x0=x[0]; x1=x0; f0=fp[0];
      xk=xk0; f1=f[1]*strike*Math.exp(-0.5*k2m1*xk-(0.25*k2m1*k2m1+k1)*tau);
      for (j=1; j<n; j++) { //Loop over financial mesh index
        while (x[j]>=x1){
          k++;x0=x1;f0=f1;xk=xk0+(k-1)*dxk;x1=strike*Math.exp(xk);}
        f1=f[k]*strike*Math.exp(-0.5*k2m1*xk-(0.25*k2m1*k2m1+k1)*tau);
        fp[j]= f0 +(x[j]-x0)/(x1-x0)*(f1-f0);              //Lin interpol in x
      }
      if (isPut) {
        fp[n]=f[n]*strike*Math.exp(-0.5*k2m1*xkn-(0.25*k2m1*k2m1+k1)*tau);
//    } else if (isCall) { //Left as an exercise
      } else {
        fp[0]=fp[1];
        fp[n]=fp[n-1];
      }
VMARKET applet:  press Start/Stop to calculate the price of a European put option V(S,t) using a log-normal discretization of the Black-Scholes equation with explicit finite differences up to 6 months before expiry. Note that the call option has not been implemented, since it is the subject of exercise 4.08.




Virtual market experiments: log-normal FD scheme
  1. Press Step 1 after initializing different payoffs to visualize the initial error induced by the interpolation to log-normal variables and back.
  2. Reduce the interpolation error by increasing MeshPoints; note that you then have to reduce TimeStep in agreement with (4.4.2#eq.1).
  3. Switch from European logn to European and compare the results from the naive scheme with the present one using log-normal variables.

SYLLABUS  Previous: 4.4.1 Naive implementation using  Up: 4.4 Methods for European  Next: 4.5 Methods for European