First caveat: I'm a programmer doing this for a client, and my knowledge of options probably has holes in it. So be a little forgiving here. =)

The Issue: When I run Black Scholes Newton against all options in a chain, I occasionally get NaN return values. My comparison for accuracy is against ThinkorSwim's numbers.

Here are screencaps of the issue: http://imgur.com/a/cItIj

spot, strike, time, etc, are all there. And most of the time the numbers are accurate. But once I hit certain ranges with Calls and Puts, I get those NaN's, and I can't seem to figure out the pattern as to why

I'm using garagebandhedgefund's code as a base, with adjustments for puts/calls.

Here's the Newton Code:

 public static double OptionPriceImpliedVolatilityCallBlackScholesNewton(double S, double K, double r, double time, double optionPrice,bool iscall, bool isput,out double price,out double diff)
        price = 0;
        diff = 0;
        int MAX_ITERATIONS = 100;
        double ACCURACY = 1.0e-5;
        double t_sqrt = Math.Sqrt(time);
        double sigma = (optionPrice / S) / (0.398 * t_sqrt);    // find initial value  
         price = 0;
        for (int i = 0; i < MAX_ITERATIONS; i++)
            if (iscall)
                 price = OptionPriceCallBlackScholes(S, K, r, sigma, time);
            if (isput)
                 price = OptionPricePutBlackScholes(S, K, r, sigma, time);
            diff = optionPrice - price;
            if (Math.Abs(diff) < ACCURACY)
                return sigma;
            double d1 = (Math.Log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
            double vega = (S * t_sqrt * NormDist(d1));
            sigma = sigma + diff / vega;
        return sigma;  // something screwy happened, should throw exception  // <--- original code  
        //throw new Exception("An error occurred"); // Comment this line if you uncomment the line above  

My question: Is it my code? Is it certain ranges of values? Are there cases where Newton fails to return valid values? I'm kinda stumped here.

For the record, when I use this data against garageband's Bisection code, I get errors across the board. I don't know if that's related. I'm fairly certain of the accuracy of my input data, since I do get some valid returns with Newton.


Some option prices can't be converted to volatility. E.g. A bid for an in-the-money call which is below its intrinsic value. So sometimes NaN is a valid answer. Best way to handle it is to do precursory checks before going down to the search loop.


.NET doubles return double.NaN when you do things like divide zero by zero. With doubles, anything less than double.Epsilon is "zero" for the purpose of this result.

I suggest that your vega is less than double.Epsilon

What happens if you run the same method using decimal instead?

  • $\begingroup$ I converted everything to decimal, but just wound up with either 'divide by zero' or 'number too large/small for decimal' So the problem is with the Vega being generated. As a band-aid, I set minimum/maximum range checking. $\endgroup$ – The One Rob Nov 6 '14 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.