function getDayOfMonth	(xdate) 	{ SDate=xdate.split("."); if  (SDate.length != 3) SDate=xdate.split(","); if  (SDate.length != 3) return -1;else return  (SDate[0]*1.0);}
function getMonth	(xdate)	{ SDate=xdate.split(".");if  (SDate.length != 3) SDate=xdate.split(","); if  (SDate.length != 3) return -1;else return  (SDate[1]*1.0);}
function getYear		(xdate)	{ SDate=xdate.split(".");if  (SDate.length != 3) SDate=xdate.split(","); if  (SDate.length != 3) return -1;else return  (SDate[2]*1.0);}


function SubMonths(xdate, months)
{
 var dummy;
 SDate=xdate.split(".");if  (SDate.length != 3) SDate=xdate.split(","); if  (SDate.length != 3) return 0;
 Fraction1=Date.UTC(SDate[2],SDate[1]-1,SDate[0]);
 time = new Date(); time.setTime(Fraction1);
 dummy=time.getYear();
 if(dummy < 999) dummy+=1900;
 time.setYear(dummy-Math.floor(months/12));
 months=months-Math.floor(months/12)*12;
 if (months >= time.getMonth()+1)
{
  dummy=time.getYear()-1;
  if(dummy < 999) dummy+=1900;
   time.setYear(dummy);
  dummy=time.getMonth()+1;
   time.setMonth(dummy+12-months-1);
}
else
{
  dummy=time.getMonth()+1;
   time.setMonth(dummy-months-1);
}
  dummy=time.getYear();
  if(dummy < 999) dummy+=1900;
 return(time.getDate()+"."+eval(time.getMonth()+1)+"."+ dummy);
}
function datecheck(startdate, enddate)
{
 SDate=startdate.split(".");if  (SDate.length != 3) SDate=startdate.split(","); if  (SDate.length != 3) return 0;
 MDate=enddate.split(".");if  (MDate.length != 3) MDate=enddate.split(","); if  (MDate.length != 3) return 0;

 Fraction1=Date.UTC(SDate[2],SDate[1]-1,SDate[0]);
 Fraction2=Date.UTC(MDate[2],MDate[1]-1,MDate[0]);
if (Fraction1>=Fraction2) 	return(1); else return(0);
}

function accrued_days(startdate, enddate, daycmeth)
{
 var add1=0.0,add2=0.0;

 daycmeth= "7";

 SDate=startdate.split(".");if  (SDate.length != 3) SDate=startdate.split(","); if  (SDate.length != 3) return 0;
 MDate=enddate.split(".");if  (MDate.length != 3) MDate=enddate.split(","); if  (MDate.length != 3) return 0;


 Fraction1=Date.UTC(SDate[2],SDate[1]-1,SDate[0]);
 Fraction2=Date.UTC(MDate[2],MDate[1]-1,MDate[0]);

 daydiff=(Fraction2-Fraction1)/1000/60/60/24;
 if (daydiff < 0) return (-1);
 switch (daycmeth)
  {
      case "1": 
      case "2": 
      case "3": 
			   return daydiff;
      case "4":
      case "5":  
			if (getDayOfMonth(startdate) == 31) add1=-1 ;
			if (getDayOfMonth(enddate) == 31 && getDayOfMonth(startdate) == 30) add2=-1;
			daydiff =(
				 getDayOfMonth(enddate) + add1 -  (getDayOfMonth(startdate)  + add2) +
				 (getMonth(enddate) - getMonth(startdate)) * 30 + 
				 (getYear(enddate) - getYear(startdate)) * 360 
				);
			 return daydiff;
      case "6": 
			if (getDayOfMonth(startdate) == 31) add1=-1 ;
			if (getDayOfMonth(enddate) == 31 && getDayOfMonth(startdate) == 30) add2=-1;
			daydiff =(
				 getDayOfMonth(enddate) + add2  -  (getDayOfMonth(startdate) + add1) +
				 (getMonth(enddate) - getMonth(startdate)) * 30 + 
				 (getYear(enddate) - getYear(startdate)) * 365
				);
			 return daydiff;
      case "7":    
			if (getDayOfMonth(startdate) == 31) add1=-1.0 ;
			if (getDayOfMonth(enddate) == 31) add2=-1.0 ;
			daydiff =(
				 getDayOfMonth(enddate) + add2  -  (getDayOfMonth(startdate) + add1) +
				 (getMonth(enddate) - getMonth(startdate)) * 30 + 
				 (getYear(enddate) - getYear(startdate)) * 360
				);
			 return daydiff;
      case "8":
			if (getDayOfMonth(startdate) == 31) add1=-1 ;
			if (getDayOfMonth(enddate) == 31) add2=-1 ;
			daydiff =(
				 getDayOfMonth(enddate) + add2  -  (getDayOfMonth(startdate) + add1) +
				 (getMonth(enddate) - getMonth(startdate)) * 30 + 
				 (getYear(enddate) - getYear(startdate)) * 365
				);
			 return daydiff;
			
      default		: return(-1);
     };
  return (-1);
}; 


function diffFinYears (startdate, enddate, daycmeth)
{
 var TRUE=1, FALSE=0;
 var  incl_29_Feb = FALSE;
 daycmeth= 7; 		

  var daydiff = accrued_days(startdate, enddate, daycmeth);
 
if (daydiff < 0) return(-1);
switch (daycmeth)
  {
      case 1: 		if (incl_29_Feb==TRUE) return (daydiff / 366); else return (daydiff / 365);
      case 2: 	 	return ( daydiff / 365 );
      case 3: 		return ( daydiff / 360 );
      case 4: 
      case 5: 		return (daydiff / 360.0 );				 
      case 6: 		return (daydiff / 365.0 );
      case 7: 		return (daydiff / 360.0 );		
      case 8:  	return (daydiff / 365.0 );
      default: 			return(-1);
     };
 return (-1);
};

function getActualDate()
{
  var akt= new Date();
  var sdate;

  Jahr=akt.getYear() 
  if(Jahr < 999) Jahr+=1900;
  sdate = akt.getDate() + "." +(akt.getMonth()+1)+"."+Jahr;
  return sdate;
};



var Duration, ModifiedDuration;

function getAccrued(startdate,enddate,frequency,coupon,redemption,daycount)
{
 return   ( diffFinYears(startdate, enddate, daycount) * coupon * redemption / 100.0); 
};

function getDuration(yld)
{
  yield2price(yld);
 return (Duration);
};

function getModDuration(yld)
{
  ModifiedDuration=getDuration(yld)/(1+yld/100); 
  return( ModifiedDuration);
};

function Yield2PerYield(yield,frequency)
{
 return ((Math.pow(1+yield/100,1.0/frequency)-1)*100);
}

function getLastCoupon(validation_date,maturity,frequency,daycount)
{
var perioden;
 disctime  = diffFinYears(validation_date, maturity,daycount);
 perioden   = Math.floor(disctime*frequency) + 1;
 switch (frequency)
 {
  case 1: months = perioden*12; break;
  case 2: months = perioden*6; break;
  case 4: months = perioden*3; break;
  case 12: months = perioden*1; break;
  default: months=0;
 };

return( SubMonths(maturity,months));
};

function yield2price( yld)
{
 var disctime, PerYear, fracYear,PerYld;
 var yldmeth = 1;
 var i=0;
 var DPV=0;
var DurT=0;
var sumDPV=0;
validation_date = mlh_replace(document.Renditerechner.validation_date.value);
maturity = mlh_replace(document.Renditerechner.maturity.value);
selected=document.Renditerechner.frequency.selectedIndex;
switch ( selected)
{
  case 0: frequency=1.0;break;
  case 1: frequency=2.0; break;
  case 2: frequency=4.0; break;
  case 3: frequency=12.0; break; 
};
redemption  = 100.0;
coupon        = document.Renditerechner.coupon.value;yldmeth =1;
disctime       = diffFinYears(validation_date, maturity,7);
if (disctime <0) return(0.0);
PerYear   = Math.floor(disctime*frequency);
fracYear  = disctime*frequency - PerYear;
PerYld     = Yield2PerYield(yld,frequency);

perend  = maturity;
j=0;
for(i = PerYear; i >= 0; i--)
{
  j++;
  perstart = SubMonths(maturity,(12/frequency)*j);
  inttime = diffFinYears(perstart,perend,7);
  perend = perstart;
   if (i==PerYear) 
	amount = redemption*1.0 + coupon*inttime;
  else
	amount = coupon*inttime;

 if  ((yldmeth == 1))
   {
	 DPV        = amount/Math.pow(1+PerYld/100,i+fracYear);
	 sumDPV +=  DPV;
	 DurT       +=  DPV * (i+fracYear);
   }
}; /* for */

Duration = (DurT/frequency) / sumDPV;
ModifiedDuration = Duration / (1+yld/100.0);
return (sumDPV);
}

var TRUE=1;FALSE=0;
var TargetValue;
var error,mode;
var limiterr, iter,  MaxIter, MaxTol, Limit, NearlyZero;
var  root,value, found;
var oldx,x,oldy,y;
var newx, newy;

function TargetFunction(approxY) 
{
  dummy= yield2price(approxY);

  return(dummy-eval(TargetValue*1.0)); 
}

function TestForRoot(tol)
{
 return ( (Math.abs(y) <=MaxTol) || (Math.abs(x-oldx) < Math.abs(oldx*tol)));
}

function Initial(Guess1, Guess2,  found)
{
 found = FALSE;
 iter  = 0;
 oldx  = Guess1;
 x     = Guess2;


 oldy  = TargetFunction(oldx);
 y     = TargetFunction(x);

 error = 0;
 if (Math.abs(oldy) <NearlyZero)
   {
     x = oldx;
     y = oldy;
     found = TRUE;
    }
 else
  {
   if ( (Math.abs(oldy-y) <= NearlyZero) || ( MaxTol <= 0) || (MaxIter < 0) ) error = -1;
  }
}

function Secant(Guess1, Guess2, root, value)
{

 Initial(Guess1,Guess2,found);

 while ( (found==0) && (error == 0) && (iter < MaxIter))
  {
    iter++;
    if ((y-oldy) != 0) newx = x-y*(x-oldx)/(y-oldy);
    newy   = TargetFunction(newx);
    found  = TestForRoot(MaxTol);
    oldx   = x;
    oldy   = y;
    x      = newx;
    y      = newy;
  }

  root  = x;
  value = y;
  if ( (found  != TRUE)  &&  (error == 0) && (iter >= MaxIter) ) error = -1;
}

function BiSection(upper, lower, eps, maxiter, yValue)
{
 var  value    = 0;
 var  root     = 0; 
 Secant(upper,lower,root, value);
 if  ( (error < 0) || (limiterr) ) 
  {
	 return (-1);
  }
 else				  
    return (root);  
}

function price2yield(amount)
{
 
 limiterr=FALSE; iter=0;  MaxIter=100; MaxTol=1e-10; Limit=9999.9; NearlyZero=1e-15;
 found=FALSE;
 newx=0; newy=0;error=0;x=0;oldx=0;y=0;oldy=0;
 TargetValue = amount;

 error= BiSection(10.0,-10.0,1e-10,200);

 return(x);
}



function ResetFelder()
{
 document.Renditerechner.taxrate.value="";
 document.Renditerechner.frequency.selectedIndex=0;
 document.Renditerechner.yield.value = "";
 document.Renditerechner.yield_pa.value = "";
 document.Renditerechner.dirty_price.value="";

 document.Renditerechner.acc_interest.value = "";
 document.Renditerechner.acc_days.value="";
 document.Renditerechner.lastcp.value ="";
 document.Renditerechner.duration.value = "";
 document.Renditerechner.ModDur.value = "";
 document.Renditerechner.remtime.value="";
 document.Renditerechner.yield_brutto.value="";
 document.Renditerechner.netto.value="";
 document.Renditerechner.akt_value.value="";
 document.dataimport.WKN.value="";
}

function ChangeNumbers()
{
 document.Renditerechner.coupon.value= document.Renditerechner.coupon.value.replace(/,/,".");
 document.Renditerechner.taxrate.value= document.Renditerechner.taxrate.value.replace(/,/,".");
 document.Renditerechner.akt_kurs.value= document.Renditerechner.akt_kurs.value.replace(/,/,".");
 document.Renditerechner.yield.value =  document.Renditerechner.yield.value.replace(/,/,".");
 document.Renditerechner.nom_betrag.value =  document.Renditerechner.nom_betrag.value.replace(/,/,".");
 document.Renditerechner.yield_pa.value =  document.Renditerechner.yield_pa.value.replace(/,/,".");
 document.Renditerechner.dirty_price.value= document.Renditerechner.dirty_price.value.replace(/,/,".");
}


function ChangeNumbers2()
{
 document.Renditerechner.coupon.value= cv_nachkomma(document.Renditerechner.coupon.value, 3);
 document.Renditerechner.taxrate.value = document.Renditerechner.taxrate.value.replace(/\./,",");

 document.Renditerechner.akt_kurs.value= cv_nachkomma(document.Renditerechner.akt_kurs.value, 2);
 document.Renditerechner.yield_pa.value =  cv_nachkomma(document.Renditerechner.yield_pa.value, 2);
 document.Renditerechner.nom_betrag.value = document.Renditerechner.nom_betrag.value.replace(/\./,",");

 document.Renditerechner.yield.value = cv_nachkomma(document.Renditerechner.yield.value, 2);
 document.Renditerechner.yield_brutto.value = cv_nachkomma(document.Renditerechner.yield_brutto.value, 2);
 document.Renditerechner.netto.value = cv_nachkomma(document.Renditerechner.netto.value, 2);

 document.Renditerechner.acc_interest.value = cv_nachkomma(document.Renditerechner.acc_interest.value, 2);
 document.Renditerechner.remtime.value = cv_nachkomma(document.Renditerechner.remtime.value, 2);


 document.Renditerechner.duration.value  = cv_nachkomma(document.Renditerechner.duration.value, 2);
 document.Renditerechner.ModDur.value  = cv_nachkomma(document.Renditerechner.ModDur.value, 2);

 document.Renditerechner.dirty_price.value= cv_nachkomma(document.Renditerechner.dirty_price.value, 2);
 document.Renditerechner.akt_value.value = cv_nachkomma(document.Renditerechner.akt_value.value, 2);
}


function cv_nachkomma(dec_val, anz_nachkomma)
{
  var erg_str, help_val, split_pos;
  var help_sign = "";

  help_val =  Math.round(dec_val*Math.pow(10,anz_nachkomma));

  if(isNaN(help_val) == true) return dec_val;

  if(help_val < 0) help_sign = "-";

  help_val = Math.abs(help_val).toString();

  while (help_val.length < anz_nachkomma + 1) {
     help_val = "0".concat(help_val);
  }

  split_pos = help_val.length - anz_nachkomma;

  help_val = help_val.substring(0,split_pos).concat(".").concat(help_val.substring(split_pos));
  erg_str = help_sign.concat(help_val);
  return erg_str;
}



function Calculate(flag)
{
ChangeNumbers();
 document.Renditerechner.acc_interest.value = "";
 document.Renditerechner.acc_days.value="";
 document.Renditerechner.lastcp.value ="";

 if (flag<3)
{
	document.Renditerechner.calc_display.value = "Calculating...";
  document.Renditerechner.yield.value = "";
 document.Renditerechner.duration.value = "";
 document.Renditerechner.ModDur.value = "";
 document.Renditerechner.remtime.value="";
 document.Renditerechner.yield_brutto.value="";
 document.Renditerechner.netto.value="";
};
 selected=document.Renditerechner.frequency.selectedIndex;
switch ( selected)
{
  case 0: frequency=1.0;break;
  case 1: frequency=2.0; break;
  case 2: frequency=4.0; break;
  case 3: frequency=12.0; break;
};
daycount=7;
startdate =  mlh_replace(document.Renditerechner.validation_date.value);
enddate = mlh_replace(document.Renditerechner.maturity.value);
if (datecheck(startdate, enddate)==1)  {alert ("Die Anleihe ist bereits fällig geworden, eine Berechnung kann daher nicht durchgeführt werden."); return; }
   lastcpdate =getLastCoupon(startdate,enddate,frequency,daycount);
document.Renditerechner.lastcp.value = mlh_replace_inv(lastcpdate) ;
  cp = document.Renditerechner.coupon.value;
   if (cp<0 ) {alert("Bitte geben Sie einen positiven Koupon-Wert an !");return};

if (flag==1)
{
  document.Renditerechner.dirty_price.value = "";
  document.Renditerechner.akt_kurs.value = "";

   if (document.Renditerechner.yield_pa.value<=0 ) {alert("Bitte geben Sie einen positiven Rendite-Wert an !");return};
   document.Renditerechner.lastcp.value = lastcpdate ;
  document.Renditerechner.acc_days.value =  accrued_days(lastcpdate,startdate,frequency, 7);
  dummy = getAccrued(lastcpdate,startdate,frequency,cp,100, 7);
  document.Renditerechner.acc_interest.value = Math.floor(dummy*100+0.5)/100;
  document.Renditerechner.dirty_price.value =  Math.floor(yield2price(document.Renditerechner.yield_pa.value)*100+0.5)/100;
  document.Renditerechner.akt_kurs.value = Math.floor
((document.Renditerechner.dirty_price.value-document.Renditerechner.acc_interest.value)*100+0.5)/100;
  document.Renditerechner.yield.value = document.Renditerechner.yield_pa.value;
  document.Renditerechner.remtime.value = Math.floor(diffFinYears (startdate, enddate, 7)*100+0.5)/100;
  document.Renditerechner.duration.value = Math.floor(Duration*100+0.5)/100;
  document.Renditerechner.ModDur.value = Math.floor(ModifiedDuration*100+0.5)/100;
}
else if (flag==2) 
{
  document.Renditerechner.yield_pa.value = "";

 DPrice = document.Renditerechner.dirty_price.value;
 CPrice = document.Renditerechner.akt_kurs.value;

 if (DPrice<=0 && CPrice <=0 ) {alert("Bitte geben Sie einen positiven Kurs-Wert an !");return};
 document.Renditerechner.acc_days.value =  accrued_days(lastcpdate,startdate,frequency, 7);
 cp = document.Renditerechner.coupon.value;
 dummy = getAccrued(lastcpdate,startdate,frequency,cp,100, 7);
 document.Renditerechner.acc_interest.value = Math.floor(dummy*100+0.5)/100;
  if ((CPrice <= 0) ||( CPrice=="")  )
	 document.Renditerechner.akt_kurs.value = Math.floor((eval(document.Renditerechner.akt_kurs.value) - eval(document.Renditerechner.acc_interest.value))*100+0.5)/100;
else
	  document.Renditerechner.dirty_price.value = Math.floor((eval(document.Renditerechner.akt_kurs.value) + eval(document.Renditerechner.acc_interest.value))*100+0.5)/100;

 DPrice = document.Renditerechner.dirty_price.value;
 CPrice = document.Renditerechner.akt_kurs.value;

 yieldtemp = price2yield(DPrice);
 document.Renditerechner.yield_pa.value = Math.floor( yieldtemp*100+0.5)/100;
 document.Renditerechner.yield.value = document.Renditerechner.yield_pa.value;
 document.Renditerechner.duration.value = Math.floor(Duration*100+0.5)/100;
 document.Renditerechner.ModDur.value = Math.floor(ModifiedDuration*100+0.5)/100;
 document.Renditerechner.remtime.value = Math.floor(diffFinYears (startdate, enddate, 7)*100+0.5)/100;

}
else (flag==3)
{
  document.Renditerechner.acc_days.value =  accrued_days(lastcpdate,startdate,frequency, 7);
  cp = document.Renditerechner.coupon.value;
  dummy = getAccrued(lastcpdate,startdate,frequency,cp,100, 7);
  document.Renditerechner.acc_interest.value = Math.floor(dummy*100+0.5)/100; 
  document.Renditerechner.dirty_price.value = eval(document.Renditerechner.akt_kurs.value) +   eval(document.Renditerechner.acc_interest.value);
}


 tax    =  document.Renditerechner.taxrate.value;
lastcpdate = document.Renditerechner.lastcp.value
if ((tax>0) && (tax<100))
{
 oldcp =  document.Renditerechner.coupon.value;
 document.Renditerechner.coupon.value = eval(oldcp*(1-tax/100));
yieldtemp = price2yield( eval(document.Renditerechner.akt_kurs.value)+eval(getAccrued(lastcpdate,startdate,frequency, document.Renditerechner.coupon.value,100, 7)));
brutto=yieldtemp/(1-tax/100);
document.Renditerechner.yield_brutto.value = Math.floor(brutto*100+0.5)/100;
document.Renditerechner.netto.value = Math.floor(brutto*(100-tax)+0.5)/100;
document.Renditerechner.coupon.value = oldcp;
};
if (tax==100)	 
	{
		document.Renditerechner.yield_brutto.value = "";
		document.Renditerechner.netto.value = "";
	};
		
if (tax==0)
	{	
		document.Renditerechner.yield_brutto.value =  document.Renditerechner.yield.value;
		document.Renditerechner.netto.value =  document.Renditerechner.yield.value;
	};

 document.Renditerechner.akt_value.value =
 Math.floor( 	eval(document.Renditerechner.nom_betrag.value)*
		eval(document.Renditerechner.dirty_price.value)+0.5
	     )/100.0;


document.Renditerechner.calc_display.value = "";


ChangeNumbers2();
}


 function BerechneForm()
 {
    var help_fval;
  document.Renditerechner.validation_date.value = document.Renditerechner.validation_date.value.replace(/\s/g,"");
  
  	
  
   if(document.Renditerechner.validation_date.value == ""){
      alert("Das Bewertungsdatum muss im Format \nTT.MM.JJJJ abgegeben sein !");
      document.Renditerechner.validation_date.focus();
      return;
   }
   document.Renditerechner.maturity.value = document.Renditerechner.maturity.value.replace(/\s/g,"");
   
   if(document.Renditerechner.maturity.value == ""){
      alert("Die F&auml;lligkeit muss im Format \nTT.MM.JJJJ abgegeben sein !");
      document.Renditerechner.maturity.focus();
      return;
   }
   document.Renditerechner.coupon.value = document.Renditerechner.coupon.value.replace(/\s/g,"");
   if(document.Renditerechner.coupon.value == ""){
      alert("Bitte geben Sie Zinssatz an !");
      document.Renditerechner.coupon.focus();
      return;
   }

   document.Renditerechner.akt_kurs.value = document.Renditerechner.akt_kurs.value.replace(/\s/g,"");
   help_fval = document.Renditerechner.akt_kurs.value.replace(/,/,".");
   help_fval = Number(help_fval);
   if(help_fval <= 0 || isNaN(help_fval)) {
      document.Renditerechner.akt_kurs.value = "";
      document.Renditerechner.yield_pa.value = document.Renditerechner.yield_pa.value.replace(/\s/g,"");
      help_fval = document.Renditerechner.yield_pa.value.replace(/,/,".");
      help_fval = Number(help_fval);
      if(help_fval <= 0 || isNaN(help_fval)) {
         alert("Bitte geben Sie entweder f&uuml;r Kurs oder Rendite \neinen positiven Wert an !");
         alert(document.Renditerechner.akt_kurs.focus());
         document.Renditerechner.akt_kurs.focus();
         return;
      }
      Calculate(1);
   }
   help_fval = document.Renditerechner.yield_pa.value.replace(/,/,".");
   if(help_fval >= 0.01 && document.Renditerechner.Chooser.value == "y") {
     {Calculate(1)}
   }
   Calculate(2);
 }
 
 
function mlh_replace(indate) {

	mlh_tmp=indate.split("/");
	return (mlh_tmp[1] + "." + mlh_tmp[0] + "." + mlh_tmp[2]);
	
}


function mlh_replace_inv(indate) {

	mlh_tmp=indate.split(".");
	return (mlh_tmp[1] + "/" + mlh_tmp[0] + "/" + mlh_tmp[2]);
	
}