private double volFromFormulaPrice(double r, double q, double time, double strike, NodalSurface surface) { double p = surface.zValue(time, strike); double pT = 0.5 / FD_EPS * (surface.zValue(time + FD_EPS, strike) - surface.zValue(time - FD_EPS, strike)); double pK = 0.5 / FD_EPS * (surface.zValue(time, strike + FD_EPS) - surface.zValue(time, strike - FD_EPS)); double pKK = (surface.zValue(time, strike + FD_EPS) + surface.zValue(time, strike - FD_EPS) - 2d * p) / FD_EPS / FD_EPS; double var = 2d * (pT + (r - q) * strike * pK + q * p) / (strike * strike * pKK); return(Math.Sqrt(var)); }
private double volFromFormula(double r, double q, double time, double strike, NodalSurface surface) { double vol = surface.zValue(time, strike); double volT = 0.5 / FD_EPS * (surface.zValue(time + FD_EPS, strike) - surface.zValue(time - FD_EPS, strike)); double volK = 0.5 / FD_EPS * (surface.zValue(time, strike + FD_EPS) - surface.zValue(time, strike - FD_EPS)); double volKK = (surface.zValue(time, strike + FD_EPS) + surface.zValue(time, strike - FD_EPS) - 2d * vol) / FD_EPS / FD_EPS; double rootT = Math.Sqrt(time); double d1 = (Math.Log(SPOT / strike) + (r - q + 0.5 * vol * vol) * time) / vol / rootT; double d2 = (Math.Log(SPOT / strike) + (r - q - 0.5 * vol * vol) * time) / vol / rootT; double den = 1d + 2d * d1 * strike * rootT * volK + strike * strike * time * (d1 * d2 * volK * volK + vol * volKK); double var = (vol * vol + 2d * vol * time * (volT + (r - q) * strike * volK)) / den; return(Math.Sqrt(var)); }