
/**
 * Computes the value of a european call option.
 * The algorithm is drawn from
 *   "Options, Futures, and other Derivative Securities", 2nd edition,
 *    by John C. Hull (Prentice-Hall, 1993), pages 226-227.
 */
public class BlackScholes
{
    private double S;
    private double s;
    private double X;
    private int    n;
    private double r;
    private double t;
    
    BlackScholes( double stock_price,
                  double stock_volatility,
                  double strike_price,
                  int    number_of_shares_optioned,
                  double interest_rate_for_maturity,
                  double years_to_option_maturity )
    {
        S = stock_price;
        s = stock_volatility;
        X = strike_price;
        n = number_of_shares_optioned;
        r = interest_rate_for_maturity;
        t = years_to_option_maturity;
    }

    /**
     * Returns the value of this European call option.
     */
    public double value() {
        final double sst = s*Math.sqrt(t);
        final double d1 = (Math.log(S/X) + (r + s*s/2)*t)/sst;
        final double d2 = d1 - sst;
        return n * (S*N(d1) - X*Math.exp(-r*t)*N(d2));
    }
    
    /** N
     * N(x) returns the probability of a random variable drawn from a
     * standard normal distribution (mean=0, s.dev=1) being less than or
     * equal to x.
     * The Algorithm used here is a polynomial approximation accurate to
     * six decimal places drawn from
     
     */
    private double N(double x) {
        if( x < 0 )
            return 1 - N(-x);
        
        
        final double k  = 1/(1+g*x);
        final double np = Math.exp(-x*x/2)/s2pi;
        double m = k*(a1 + k*(a2 + k*(a3 + k*(a4 + k*(a5)))));           
        return 1 - np*m;
    }
    
    private final static double g  =  0.231641900;
    private final static double a1 =  0.319381530;
    private final static double a2 = -0.356563782;
    private final static double a3 =  1.781477937;
    private final static double a4 = -1.821255978;
    private final static double a5 =  1.330274429;
    private final static double s2pi = Math.sqrt(Math.PI*2);
}
