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: https://i.sstatic.net/B0vYN.jpg
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.