#!/usr/bin/perl -w

use 5.030;

my $K = 100;  # strike price
my $r = 0.02; # risk free anual rate
my $sigma = 0.2; # volatility 20%
my $T = 0.5; # tiempo de madurez en años
my $S0 = 102; # precio corriente

# call option 
my $d1 = (log ($S0/$K) + ($r + $sigma**2/2) * $T) / ($sigma * sqrt($T));
my $d2 = $d1 - $sigma * sqrt($T);
my $phid1 = pnorm($d1);
my $call_price = $S0 * $phid1 - $K * exp(-$r*$T) * pnorm($d2);
say "Call price = $call_price";
# put option 
$d1 = (log ($S0/$K) + ($r + $sigma**2/2) * $T) / ($sigma * sqrt($T));
$d2 = $d1 - $sigma * sqrt($T);
my $phimd1 = pnorm(-$d1);
my $put_price = -$S0 * $phimd1 + $K * exp(-$r*$T) * pnorm(-$d2);
say "Put price = $put_price";
### around 3*10^-6 error

exit 1;


sub pnorm {
# use Math::Trig qw(:pi);
# use bignum qw/e PI/;
    my $z = shift;
#    die "Wrong number as argument" if ($z<=0 || $z=~/\D\D/ || !defined $z);
    my $step = 1/100_000_000;
    my $r = 0.5;
    my $pi2 = 8*atan2(1,1);
# densidad de la distribuci<F3>n normal estandarizada
# Z = (1/sqrt(2*pi))*exp(1)^(-0.5*z*z)
# $pi = 4*atan2(1,1);
    my $static = 1/(100_000_000*sqrt($pi2));
#    my $e = exp(1);
    
    for ( my $i = 0; $i < abs($z); $i += $step ) {
	$r += $static*(exp(-$i*$i/2));
    }
#    $r = sprintf ("%.7f",$r);
#    print "P[Z<=$z] = $r\n";
    if ($z > 0){
	return $r;
    }else{
	my $rleft = 1 - $r;
#	$r -= $rleft;
#    print "P[-$z<=Z<=$z] = $r\n";
	return $rleft;
    }
	
#  Esta utilidad nos devuelve la probabilidad de una tabla N(0,1) de una cola
#  y de dos colas
}
