46#define PI 3.14159265358979324
54 Real H1, H2, H3, R23, RUA, RUB, AR, RUC;
90 const ext::function<
Real(
Real)>& sigmaq) {
91 Real v0=0.0, v1=0.0, v1p=0.0, v2p=0.0, v2pp=0.0, gm=0.0;
93 Real tmp=0.0, e1=0.0, e2=0.0, e3=0.0, e4=0.0;
94 Real xstar=0.0, s0=0.0;
95 Real sigmat=0.0, disc=0.0, d1=0.0,d2=0.0,d3=0.0,d4=0.0;
96 Real et=0.0,tt=0.0, dt=0.0,p=0.0;
98 static double pi= 3.14159265358979324;
100 Real caux=0.0,ccaux=0.0;
102 Real x=0.0,
b=0.0,c=0.0;
107 gm=integalpha(taumin,taumax)/(0.5*integs(taumin,taumax));
120 xstar=log(kprice/hbarr);
122 if(xstar>0.0) xstar=0.0;
123 sigmat=integs(taumin,taumax);
124 disc=-integr(taumin,taumax);
140 d1=(xstar-log(s0)+(1.0-gm)*0.5*sigmat)/sqrt(sigmat);
141 d2=(xstar+log(s0)+(1.0-gm)*0.5*sigmat)/sqrt(sigmat);
142 d3=(xstar-log(s0)-(1.0+gm)*0.5*sigmat)/sqrt(sigmat);
143 d4=(xstar+log(s0)-(1.0+gm)*0.5*sigmat)/sqrt(sigmat);
150 v0=kprice*e1-kprice*std::pow(s0,(1.0-gm))*e2;
151 v0=
v0+exp(gm*0.5*sigmat)*(-hbarr*s0*e3+hbarr*std::pow(s0,-gm)*e4);
154 if(iord==0)
return v0;
167 dt=(taumax-taumin)/
double(npoint);
169 tt=0.5*integs(taumin,taumax);
172 et=exp(0.5*(1.0-gm)*x);
174 dsqpi=std::pow(pi,0.5);
177 for( i=1;i<=npoint;i++) {
179 tmp=taumin+dt*double(2*i-1)*0.5;
180 p=0.5*integs(tmp,taumax);
186 ccaux=
v(p,tt,x,xstar,gm)+
v(p,tt,x,-xstar,gm)-
v(p,tt,-x,xstar,gm)-
v(p,tt,-x,-xstar,gm);
187 auxnew=ccaux*(-kprice*exp(-xstar*0.5*(1.0-gm))+hbarr*exp(xstar*0.5*(1.0+gm)));
196 ccaux=llold(p,tt,x,
b,c,gm)-llold(p,tt,-x,
b,c,gm);
197 auxnew=kprice*(1.0-gm)*ccaux;
202 ccaux=llold(p,tt,x,
b,c,gm)-llold(p,tt,-x,
b,c,gm);
203 auxnew=-exp(gm*p)*hbarr*ccaux;
208 ccaux=llold(p,tt,x,
b,c,gm)-llold(p,tt,-x,
b,c,gm);
209 auxnew=exp(gm*p)*hbarr*gm*ccaux;
217 auxnew=-kprice*(1.0-gm)*(ff(p,tt,x,
b,gm)-ff(p,tt,-x,
b,gm));
221 auxnew=-exp(gm*p)*gm*hbarr*(ff(p,tt,x,
b,gm)-ff(p,tt,-x,
b,gm));
224 v1=v1+(
alpha(tmp)-gm*0.5*sigmaq(tmp))*v1p;
227 v1=exp(disc)*et*v1*dt/(dsqpi*2.0);
229 if(iord==1)
return v0+v1;
239 Real v2,dtp, tmp1,
s,caux2;
242 for(i=1;i<=npoint;i++) {
244 tmp=taumin+dt*(double)(2*i-1)*0.5;
245 p=0.5*integs(tmp,taumax);
247 dtp=(taumax-tmp)/(
double)(npoint2);
249 for(j=1;j<=npoint2; j++) {
250 tmp1=tmp+dtp*(double)(2*j-1)*0.50;
251 s=0.50*integs(tmp1,taumax);
253 caux=dll(
s,p,tt,-x,-1.0+gm,-xstar,gm)-dll(
s,p,tt,x,-1.0+gm,-xstar,gm);
254 v2pp=caux*kprice*(1.0-gm);
256 caux=dll(
s,p,tt,-x,-1.0-gm,xstar,gm)-dll(
s,p,tt,x,-1.0-gm,xstar,gm);
257 v2pp=v2pp-exp(gm*
s)*hbarr*caux;
259 caux=dll(
s,p,tt,-x,1.0+gm,-xstar,gm)-dll(
s,p,tt,x,1.0+gm,-xstar,gm);
260 v2pp=v2pp+exp(gm*
s)*gm*hbarr*caux;
262 caux=+dvv(
s,p,tt,-x,xstar,gm)-dvv(
s,p,tt,x,xstar,gm);
263 caux=caux+(dvv(
s,p,tt,-x,-xstar,gm)-dvv(
s,p,tt,x,-xstar,gm));
264 caux2=hbarr*exp(0.5*(1.0+gm)*xstar)-kprice*exp(-0.5*(1.0-gm)*xstar);
265 v2pp=v2pp+caux2*caux;
267 caux=dff(
s,p,tt,-x,-1.0+gm,gm)-dff(
s,p,tt,x,-1.0+gm,gm);
268 v2pp=v2pp-(1.0-gm)*kprice*caux;
270 caux=dff(
s,p,tt,-x,1.0+gm,gm)-dff(
s,p,tt,x,1.0+gm,gm);
271 v2pp=v2pp-exp(gm*
s)*gm*hbarr*caux;
273 v2pp=v2pp*0.5*(1.0-gm);
275 caux=-ddll(
s,p,tt,-x,-1.0+gm,-xstar,gm)+ddll(
s,p,tt,x,-1.0+gm,-xstar,gm);
276 v2pp=v2pp+caux*kprice*(1.0-gm);
278 caux=-ddll(
s,p,tt,-x,-1.0-gm,xstar,gm)+ddll(
s,p,tt,x,-1.0-gm,xstar,gm);
279 v2pp=v2pp-exp(gm*
s)*hbarr*caux;
281 caux=-ddll(
s,p,tt,-x,1.0+gm,-xstar,gm)+ddll(
s,p,tt,x,1.0+gm,-xstar,gm);
282 v2pp=v2pp+exp(gm*
s)*gm*hbarr*caux;
284 caux=-ddvv(
s,p,tt,-x,xstar,gm)+ddvv(
s,p,tt,x,xstar,gm);
285 caux=caux+(-dvv(
s,p,tt,-x,-xstar,gm)+dvv(
s,p,tt,x,-xstar,gm));
286 caux2=hbarr*exp(0.5*(1.0+gm)*xstar)-kprice*exp(-0.5*(1-gm)*xstar);
288 v2pp=v2pp+caux2*caux;
290 caux=-ddff(
s,p,tt,-x,-1+gm,gm)+ddff(
s,p,tt,x,-1+gm,gm);
291 v2pp=v2pp-(1.0-gm)*kprice*caux;
293 caux=-ddff(
s,p,tt,-x,1.0+gm,gm)+ddff(
s,p,tt,x,1.0+gm,gm);
294 v2pp=v2pp-exp(gm*
s)*gm*hbarr*caux;
296 v2p=v2p+(
alpha(tmp1)-gm*0.5*sigmaq(tmp1))*v2pp;
299 v2=v2+v2p*(
alpha(tmp)-gm*0.5*sigmaq(tmp))*dtp;
302 v2=exp(disc)*et*v2*dt;
320 Real P0, P1, P2, P3, P4, P5, P6;
321 Real Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7;
322 Real P, EXPNTL, CUTOFF, ROOTPI, ZABS;
324 P0 = 220.2068679123761;
325 P1 = 221.2135961699311;
326 P2 = 112.0792914978709;
327 P3 = 33.91286607838300;
328 P4 = 6.373962203531650;
329 P5 = 0.7003830644436881;
330 P6 = 0.03526249659989109;
332 Q0 = 440.4137358247522;
333 Q1 = 793.8265125199484;
334 Q2 = 637.3336333788311;
335 Q3 = 296.5642487796737;
336 Q4 = 86.78073220294608;
337 Q5 = 16.064177579206950;
338 Q6 = 1.7556671631826420;
339 Q7 = 0.088388347648318440;
340 ROOTPI = 2.506628274631001;
341 CUTOFF = 7.071067811865475;
354 EXPNTL =exp(-ZABS*ZABS/2);
359 P = EXPNTL*((((((P6*ZABS + P5)*ZABS + P4)*ZABS + P3)*ZABS+ P2)*ZABS + P1)*ZABS + P0)/(((((((Q7*ZABS + Q6)*ZABS + Q5)*ZABS + Q4)*ZABS + Q3)*ZABS + Q2)*ZABS + Q1)*ZABS + Q0);
364 P = EXPNTL/(ZABS + 1/(ZABS + 2/(ZABS + 3/(ZABS + 4/(ZABS + 0.65)))))/ROOTPI;
367 if ( Z > 0 ) P = 1 - P;
389 Real ppi= 3.14159265358979324;
391 aa=-(
b*p-
b*tt+a)/std::pow(2.0*(tt-p),0.5);
393 caux=2.0*std::pow(ppi,0.5)*PHID(aa);
394 aa=
b*
b-(1.0-gm)*(1.0-gm);
396 phid=exp(-0.5*a*
b)*exp(aa*(tt-p))*caux;
411 aa=-(p*(a-
b)+
b*tt)/std::pow(2.0*p*tt*(tt-p),0.5);
414 aa=exp(std::pow((a-
b),2)/(4.0*tt))*exp(std::pow((1.0-gm),2)*tt/4.0)*std::pow(tt,0.5);
428 Real ppi= 3.14159265358979324;
431 xx=(-a+
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
432 yy=(-a+
b*tt+c)/std::pow(2.0*tt,0.5);
433 rho=std::pow((tt-p)/tt,0.5);
434 aa=
b*
b-(1.0-gm)*(1.0-gm);
436 caux=ND2(-xx,-yy,
rho);
438 bvnd=2.0*std::pow(ppi,0.5)*exp(-a*
b*0.5)*exp(aa*(tt-p))*caux;
457 double ppi= 3.14159265358979324;
459 Real aa,caux,caux1,caux2;
462 aa=(a*p+
b*(tt-p))/std::pow(2.0*p*tt*(tt-p),0.5);
465 aa=exp((a-
b)*(a-
b)/(4.0*tt))*exp(std::pow((1.0-gm),2)*tt/4.0)*std::pow(tt,0.5);
468 xx=(a*p+
b*(tt-p))/std::pow(2.0*tt*p*(tt-p),0.5);
469 yy=(a*
s+
b*(tt-
s))/std::pow(2.0*tt*
s*(tt-
s),0.5);
470 rho=std::pow((
s*(tt-p))/(p*(tt-
s)),0.5);
471 caux1=ND2(-xx,-yy,
rho);
475 aa=exp((a+
b)*(a+
b)/(4.0*tt))*exp(std::pow((1.0-gm),2)*tt/4.0)*std::pow(tt,0.5);
477 xx=(a*p-
b*(tt-p))/std::pow(2.0*tt*p*(tt-p),0.5);
478 yy=(a*
s-
b*(tt-
s))/std::pow(2.0*tt*
s*(tt-
s),0.5);
479 rho=std::pow((
s*(tt-p))/(p*(tt-
s)),0.5);
480 caux2=ND2(-xx,-yy,
rho);
482 result=(caux+caux1+caux2)/(2.0*std::pow(ppi,0.5));
494 Real aa,caux,caux1,caux2;
497 xx=(a-
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
498 caux=-PHID(xx)*exp(-0.5*a*
b);
500 xx=(a+
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
501 yy=(a+
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
502 rho=std::pow((tt-p)/(tt-
s),0.5);
503 caux1=ND2(-xx,-yy,
rho);
504 caux1=exp(0.5*a*
b)*caux1;
506 xx=(a-
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
507 yy=(a-
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
508 rho=std::pow((tt-p)/(tt-
s),0.5);
509 caux2=ND2(-xx,-yy,
rho);
510 caux2=exp(-0.5*a*
b)*caux2;
512 aa=exp((
b*
b-(1.0-gm)*(1.0-gm))*(tt-
s)/4.0);
514 result=(caux+caux1+caux2)*aa;
528 Real sigmarho[4],limit[4],epsi;
531 limit[1]=(a+
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
532 limit[2]=(a+
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
533 limit[3]=(a+
b*tt+c)/std::pow(2.0*tt,0.5);
534 sigmarho[1]=std::pow((tt-p)/(tt-
s),0.5);
535 sigmarho[2]=std::pow((tt-p)/tt,0.5);
536 sigmarho[3]=std::pow((tt-
s)/tt,0.5);
538 caux=exp(0.5*a*
b)*tvtl(0,limit,sigmarho,epsi);
540 limit[1]=(a-
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
541 limit[2]=(-a+
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
542 limit[3]=(-a+
b*tt+c)/std::pow(2.0*tt,0.5);
543 sigmarho[1]=-std::pow((tt-p)/(tt-
s),0.5);
544 sigmarho[2]=-std::pow((tt-p)/tt,0.5);
545 sigmarho[3]=std::pow((tt-
s)/tt,0.5);
547 caux1=-exp(-0.5*a*
b)*tvtl(0,limit,sigmarho,epsi);
549 aa=exp((
b*
b-(1.0-gm)*(1.0-gm))*(tt-
s)/4.0);
552 result=(caux+caux1)*aa;
564 Real aa,caux,caux1,caux2,caux3,caux4;
567 double ppi= 3.14159265358979324;
569 xx=(a-
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
570 caux=PHID(xx)*exp(-0.5*a*
b);
572 xx=(a+
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
573 yy=(a+
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
574 rho=std::pow((tt-p)/(tt-
s),0.5);
575 caux1=ND2(-xx,-yy,
rho);
576 caux1=exp(0.5*a*
b)*caux1;
578 xx=(a-
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
579 yy=(a-
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
580 rho=std::pow((tt-p)/(tt-
s),0.5);
581 caux2=ND2(-xx,-yy,
rho);
582 caux2=-exp(-0.5*a*
b)*caux2;
584 caux=0.5*
b*(caux+caux1+caux2);
586 xx=(a+
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
587 yy=
b*std::pow((p-
s),0.5)/std::pow(2.0,0.5);
588 caux1=exp(-0.5*xx*xx)*exp(0.5*a*
b)*PHID(yy)/(2.0*std::pow(ppi*(tt-p),0.5));
591 xx=(a+
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
592 yy=a*std::pow((p-
s),0.5)/std::pow(2.0*(tt-p)*(tt-
s),0.5);
593 caux2=exp(-0.5*xx*xx)*exp(0.5*a*
b)*PHID(yy)/(2.0*std::pow(ppi*(tt-
s),0.5));
595 xx=(a-
b*(tt-p))/std::pow(2.0*(tt-p),0.5);
596 yy=
b*std::pow((p-
s),0.5)/std::pow(2.0,0.5);
597 caux3=-exp(-0.5*xx*xx)*exp(-0.5*a*
b)*PHID(yy)/(2.0*std::pow(ppi*(tt-p),0.5));
600 xx=(a-
b*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
601 yy=a*std::pow((p-
s),0.5)/std::pow(2.0*(tt-p)*(tt-
s),0.5);
602 caux4=exp(-0.5*xx*xx)*exp(-0.5*a*
b)*PHID(yy)/(2.0*std::pow(ppi*(tt-
s),0.5));
606 aa=exp((
b*
b-(1.0-gm)*(1.0-gm))*(tt-p)/4.0);
609 result=(caux+caux1+caux2+caux3+caux4)*aa;
621 static Real aa,caux,caux1;
622 static Real sigmarho[4],limit[4];
627 limit[1]=(ax+bx*(tt-p))/std::pow(2.0*(tt-p),0.5);
628 limit[2]=(ax+bx*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
629 limit[3]=(ax+bx*tt+c)/std::pow(2.0*tt,0.5);
630 sigmarho[1]=std::pow((tt-p)/(tt-
s),0.5);
631 sigmarho[2]=std::pow((tt-p)/tt,0.5);
632 sigmarho[3]=std::pow((tt-
s)/tt,0.5);
634 caux=0.5*bx*tvtl(0,limit,sigmarho,epsi);
638 caux=caux+derivn3(limit,sigmarho,idx)/std::pow(2.0*(tt-p),0.5);
641 caux=caux+derivn3(limit,sigmarho,idx)/std::pow(2.0*(tt-
s),0.5);
644 caux=caux+derivn3(limit,sigmarho,idx)/std::pow(2.0*tt,0.5);
646 caux=exp(0.5*ax*bx)*caux;
648 limit[1]=(ax-bx*(tt-p))/std::pow(2.0*(tt-p),0.5);
649 limit[2]=(-ax+bx*(tt-
s))/std::pow(2.0*(tt-
s),0.5);
650 limit[3]=(-ax+bx*tt+c)/std::pow(2.0*tt,0.5);
651 sigmarho[1]=-std::pow((tt-p)/(tt-
s),0.5);
652 sigmarho[2]=-std::pow((tt-p)/tt,0.5);
653 sigmarho[3]=std::pow((tt-
s)/tt,0.5);
655 caux1=0.5*bx*tvtl(0,limit,sigmarho,epsi);
658 caux1=caux1-derivn3(limit,sigmarho,idx)/std::pow(2.0*(tt-p),0.5);
661 caux1=caux1+derivn3(limit,sigmarho,idx)/std::pow(2.0*(tt-
s),0.5);
665 caux1=caux1+derivn3(limit,sigmarho,idx)/std::pow(2.0*tt,0.5);
667 caux1=exp(-0.5*ax*bx)*caux1;
670 aa=exp((bx*bx-(1.0-gm)*(1.0-gm))*(tt-
s)/4.0);
672 result=(caux+caux1)*aa;
684 static Real aa,caux,caux1,caux2,caux6;
685 static Real caux3,caux4,caux5,aux;
687 static double ppi= 3.14159265358979324;
689 aa=(a*p+
b*(tt-p))/std::pow(2.0*p*tt*(tt-p),0.5);
692 aa=exp(-(a-
b)*(a-
b)/(4.0*tt))/tt;
694 caux=0.5*aa*caux*(a-
b);
696 xx=(a*p+
b*(tt-p))/std::pow(2.0*tt*p*(tt-p),0.5);
697 yy=(a*
s+
b*(tt-
s))/std::pow(2.0*tt*
s*(tt-
s),0.5);
698 rho=std::pow((
s*(tt-p))/(p*(tt-
s)),0.5);
699 caux1=ND2(-xx,-yy,
rho);
700 caux1=-0.5*aa*caux1*(a-
b);
703 aa=exp(-(a+
b)*(a+
b)/(4.0*tt))/tt;
705 xx=(a*p-
b*(tt-p))/std::pow(2.0*tt*p*(tt-p),0.5);
706 yy=(a*
s-
b*(tt-
s))/std::pow(2.0*tt*
s*(tt-
s),0.5);
707 rho=std::pow((
s*(tt-p))/(p*(tt-
s)),0.5);
708 caux2=ND2(-xx,-yy,
rho);
709 caux2=-0.5*aa*caux2*(a+
b);
711 aa=-
b*std::pow((p-
s)/std::pow(2.0*p*
s,0.5),0.5);
712 aux=std::pow(p/(ppi*tt*(tt-p)),0.5)*PHID(aa);
714 xx=(a+
b)*(a+
b)/(4.0*tt);
715 yy=std::pow((a*p-
b*(tt-p)),2)/(4.0*p*tt*(tt-p));
716 caux3=aux*exp(-xx)*exp(-yy)/2.0;
719 xx=(a-
b)*(a-
b)/(4.0*tt);
720 yy=std::pow((a*p+
b*(tt-p)),2)/(4.0*p*tt*(tt-p));
721 caux4=aux*exp(-xx)*exp(-yy)/2.0;
723 aa=a*std::pow((p-
s)/std::pow(2.0*(tt-p)*(tt-
s),0.5),0.5);
724 aux=std::pow(
s/(ppi*tt*(tt-
s)),0.5)*PHID(aa);
726 xx=(a+
b)*(a+
b)/(4.0*tt);
727 yy=std::pow((a*
s-
b*(tt-
s)),2)/(4.0*
s*tt*(tt-
s));
728 caux5=aux*exp(-xx)*exp(-yy)/2.0;
730 xx=(a-
b)*(a-
b)/(4.0*tt);
731 yy=std::pow((a*
s+
b*(tt-
s)),2)/(4.0*
s*tt*(tt-
s));
732 caux6=aux*exp(-xx)*exp(-yy)/2.0;
734 aux=exp((1.0-gm)*(1.0-gm)*tt/4.0)*std::pow(tt,0.5);
736 result=(caux+caux1+caux2+caux3+caux4+caux5+caux6)/(aux*2.0*std::pow(ppi,0.5));
750 static double ppi= 3.14159265358979324;
752 sc=std::pow(2.0*ppi,0.5);
756 aa=exp(-0.5*std::pow(limit[1],2));
757 xx=(limit[3]-sigmarho[2]*limit[1])/std::pow((1.0-std::pow(sigmarho[2],2)),0.5);
758 yy=(limit[2]-sigmarho[1]*limit[1])/std::pow((1.0-std::pow(sigmarho[1],2)),0.5);
759 rho=(sigmarho[3]-sigmarho[1]*sigmarho[2])/std::pow((1.0-sigmarho[1]*sigmarho[1])*(1.0-sigmarho[2]*sigmarho[2]),0.5);
760 deriv=aa*ND2(-xx,-yy,
rho)/sc;
766 aa=exp(-0.5*limit[2]*limit[2]);
767 xx=(limit[1]-sigmarho[1]*limit[2])/std::pow((1.0-std::pow(sigmarho[1],2)),0.5);
768 yy=(limit[3]-sigmarho[3]*limit[2])/std::pow((1.0-std::pow(sigmarho[3],2)),0.5);
769 rho=(sigmarho[2]-sigmarho[1]*sigmarho[3])/ \
770 std::pow((1.0-sigmarho[1]*sigmarho[1])*(1.0-sigmarho[3]*sigmarho[3]),0.5);
771 deriv=aa*ND2(-xx,-yy,
rho)/sc;
776 aa=exp(-0.5*limit[3]*limit[3]);
778 xx=(limit[1]-sigmarho[2]*limit[3])/std::pow((1.0-std::pow(sigmarho[2],2)),0.5);
779 yy=(limit[2]-sigmarho[3]*limit[3])/std::pow((1.0-std::pow(sigmarho[3],2)),0.5);
780 rho=(sigmarho[1]-sigmarho[2]*sigmarho[3])/ \
781 std::pow((1.0-sigmarho[2]*sigmarho[2])*(1.0-sigmarho[3]*sigmarho[3]),0.5);
782 deriv=aa*ND2(-xx,-yy,
rho)/sc;
840 static Real ONE=1.0, ZRO=0.0, EPS, TVT;
841 static Real PT, R12, R13;
842 static double ppi= 3.14159265358979324;
843 EPS = max( 1.e-14, epsi );
856 if ( fabs(R12) > fabs(R13) ) {
863 if ( fabs(R13) > fabs(R23) ) {
871 if ( (fabs(H1) + fabs(H2) + fabs(H3)) < EPS ) TVT = ( 1 + ( asin(R12) + asin(R13) + asin(R23) )/PT )/8.0;
873 else if ( (NU < 1) && ( (fabs(R12) + fabs(R13)) < EPS) ) TVT = PHID(H1)*BVTL( NU, H2, H3, R23 );
875 else if ( (NU < 1) && ((fabs(R13) + fabs(R23))< EPS) ) TVT = PHID(H3)*BVTL( NU, H1, H2, R12 );
877 else if( (NU < 1) && ((fabs(R12) + fabs(R23))< EPS) ) TVT = PHID(H2)*BVTL( NU, H1, H3, R13 );
879 else if ( (1.0 - R23)< EPS ) TVT = BVTL( NU, H1, min( H2, H3 ), R12 );
881 else if ( (R23 + 1.0) <EPS ) {
882 if ( H2 > -H3 ) TVT = BVTL( NU, H1, H2, R12 ) - BVTL( NU, H1, -H3, R12 );}
888 if ( NU < 1 ) TVT = BVTL( NU, H2, H3, R23 )*PHID(H1);
890 else if ( R23 > 0 ) TVT = BVTL( NU, H1, min( H2, H3 ), ZRO );
892 else if ( H2 > -H3 ) TVT = BVTL( NU, H1, H2, ZRO ) - BVTL( NU, H1, -H3, ZRO );
901 RUC = SIGN( PT, AR ) - AR;
902 TVT = TVT + ADONET(ZRO, ONE, EPS, TVTMFN) / (4.0 * PT);
904 result = max( ZRO, min( TVT, ONE ) );
919 static Real R12=0.0, RR2=0, R13=0.0, RR3=0.0, R=0.0, RR=0.0;
920 const Real ZRO = 0.0;
923 SINCS( RUA*X, R12, RR2 );
924 SINCS( RUB*X, R13, RR3 );
926 if ( fabs(RUA)> 0 ) result += RUA*PNTGND( NUC, H1,H2,H3, R13,R23,R12,RR2);
927 if( fabs(RUB)>0 ) result += RUB*PNTGND( NUC, H1,H3,H2, R12,R23,R13,RR3 ) ;
930 SINCS( AR + RUC*X, R, RR );
931 result -= RUC*PNTGND( NUC, H2, H3, H1, ZRO, ZRO, R, RR );
944 PT = 1.57079632679489661923132169163975;
945 EE = std::pow(( PT - fabs(X) ),2);
949 SX = SIGN( 1 - EE*( 1 - EE/12 )/2, X );
950 CS = EE*( 1 - EE*( 1 - 2*EE/15 )/3 );
965 Real ADONET(
Real A,
Real B,
Real TOL,
Real(*TVTMFN)(
Real X,
Real H1,
Real H2,
Real H3,
Real R23,
Real RUA,
Real RUB,
Real AR,
Real RUC,
int NUC)){
969 int NL=100, I, IM, IP;
970 static Real EI[101], AI[101], BI[101], FI[101], FIN;
971 static Real result,ERR;
979 while ( ((4*ERR)> TOL) && (IM< NL) )
983 AI[IM] = (AI[IP] + BI[IP] )/2.0;
985 FI[IP] = KRNRDT( AI[IP], BI[IP], *TVTMFN, EI[IP] );
986 FI[IM] = KRNRDT( AI[IM], BI[IM], *TVTMFN, EI[IM] );
990 for(I = 1; I<=IM; I++)
992 if( EI[I] > EI[IP]) IP = I;
994 ERR = ERR + EI[I]*EI[I];
996 ERR = std::pow( ERR,0.5 );
1004 Real KRNRDT(
Real A,
Real B,
Real(*TVTMFN)(
Real X,
Real H1,
Real H2,
Real H3,
Real R23,
Real RUA,
Real RUB,
Real AR,
Real RUC,
int NUC),
Real& ERR ){
1009 static Real T, CEN, FC, WID, RESG, RESK;
1024 static Real WG[7], WGK[13], XGK[13];
1026 WG[1]= 0.2729250867779007;
1027 WG[2]=0.05566856711617449;
1028 WG[3]=0.1255803694649048;
1029 WG[4]=0.1862902109277352;
1030 WG[5]= 0.2331937645919914;
1031 WG[6]= 0.2628045445102478;
1033 XGK[1]= 0.0000000000000000;
1034 XGK[2]= 0.9963696138895427;
1035 XGK[3]= 0.9782286581460570;
1036 XGK[4]= 0.9416771085780681;
1037 XGK[5]= 0.8870625997680953;
1038 XGK[6]= 0.8160574566562211;
1039 XGK[7]= 0.7301520055740492;
1040 XGK[8]= 0.6305995201619651;
1041 XGK[9]= 0.5190961292068118;
1042 XGK[10]= 0.3979441409523776;
1043 XGK[11]= 0.2695431559523450;
1044 XGK[12]= 0.1361130007993617;
1046 WGK[1]=0.1365777947111183;
1047 WGK[2]=0.9765441045961290e-02;
1048 WGK[3]=0.2715655468210443e-01;
1049 WGK[4]=0.4582937856442671e-01;
1050 WGK[5]=0.6309742475037484e-01;
1051 WGK[6]=0.7866457193222764e-01;
1052 WGK[7]=0.9295309859690074e-01;
1053 WGK[8]=0.1058720744813894;
1054 WGK[9]=0.1167395024610472;
1055 WGK[10]=0.1251587991003195;
1056 WGK[11]=0.1312806842298057;
1057 WGK[12]=0.1351935727998845;
1068 WID = ( B - A )/2.0;
1069 CEN = ( B + A )/2.0;
1071 FC = TVTMFN(CEN,H1, H2, H3, R23, RUA, RUB, AR, RUC, NUC);
1076 for (J = 1; J<= N; J++)
1079 FC = TVTMFN(CEN-
T,H1, H2, H3, R23, RUA, RUB, AR, RUC, NUC )+TVTMFN(CEN+
T,H1, H2, H3, R23, RUA, RUB, AR, RUC, NUC );
1080 RESK = RESK + WGK[J+1]*FC;
1081 if((J-2*
int(J/2)) == 0 ) RESG = RESG + WG[1+J/2]*FC;
1084 ERR = fabs( WID*( RESK - RESG ) );
1095 static Real ZRO=0.0, ONE=1.0;
1096 static Real CSSTHE, SNTHE, POLYN, TT, TS, RN;
1100 if ( NU < 1 ) result= PHID(
T );
1101 else if ( NU == 1 ) result = ( 1 + 2.0*atan(
T)/
PI )/2.0;
1102 else if ( NU == 2 ) result = ( 1 +
T/std::pow(( 2.0 +
T*
T),0.5))/2.0;
1106 CSSTHE = 1/( 1 + TT/double(NU) );
1108 for( J = NU-2; J>= 2; J=J-2)
1110 POLYN = 1.0 + ( J - 1.0 )*CSSTHE*POLYN/(
double)J;
1112 if ((NU-2*
int(NU/2) ) == 1 )
1115 TS =
T/std::pow(RN,0.5);
1116 result = ( 1.0 + 2.0*( atan(TS) + TS*CSSTHE*POLYN )/
PI )/2.0;
1120 SNTHE =
T/std::pow(( NU + TT ),0.5);
1121 result = ( 1 + SNTHE*POLYN )/2.0;
1123 result = max( ZRO, min( result, ONE ) );
1158 static int J, HS, KS;
1159 static Real TPI, ORS, HRK, KRH, BVT, SNU;
1160 static Real GMPH, GMPK, XNKH, XNHK, QHRK, HKN, HPK, HKRN;
1161 static Real BTNCKH, BTNCHK, BTPDKH, BTPDHK, ONE, EPS;
1165 if ( NU <1 ) result = ND2( -DH, -DK, R );
1167 else if ( (1 - R)<= EPS ) result = STUDNT( NU, min( DH, DK ) );
1169 else if( (R + 1)<=EPS )
1171 if( DH > -DK ) result = STUDNT( NU, DH ) - STUDNT( NU, -DK );
1179 SNU = std::pow(SNU,0.5);
1183 if((fabs(HRK) + ORS)> 0 )
1185 XNHK = HRK*HRK/( HRK*HRK + ORS*( NU + DK*DK ) );
1186 XNKH = KRH*KRH/( KRH*KRH+ ORS*( NU + DH*DH ) );
1194 HS =(int)SIGN( ONE, DH - R*DK );
1195 KS =(int)SIGN( ONE, DK - R*DH );
1196 if((NU-2*(
int)(NU/2))==0 )
1198 BVT = atan2( std::pow(ORS,0.5), -R )/TPI;
1199 GMPH = DH/std::pow( 16*( NU + DH*DH ),0.5 );
1200 GMPK = DK/std::pow( 16*( NU + DK*DK),0.5);
1201 BTNCKH = 2*atan2( std::pow( XNKH,0.5 ), std::pow(( 1-XNKH),0.5) )/
PI;
1202 BTPDKH = 2*std::pow( XNKH*( 1 - XNKH ),0.5 )/
PI;
1203 BTNCHK = 2*atan2( std::pow( XNHK,0.5 ), std::pow((1 - XNHK),0.5) )/
PI;
1204 BTPDHK = 2*std::pow( XNHK*( 1 - XNHK ),0.5 )/
PI;
1205 for( J = 1; J<= NU/2;J++)
1207 BVT = BVT + GMPH*( 1 + KS*BTNCKH );
1208 BVT = BVT + GMPK*( 1 + HS*BTNCHK );
1209 BTNCKH = BTNCKH + BTPDKH;
1210 BTPDKH = 2*J*BTPDKH*( 1 - XNKH )/( 2*J + 1 );
1211 BTNCHK = BTNCHK + BTPDHK;
1212 BTPDHK = 2*J*BTPDHK*( 1 - XNHK )/( 2*J + 1 );
1213 GMPH = GMPH*( 2*J - 1 )/( 2*J*( 1 + DH*DH/NU ) );
1214 GMPK = GMPK*( 2*J - 1 )/( 2*J*( 1 + DK*DK/NU ) );
1219 QHRK = std::pow((DH*DH + DK*DK - 2*R*DH*DK + NU*ORS),0.5 ) ;
1220 HKRN = DH*DK + R*NU ;
1223 BVT = atan2( -SNU*( HKN*QHRK + HPK*HKRN ),HKN*HKRN-NU*HPK*QHRK )/TPI;
1224 if ( BVT < -EPS ) BVT = BVT + 1;
1225 GMPH = DH/( TPI*SNU*( 1 + DH*DH/NU ) );
1226 GMPK = DK/( TPI*SNU*( 1 + DK*DK/NU ) );
1227 BTNCKH = std::pow( XNKH,0.5 );
1229 BTNCHK = std::pow( XNHK,0.5 );
1231 for( J = 1;J<= ( NU - 1 )/2; J++)
1233 BVT = BVT + GMPH*( 1 + KS*BTNCKH );
1234 BVT = BVT + GMPK*( 1 + HS*BTNCHK );
1235 BTPDKH = ( 2*J - 1 )*BTPDKH*( 1 - XNKH )/( 2*J );
1236 BTNCKH = BTNCKH + BTPDKH;
1237 BTPDHK = ( 2*J - 1 )*BTPDHK*( 1 - XNHK )/( 2*J );
1238 BTNCHK = BTNCHK + BTPDHK;
1239 GMPH = 2*J*GMPH/( ( 2*J + 1 )*( 1 + DH*DH/NU ) );
1240 GMPK = 2*J*GMPK/( ( 2*J + 1 )*( 1 + DK*DK/NU ) );
1257 static Real DT, FT, BT,result;
1260 DT = RR*( RR - std::pow(( RA - RB ),2) - 2*RA*RB*( 1 - R ) );
1262 BT = ( BC*RR + BA*( R*RB - RA ) + BB*( R*RA -RB ) )/std::pow(DT,0.5);
1263 FT = std::pow(( BA - R*BB ),0.5)/RR + BB*BB;
1265 if ( (BT > -10) && (FT <100) ) {
1266 result = exp( -FT/2 );
1267 if ( BT <10 ) result= result*PHID(BT);
1269 FT = std::pow((1 + FT/NUC),0.5);
1270 result = STUDNT( NUC, BT/FT )/std::pow(FT,NUC);
1308 static double TWOPI = 6.283185307179586;
1309 static Real result, DK, DH, R;
1310 static int I, IS, LG, NG;
1312 static Real XL[11][4], WL[11][4], AS, AA, BB, C, D, RS, XS, BVN;
1313 static Real SN, ASR, H, K, BS, HS, HK;
1316 WL[1][1]=0.1713244923791705;
1317 XL[1][1]=-0.9324695142031522;
1318 WL[2][1]= 0.3607615730481384;
1319 XL[2][1]=-0.6612093864662647;
1320 WL[3][1]= 0.4679139345726904;
1321 XL[3][1]=-0.2386191860831970;
1325 WL[1][2]=0.4717533638651177e-01;
1326 XL[1][2]=-0.9815606342467191;
1327 WL[2][2]= 0.1069393259953183;
1328 XL[2][2]=-0.9041172563704750;
1329 WL[3][2]= 0.1600783285433464;
1330 XL[3][2]=-0.7699026741943050;
1331 WL[4][2]= 0.2031674267230659;
1332 XL[4][2]=-0.5873179542866171;
1333 WL[5][2]= 0.2334925365383547;
1334 XL[5][2]=-0.3678314989981802;
1335 WL[6][2] = 0.2491470458134029;
1336 XL[6][2]=-0.1252334085114692;
1340 WL[1][3]=0.1761400713915212e-01;
1341 XL[1][3]=-0.9931285991850949;
1342 WL[2][3]=0.4060142980038694e-01;
1343 XL[2][3]=-0.9639719272779138;
1344 WL[3][3]=0.6267204833410906e-01;
1345 XL[3][3]=-0.9122344282513259;
1346 WL[4][3]=0.8327674157670475e-01;
1347 XL[4][3]=-0.8391169718222188;
1348 WL[5][3]=0.1019301198172404;
1349 XL[5][3]=-0.7463319064601508;
1350 WL[6][3]=0.1181945319615184;
1351 XL[6][3]=-0.6360536807265150;
1352 WL[7][3]=0.1316886384491766;
1353 XL[7][3]=-0.5108670019508271;
1354 WL[8][3]=0.1420961093183821;
1355 XL[8][3]=-0.3737060887154196;
1356 WL[9][3]=0.1491729864726037;
1357 XL[9][3]=-0.2277858511416451;
1358 WL[10][3]=0.1527533871307259;
1359 XL[10][3]=-0.7652652113349733e-01;
1365 if( fabs(R) < 0.3 ) {
1368 else if ( fabs(R) < 0.75 ) {
1380 if( fabs(R) < 0.925 ) {
1382 HS = ( H*H + K*K )/2;
1384 for (I = 1;I<= LG; I++){
1385 for( IS = -1; IS<= 1; IS=IS+2){
1386 SN = sin( ASR*( IS*XL[I][NG] + 1 )/2 );
1387 BVN = BVN + WL[I][NG]*exp( ( SN*HK-HS )/( 1.0-SN*SN ) );
1391 BVN = BVN*ASR/( 2*TWOPI );
1395 BVN = BVN + PHID(-H)*PHID(-K);
1406 AS = ( 1 - R )*( 1 + R );
1407 AA = std::pow(AS,0.5);
1409 BS = std::pow(( H - K ),2);
1412 ASR = -( BS/AS + HK )/2;
1413 if( ASR > -100 ) BVN = AA*exp(ASR)*( 1 - C*( BS - AS )*( 1 - D*BS/5 )/3 + C*D*AS*AS/5 );
1415 BB = std::pow(BS,0.5);
1416 BVN = BVN - exp( -HK/2 )*std::pow(TWOPI,0.5)*PHID(-BB/AA)*BB*( 1 - C*BS*( 1 - D*BS/5 )/3 );
1419 for (I = 1; I<= LG;I++){
1420 for( IS = -1; IS<=1; IS=IS+2){
1421 XS =std::pow( ( AA*( IS*XL[I][NG] + 1 ) ),2) ;
1422 RS = std::pow( (1 - XS),2 );
1423 ASR = -( BS/XS + HK )/2;
1426 BVN = BVN + AA*WL[I][NG]*exp( ASR )*(exp( -HK*( 1 - RS )/( 2*( 1 + RS ) ) )/RS- ( 1 + C*XS*( 1 + D*XS ) ) );
1436 BVN = BVN + PHID( -max( H, K ) );
1442 if( K > H ) BVN = BVN + PHID(K) - PHID(H);
1453 struct integr_adapter {
1454 ext::shared_ptr<YieldTermStructure>
r;
1455 explicit integr_adapter(
const ext::shared_ptr<GeneralizedBlackScholesProcess>& process)
1456 :
r(*(process->riskFreeRate())) {}
1458 return r->forwardRate(t1,t2,
Continuous) * (t2-t1);
1462 struct integalpha_adapter {
1463 ext::shared_ptr<YieldTermStructure>
r;
1464 ext::shared_ptr<YieldTermStructure>
q;
1465 explicit integalpha_adapter(
1466 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process)
1467 :
r(*(process->riskFreeRate())),
q(*(process->dividendYield())) {}
1471 return alpha * (t2-t1);
1475 struct alpha_adapter {
1476 ext::shared_ptr<YieldTermStructure>
r;
1477 ext::shared_ptr<YieldTermStructure>
q;
1478 explicit alpha_adapter(
const ext::shared_ptr<GeneralizedBlackScholesProcess>& process)
1479 :
r(*(process->riskFreeRate())),
q(*(process->dividendYield())) {}
1486 struct sigmaq_adapter {
1487 ext::shared_ptr<BlackVolTermStructure>
v;
1489 explicit sigmaq_adapter(
const ext::shared_ptr<GeneralizedBlackScholesProcess>& process)
1490 :
v(*(process->blackVolatility())),
s(process->x0()) {}
1497 struct integs_adapter {
1498 ext::shared_ptr<BlackVolTermStructure>
v;
1500 explicit integs_adapter(
const ext::shared_ptr<GeneralizedBlackScholesProcess>& process)
1501 :
v(*(process->blackVolatility())),
s(process->x0()) {}
1503 return v->blackForwardVariance(t1,t2,s,
true);
1511 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
Natural order,
bool zeroGamma)
1512 : process_(
std::move(process)),
order_(order), zeroGamma_(zeroGamma) {
1519 "this engine only manages up-and-out options");
1522 "this engine does not manage non-null rebates");
1524 ext::shared_ptr<PlainVanillaPayoff>
payoff =
1525 ext::dynamic_pointer_cast<PlainVanillaPayoff>(
arguments_.payoff);
1527 "this engine only manages put options");
1541 tauMin, tauMax,
order_, igm,
Barrier::Type barrierType
BarrierOption::results results_
BarrierOption::arguments arguments_
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
void calculate() const override
PerturbativeBarrierOptionEngine(ext::shared_ptr< GeneralizedBlackScholesProcess >, Natural order=1, bool zeroGamma=false)
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Classes and functions for error handling.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Option exercise classes and payoff function.
ext::function< Real(Real)> b
Maps function, bind and cref to either the boost or std implementation.
Real Time
continuous quantity with 1-year units
unsigned QL_INTEGER Natural
positive integer
ext::shared_ptr< QuantLib::Payoff > payoff
ext::shared_ptr< YieldTermStructure > q
ext::shared_ptr< YieldTermStructure > r
ext::shared_ptr< BlackVolTermStructure > v
perturbative barrier-option engine