

function roundToPennies(n)
{
	pennies= n*10000;
	pennies= Math.round(pennies);
	return pennies / 10000;
}

function erf(d)
{
	step= 0.01;
	sum= 0;
	x= -5 + step / 2;
	while ( (x < d) && (x < 4) )
	{
		sum= sum + Math.exp(- x * x / 2) * step;
		x= x + step;
	}
	return sum / Math.sqrt(2 * Math.PI);
}

//function B_S_call(price, strike, rem_time, vol, int_rate)
//{
//	d1= Math.log( price / (strike * Math.pow(1+int_rate,-rem_time))) /
//			(vol*Math.sqrt(rem_time)) + (vol*Math.sqrt(rem_time)) / 2;
//	d2= d1 - vol*Math.sqrt(rem_time);
//	return price * erf(d1) - strike * Math.pow(1+int_rate,-rem_time) * erf(d2);
//}

function B_S_call(price, strike, rem_time, vol, int_rate)
{
	d1= ( Math.log( price / strike) + ( int_rate + vol*vol / 2 ) * rem_time ) /
		( vol * Math.sqrt( rem_time) );
	d2= d1 - vol * Math.sqrt( rem_time );
	return price * erf(d1) - strike * Math.exp( - (int_rate*rem_time) ) * erf(d2);
}

//function B_S_put(price, strike, rem_time, vol, int_rate)
//{
//	d1= Math.log( price / (strike * Math.pow(1+int_rate,-rem_time))) /
//			(vol*Math.sqrt(rem_time)) + (vol*Math.sqrt(rem_time)) / 2;
//	d2= d1 - vol*Math.sqrt(rem_time);
//	return - price * erf(-d1) + strike * Math.pow(1+int_rate,-rem_time) * erf(-d2);
//}	

function B_S_put(price, strike, rem_time, vol, int_rate)
{
	d1= ( Math.log( price / strike) + ( int_rate + vol*vol / 2 ) * rem_time ) /
		( vol * Math.sqrt( rem_time) );
	d2= d1 - vol * Math.sqrt( rem_time );
	return strike * Math.exp( - (int_rate*rem_time) ) * erf(-d2) - price * erf(-d1);
}

function compute(form)
{
	form.call.value= " ";
	form.put.value= " ";
	form.delta_call.value= " ";
	form.delta_put.value= " ";
	form.theta_call.value= " ";
	form.theta_put.value= " ";
	form.rho_call.value= " ";
	form.rho_put.value= " ";
	form.vega.value= " ";
	form.gamma.value= " ";
	window.status="Processing, please wait.";
	rem_time= form.rem.value / 365;
	strike= form.strike.value;
	price= form.price.value;
	vol= form.vol.value /100;
	int_rate= form.intr.value / 100;
	B_S_c= B_S_call(price,strike,rem_time,vol,int_rate);
	B_S_p= B_S_put(price,strike,rem_time,vol,int_rate);
	form.call.value= roundToPennies(B_S_c);
	form.put.value= roundToPennies(B_S_p);
	window.status="";
}

function compute_derivatives(form)
{
	window.status="Processing, please wait.";
	rem_time= form.rem.value / 365;
	strike= form.strike.value;
	price= form.price.value;
	vol= form.vol.value / 100;
	int_rate= form.intr.value / 100;
	compute(form);
	d1= ( Math.log( price / strike) + ( int_rate + vol*vol / 2 ) * rem_time ) /
		( vol * Math.sqrt( rem_time) );
	d2= d1 - vol * Math.sqrt( rem_time );
	erfprimed1= Math.exp( -(d1*d1)/2 ) / Math.sqrt( 2*Math.PI );
	delta_c= erf(d1);
	delta_p= erf(d1) - 1;
	theta_c= - price * erfprimed1 * vol / ( 2 * Math.sqrt( rem_time ) ) -
			int_rate * strike * Math.exp( - int_rate * rem_time ) * erf(d2);
	theta_c= theta_c / 365;
	theta_p= - price * erfprimed1 * vol / ( 2 * Math.sqrt( rem_time ) ) +
			int_rate * strike * Math.exp( - int_rate * rem_time ) * erf(-d2);
	theta_p= theta_p / 365;
	rho_c=   strike * rem_time * Math.exp( - int_rate * rem_time ) * erf(d2);
	rho_c= rho_c / 100;
	rho_p= - strike * rem_time * Math.exp( - int_rate * rem_time ) * erf(-d2);
	rho_p= rho_p / 100;
	vega= price * Math.sqrt( rem_time ) * erfprimed1;
	vega= vega / 100;
	gamma= erfprimed1 / ( price * vol * Math.sqrt( rem_time) );
	form.delta_call.value= roundToPennies(delta_c);
	form.delta_put.value= roundToPennies(delta_p);
	form.theta_call.value= roundToPennies(theta_c);
	form.theta_put.value= roundToPennies(theta_p);
	form.rho_call.value= roundToPennies(rho_c);
	form.rho_put.value= roundToPennies(rho_p);
	form.vega.value= roundToPennies(vega);
	form.gamma.value= roundToPennies(gamma);
	window.status="";
}


