Tuesday, June 11, 2013

Compound Option Sharp Monte Carlo


function calculateMCCompoundOptionSSharp(oStart,oEnd,precision,BASE,X1,X2,r,sigma,q,T1,T2)
{
 xn=oStart;
 minValue=xn;
 minPrecision=888888888888;
 fxprev=0;
 counter=0;
 xn1=xn;
 xn2=0;
 basee=BASE*100;
 beginBase=0;
 xnOld=0;
 fxmOld=0
 while (counter<oEnd)
 {
  
  xn=Math.random()*basee+beginBase-0.5*basee;
  if (xn>0)
  {
   fxm1=CallBlackScholes(xn,X1,r,sigma,q,T2-T1,0)-X2;
   
   va=Math.abs(fxm1);
   if (va <= precision)
   {
    
    return xn;
   }
   if (minPrecision>va)
   {
    minPrecision=va;
    minValue=xn;
   }
   if (counter>0)
   {
    if (Math.abs(fxm1)<Math.abs(fxmOld))
    {
     beginBase=xn;
     basee=beginBase*0.1;
    } 
    else
    {
     beginBase=xnOld;
     basee=beginBase*0.1;
    }
    
   }
   xnOld=xn;
   fxmOld=fxm1;
  }
  counter++;
  
 }
 
 
 return minValue;
 
}

function calculateLinCompoundOptionSSharp(oStart,oEnd,precision,BASE,X1,X2,r,sigma,q,T1,T2)
{
 xn=oStart;
 minValue=BASE;
 
 fxprev=0;
 counterade=0;
 xn1=xn;
 xn2=0;
 basee=BASE*100;
 beginBase=0;
 xnOld=0;
 fxmOld=0;
 maxvalue=BASE;
 if (maxvalue<X1)
  maxvalue=X1;
 if (maxvalue<X2)
  maxvalue=X2;
 mratio=5*maxvalue/oEnd;
 minPrecision=maxvalue*100000;
 while (counterade<oEnd)
 {
  po=counterade;
  xn=po*mratio;
  if (xn>0)
  {
   fxm1=CallBlackScholes(xn,X1,r,sigma,q,T2-T1,0)-X2;
   if (isNaN(fxm1))
   {
    counterade=counterade+1;
    continue;
   }
   va=Math.abs(fxm1);
   if (va <= precision)
   {
    
    return xn;
   }
   if (!isNaN(va)&&minPrecision>va )
   {
    
    minPrecision=va;
    minValue=xn;
   }
   
  }
  counterade=counterade+1;
  
 }
 
 
 return minValue;
 
}

function e(val){
 return Math.exp(val);
}
function exp(val){
 return e(val);
}
function N2(a,b,r)
{
 return CumulativeBivariateNormal(a,b,r);
}
function N(a)
{
 return NCDF2(a);
}

function CallCallCompoundOption(S,X1,X2,r,sigma,q,T1,T2)
{
 sigma2=sigma*sigma;
 //search bossvalue
 Base=S;
 if (X1>Base)
 Base=X1;
 if (X2>Base)
 Base=X2;
 Sb=calculateLinCompoundOptionSSharp(0,9999,0.1,S,X1,X2,r,sigma,q,T1,T2);
 a1=(ln(S/Sb)+(r-q+0.5*sigma2)*T1)/(sigma*Math.sqrt(T1));
 a2=a1-sigma*Math.sqrt(T1);
 b1=(ln(S/X2)+(r-q+0.5*sigma2)*T2)/(sigma*Math.sqrt(T2));
 b2=b1-(sigma*Math.sqrt(T2));
 return S*e(-q*T2)*N2(a1,b1,Math.sqrt(T1/T2))-X2*e(-r*T2)*N2(a2,b2,Math.sqrt(T1/T2))-X1*e(-r*T1)*N(a2);
}

function CallPutCompoundOption(S,X1,X2,r,sigma,q,T1,T2)
{
 sigma2=sigma*sigma;
 //search bossvalue
 Base=S;
 if (X1>Base)
 Base=X1;
 if (X2>Base)
 Base=X2;
 Sb=calculateLinCompoundOptionSSharp(0,9999,0.1,S,X1,X2,r,sigma,q,T1,T2);
 
 a1=(ln(S/Sb)+(r-q+0.5*sigma2)*T1)/(sigma*Math.sqrt(T1));
 a2=a1-sigma*Math.sqrt(T1);
 b1=(ln(S/X2)+(r-q+0.5*sigma2)*T2)/(sigma*Math.sqrt(T2));
 b2=b1-(sigma*Math.sqrt(T2));
 return S*e(-q*T2)*N2(a1,-b1,-Math.sqrt(T1/T2))-X2*e(-r*T2)*N2(a2,-b2,-Math.sqrt(T1/T2))+X1*e(-r*T1)*N(a2);
}
function PutCallCompoundOption(S,X1,X2,r,sigma,q,T1,T2)
{
 sigma2=sigma*sigma;
 //search bossvalue
 Base=S;
 if (X1>Base)
 Base=X1;
 if (X2>Base)
 Base=X2;
 Sb=calculateLinCompoundOptionSSharp(0,9999,0.1,S,X1,X2,r,sigma,q,T1,T2);
 
 a1=(ln(S/Sb)+(r-q+0.5*sigma2)*T1)/(sigma*Math.sqrt(T1));
 a2=a1-sigma*Math.sqrt(T1);
 b1=(ln(S/X2)+(r-q+0.5*sigma2)*T2)/(sigma*Math.sqrt(T2));
 b2=b1-(sigma*Math.sqrt(T2));
 return X2*e(-r*T2)*N2(-a2,b2,-Math.sqrt(T1/T2))-S*e(-q*T2)*N2(-a1,b1,-Math.sqrt(T1/T2))+X1*e(-r*T1)*N(-a2);
}
function PutPutCompoundOption(S,X1,X2,r,sigma,q,T1,T2)
{
 sigma2=sigma*sigma;
 //search bossvalue
 Base=S;
 if (X1>Base)
 Base=X1;
 if (X2>Base)
 Base=X2;
 Sb=calculateLinCompoundOptionSSharp(0,9999,0.1,S,X1,X2,r,sigma,q,T1,T2);
 
 a1=(ln(S/Sb)+(r-q+0.5*sigma2)*T1)/(sigma*Math.sqrt(T1));
 a2=a1-sigma*Math.sqrt(T1);
 b1=(ln(S/X2)+(r-q+0.5*sigma2)*T2)/(sigma*Math.sqrt(T2));
 b2=b1-(sigma*Math.sqrt(T2));
 return X2*e(-r*T2)*N2(-a2,-b2,Math.sqrt(T1/T2))-S*e(-q*T2)*N2(-a1,-b1,Math.sqrt(T1/T2))-X1*e(-r*T1)*N(-a2);
}

No comments: