I am trying to use Newtons method to find implied volatility of a Black Scholes Call. So given all the other variables, I need to find what volatility makes the black scholes call equal to the current call price. I'm running what I have below but keep getting a random string returned. I tested the black function and that is working right. Any thoughts?
http://en.wikipedia.org/wiki/Newton%27s_method
http://en.wikipedia.org/wiki/Black_scholes
// black_scholesC.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double cum_dist_normal(double t);
double black(double S, double K, double T, double vol, double r, double q);
double vega(double S, double K, double T, double vol, double r, double q);
int _tmain(int argc, _TCHAR* argv[])
{
double C = 2.50;
double S = 30;
double K = 30;
double T = 180;
double q = 0.01;
double r = 0.03;
double tol = 10E-6;
double vol = 0.25;
double xnew = vol;
double xold = vol - 1.0;
while (abs(xnew-xold) > tol)
{
xold = xnew;
xnew = xnew - (black(S, K, T, xnew, r, q)/vega(S, K, T, xnew, r, q));
}
cout << xnew << endl;
return 0;
}
double cum_dist_normal(double t)
{
const double PI = 3.141592;
double z = abs(t);
double y = (1.0/(1.0 + 0.2316419*z));
double a1 = 0.31938150;
double a2 = -0.356563782;
double a3 = 1.781477937;
double a4 = -1.821255978;
double a5 = 1.330274429;
double m = 1.0 - ((exp(-(pow(t, 2.0)/2.0))*(a1*y + a2*pow(y, 2) + a3*pow(y, 3) + a4*pow(y, 4) + a5*pow(y, 5)))/sqrt(2*PI));
double nm;
if (t>0)
nm = m;
else
nm = 1.0 - m;
return nm;
}
double black(double S, double K, double T, double vol, double r, double q)
{
double d1 = (log(S/K) + (r - q + (pow(vol, 2)/2)*T))/(vol*sqrt(T));
double d2 = d1 - vol*sqrt(T);
double cblack = S*exp(-(q*T))*cum_dist_normal(d1) - (K*exp(-(r*T))*cum_dist_normal(d2));
return cblack;
}
double vega(double S, double K, double T, double vol, double r, double q)
{
const double PI = 3.141592;
double d1 = (log(S/K) + (r - q + (pow(vol, 2)/2)*T))/(vol*sqrt(T));
double vegaC = (1.0/sqrt(2*PI))*(S*exp(-q*T))*(exp(-(pow(d1, 2))))*sqrt(T);
return vegaC;
}