%
% Test weak convergence of Euler method
% for barrier and lookback options
%
% Test problem: dS = r*S dt + sig*S dW
%

clear all; close all
randn('state',0)

%
% problem parameters and exact solution
%

r   = 0.05; 
sig = 0.5; 
T   = 1; 
S0  = 100; 
K   = 110;
B   = 90;

Vb  = down_and_out_call(r,sig,T,S0,K,B,'value');
Vl  = lookback_call(r,sig,T,S0,'value');

%
% Monte Carlo simulation comparing to exact solution
%

if 1

M  = 1e+6;   % total number of Monte Carlo paths
M2 = 1e+4;   % number of paths at a time 

for p = 1:5
p
  N = 2^p;
  h = T/N;

  sum1 = 0;
  sum2 = 0;
  sum3 = 0;
  sum4 = 0;

  for m = 1:M2:M
    m2 = min(M2,M-m+1); 

    S  = S0*ones(1,m2);
    Mn = S;

    for n = 1:N
      dW = sqrt(h)*randn(1,m2);
      S  = S.*(1+r*h+sig*dW);
      Mn = min(Mn, S);
    end

    P    = exp(-r*T)*max(S-K,0)*0.5.*(sign(Mn-B)+1);
    sum1 = sum1 + sum(P);
    sum2 = sum2 + sum(P.^2);

    P    = exp(-r*T)*(S-Mn);
    sum3 = sum3 + sum(P);
    sum4 = sum4 + sum(P.^2);
  end

  hh(p) = h;

  V  = sum1/M;
  sd = sqrt((sum2/M - (sum1/M)^2)/(M-1));
  err1(p) = V-Vb;
  err2(p) = 3*sd;

  V  = sum3/M;
  sd = sqrt((sum4/M - (sum3/M)^2)/(M-1));
  err3(p) = V-Vl;
  err4(p) = 3*sd;
end

figure; pos=get(gcf,'pos'); pos(3:4)=pos(3:4).*[0.8 0.8]; set(gcf,'pos',pos);
loglog(hh,abs(err1),'b-*',hh,err2,'r-*')
title('Barrier weak convergence -- comparison to exact solution')
xlabel('h'); ylabel('Error');
legend(' Weak error',' MC error')
axis([.02 0.5 0.02 20])
print('-deps2c','lec10a.eps')

figure; pos=get(gcf,'pos'); pos(3:4)=pos(3:4).*[0.8 0.8]; set(gcf,'pos',pos);
loglog(hh,abs(err3),'b-*',hh,err4,'r-*')
title('Lookback weak convergence -- comparison to exact solution')
xlabel('h'); ylabel('Error');
legend(' Weak error',' MC error')
axis([.02 0.5 0.05 50])
print('-deps2c','lec10b.eps')

end

%
% Monte Carlo simulation comparing to 2h simulation
%

if 1

M  = 1e+5;   % total number of Monte Carlo paths
M2 = 1e+4;   % number of paths at a time 

for p = 1:7
p
  N = 2^p;
  h = T/N;

  sum1 = 0;
  sum2 = 0;
  sum3 = 0;
  sum4 = 0;

  for m = 1:M2:M
    m2 = min(M2,M-m+1); 

    S  = S0*ones(1,m2);
    S2 = S0*ones(1,m2);
    Mn  = S;
    Mn2 = S2;

    for n = 1:N/2
      dW1 = sqrt(h)*randn(1,m2);
      S   = S.*(1+r*h+sig*dW1);    
      Mn  = min(Mn,S);

      dW2 = sqrt(h)*randn(1,m2);
      S   = S.*(1+r*h+sig*dW2);
      Mn  = min(Mn,S);

      S2  = S2.*(1+r*2*h+sig*(dW1+dW2));
      Mn2 = min(Mn2,S2);
    end

    P    = exp(-r*T)*max(S-K,0)*0.5.*(sign(Mn-B)+1);
    P2   = exp(-r*T)*max(S2-K,0)*0.5.*(sign(Mn2-B)+1);
    sum1 = sum1 + sum(P-P2);
    sum2 = sum2 + sum((P-P2).^2);

    P    = exp(-r*T)*(S-Mn);
    P2   = exp(-r*T)*(S2-Mn2);
    sum3 = sum3 + sum(P-P2);
    sum4 = sum4 + sum((P-P2).^2);
  end

  hh(p) = h;

  Vd = sum1/M;
  sd = sqrt((sum2/M - (sum1/M)^2)/(M-1));
  err1(p) = Vd;
  err2(p) = 3*sd;

  Vd = sum3/M;
  sd = sqrt((sum4/M - (sum3/M)^2)/(M-1));
  err3(p) = Vd;
  err4(p) = 3*sd;
end

figure; pos=get(gcf,'pos'); pos(3:4)=pos(3:4).*[0.8 0.8]; set(gcf,'pos',pos);
loglog(hh,abs(err1),'b-*',hh,err2,'r-*')
title('Barrier weak convergence -- difference from 2h approximation')
xlabel('h'); ylabel('Error');
legend(' Weak error',' MC error')
axis([.005 0.5 0.02 5])
print('-deps2c','lec10c.eps')

figure; pos=get(gcf,'pos'); pos(3:4)=pos(3:4).*[0.8 0.8]; set(gcf,'pos',pos);
loglog(hh,abs(err3),'b-*',hh,err4,'r-*')
title('Lookback weak convergence -- difference from 2h approximation')
xlabel('h'); ylabel('Error');
legend(' Weak error',' MC error')
axis([.005 0.5 0.01 10])
print('-deps2c','lec10d.eps')

end
