Example #1
0
        public double volatility(double strike, VolatilityType volatilityType, double shift = 0.0)
        {
            if (volatilityType == volatilityType_ && Utils.close(shift, this.shift()))
            {
                return(volatility(strike));
            }
            double?atm = atmLevel();

            Utils.QL_REQUIRE(atm != null, () => "smile section must provide atm level to compute converted volatilties");
            Option.Type type       = strike >= atm ? Option.Type.Call : Option.Type.Put;
            double      premium    = optionPrice(strike, type);
            double      premiumAtm = optionPrice(atm.Value, type);

            if (volatilityType == VolatilityType.ShiftedLognormal)
            {
                try
                {
                    return(Utils.blackFormulaImpliedStdDev(type, strike, atm.Value, premium, 1.0, shift) /
                           Math.Sqrt(exerciseTime()));
                }
                catch (Exception)
                {
                    return(Utils.blackFormulaImpliedStdDevChambers(type, strike, atm.Value, premium, premiumAtm, 1.0, shift) /
                           Math.Sqrt(exerciseTime()));
                }
            }
            else
            {
                return(Utils.bachelierBlackFormulaImpliedVol(type, strike, atm.Value, exerciseTime(), premium));
            }
        }