public double ImpliedVolatility(ConstantValues.xOptionType argvOptionType, double argvUnderlyingPrice, double argvStrike, double argvTimeToMaturity, double argvYield , double argvRiskFreeRate, double argvOptionPrice, double argvUpperVol) { double tImpliedVolatility = 0.0; double tUpperVol = argvUpperVol; double tLowerVol = 0.000001; double tPrice = this.Price(argvOptionType, argvUnderlyingPrice, argvStrike, argvTimeToMaturity, argvYield, argvRiskFreeRate, tUpperVol); if (argvOptionPrice > tPrice) { tImpliedVolatility = argvUpperVol; } else { while (tUpperVol - tLowerVol > 0.000001) { tImpliedVolatility = (tUpperVol + tLowerVol) / 2; tPrice = this.Price(argvOptionType, argvUnderlyingPrice, argvStrike, argvTimeToMaturity, argvYield, argvRiskFreeRate, tImpliedVolatility); if (tPrice > argvOptionPrice) { tUpperVol = tImpliedVolatility; } else { tLowerVol = tImpliedVolatility; } } } return(tImpliedVolatility); }
public double Price(ConstantValues.xOptionType argvOptionType, double argvUnderlyingPrice, double argvStrike, double argvTimeToMaturity, double argvYield , double argvRiskFreeRate, double argvVolatility) { double d1 = 0.0; double d2 = 0.0; double tPrice = 0.0; int tOptionTypeMultiplier = 1; if (argvOptionType == ConstantValues.xOptionType.Put) { tOptionTypeMultiplier = -1; } if (argvTimeToMaturity == 0) { tPrice = Math.Max((argvUnderlyingPrice - argvStrike) * tOptionTypeMultiplier, 0); } else if (argvTimeToMaturity < 0) { tPrice = 0; } else { d1 = (Math.Log(argvUnderlyingPrice / argvStrike) + (argvRiskFreeRate - argvYield + argvVolatility * argvVolatility / 2.0) * argvTimeToMaturity) / (argvVolatility * Math.Sqrt(argvTimeToMaturity)); d2 = d1 - argvVolatility * Math.Sqrt(argvTimeToMaturity); tPrice = Math.Exp(-argvYield * argvTimeToMaturity) * tOptionTypeMultiplier * argvUnderlyingPrice * StandardNormalCumulativeDistribution(d1 * tOptionTypeMultiplier) - Math.Exp(-argvRiskFreeRate * argvTimeToMaturity) * tOptionTypeMultiplier * argvStrike * StandardNormalCumulativeDistribution(d2 * tOptionTypeMultiplier); } return(tPrice); }