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?
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 :
And my test main is:
Thank you very much for your help.
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
};
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;
}
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]);
}