IMPLIED VOLATILITY FOR BLACK-SCHOLES MODEL

  • Thread starter Thread starter Jaysam
  • Start date Start date
Joined
5/15/13
Messages
1
Points
11
Hi all, I'm new in this forum amd and I'm stuck by an issue I can't solve.

I want to coding the implied volatility in a Black-Scholes model, given the initial spot, a strike varying from 0 to 100, a risk-free rate, a time-to-maturity and a given observed call price.
But I remark that after strike 20, the implied vol is totally wrong. It should be still flat since it's constant. So what`s wrong with my coding please?
Code:
#ifndef _FORMULA_PRICER_
#define _FORMULA_PRICER_
 
class Formula_Pricer
{
public:
static double Call_BS(double Spot, double Strike, double Volatility, double TimeToMaturity, double RiskFreeRate);
 
static double N(double x);
static double Vega_BS(double Spot, double Strike, double Volatility, double TimeToMaturity, double RiskFreeRate);
 
 
static double Implied_Vol_BS(const double& Spot, const double& Strike, const double& TimeToMaturity, const double& RiskFreeRate, const double& Obs_OptionPrice);
 
static double d1(double Spot, double Strike, double Volatility, double TimeToMaturity, double RiskFreeRate)
 
static double d2(double Spot, double Strike, double Volatility, double TimeToMaturity, double RiskFreeRate);
 
};
 
#endif
 
double Formula_Pricer::Implied_Vol_BS(const double& Spot, const double& Strike, const double& TimeToMaturity, const double& RiskFreeRate, const double& Obs_OptionPrice) {
 
if (Obs_OptionPrice<(0.99*(Spot-Strike*exp(-TimeToMaturity*RiskFreeRate)))) { // check for arbitrage violations. Option price is too low if this happens
return 0.0;
};
 
int MAX_ITERATIONS = 100;
const double ACCURACY = 1.0e-5;
double t_sqrt = sqrt(TimeToMaturity);
double sigma = (Obs_OptionPrice/Spot)/(0.4*t_sqrt); // find initial value
for (int i=0;i<MAX_ITERATIONS;i++){
double price = Call_BS(Spot, Strike, sigma, TimeToMaturity, RiskFreeRate);
 
double diff = Obs_OptionPrice - price;
double abs = fabs(diff);
if (abs<ACCURACY)
return sigma;
double vega = Vega_BS(Spot, Strike, sigma, TimeToMaturity, RiskFreeRate);
sigma = sigma + diff/vega;
};
return -99e10; // something screwy happened, should throw exception
 
};
Notice that I implicitly computed my vega ie instead of Vega = Spot * sqrt(Maturity) * N'(d1);
I computed Vega = Spot * sqrt(Maturity) * exp(-d1*d1/2) / (sqrt(2*pi)) as follows :
Code:
double Formula_Pricer::Vega_BS(double Spot, double Strike, double Volatility, double TimeToMaturity, double RiskFreeRate)
{
double d = d1(Spot, Strike, Volatility, TimeToMaturity, RiskFreeRate);
double Vega = (Spot * sqrt(TimeToMaturity) * exp(-d * d/2. )) / (sqrt(2.*Pi));
return Vega;
 
}
And my test main is:
Code:
double spt = 10., mat = 10., vol = 0.1, rate = 0.04;
 
std::vector<double> dx(100);
std::vector<double> dy(100);
std::vector<double> Call(100);
std::vector<double> Vega(100);
std::vector<double> Imp_Vol(100);
 
 
for(int strk = 0; strk < 100; strk++)
{
dx[strk] = Formula_Pricer::d1(spt, strk, vol, mat, rate);
dy[strk] = Formula_Pricer::d2(spt, strk, vol, mat, rate);
Call[strk] = Formula_Pricer::Call_BS(spt, strk, vol, mat, rate);
Vega[strk] = Formula_Pricer::Vega_BS(spt, strk, vol, mat, rate);
Imp_Vol[strk] = Formula_Pricer::Implied_Vol_BS(spt, strk, mat, rate, Call[strk]);
 
}
Thank you very much for your help.
 
Code is not documented in any form; are you using Newton?
Can you explain line 41. Who knows, you might have got the sign wrong!

The underlying maths is missing, so it's difficult to debug.

Is the initial seed good enough?

//
 
  1. for (int i=0;i<MAX_ITERATIONS;i++){
  2. price = Call_BS(Spot, Strike, sigma, TimeToMaturity, RiskFreeRate);
  3. diff = Obs_OptionPrice - price;
  4. myAbs = std::abs(diff);
  5. if (std::abs<ACCURACY)
  6. return sigma;
I would use a 1) do .. while or 2) goto label instead of for loop.
 
Back
Top Bottom