Real HullWhiteSmileSection::volatilityImpl(Rate strike) const { boost::shared_ptr<VanillaSwap> underlying = MakeVanillaSwap(swapLength_,swapIndex_->iborIndex(),strike) .withEffectiveDate(swapIndex_->valueDate(optionDate_)) .withFixedLegCalendar(swapIndex_->fixingCalendar()) .withFixedLegDayCount(swapIndex_->dayCounter()) .withFixedLegTenor(swapIndex_->fixedLegTenor()) .withFixedLegConvention(swapIndex_->fixedLegConvention()) .withFixedLegTerminationDateConvention(swapIndex_->fixedLegConvention()) .withType(VanillaSwap::Payer); underlying->setPricingEngine(discountingEngine_); boost::shared_ptr<Exercise> exercise(new EuropeanExercise(optionDate_)); Swaption swaption(underlying,exercise); swaption.setPricingEngine(jamshidianEngine_); Real npv = swaption.NPV(); Real annuity = fabs(underlying->fixedLegBPS() * 10000.0); //Real blackNpv=blackFormula(Option::Call,strike,atm,0.30*sqrt(exerciseTime())); //std::cout << std::setprecision(8) << "SECTION atm=" << atm_ << " annuity=" << annuity << " npv=" << npv << " strike= " << strike << std::endl; Real vol=0.0; try { vol=blackFormulaImpliedStdDev(Option::Call,strike,atm_,npv,annuity) / sqrt(exerciseTime()); } catch(QuantLib::Error) { //std::cout << " can not imply vol for npv " << npv << " black(300%)=" << blackFormula(Option::Call,strike,atm_,sqrt(exerciseTime())*3.00,annuity) << // " black(1%)=" << blackFormula(Option::Call,strike,atm_,sqrt(exerciseTime())*0.01,annuity) << std::endl; if(npv>blackFormula(Option::Call,strike,atm_,3.00,annuity)) vol =3.0/sqrt(exerciseTime()); else vol=0.0; } return vol; }
Real SmileSection::volatility(Rate strike, VolatilityType volatilityType, Real shift) const { if(volatilityType == volatilityType_ && close(shift,this->shift())) return volatility(strike); Real atm = atmLevel(); QL_REQUIRE(atm != Null<Real>(), "smile section must provide atm level to compute converted volatilties"); Option::Type type = strike >= atm ? Option::Call : Option::Put; Real premium = optionPrice(strike,type); Real premiumAtm = optionPrice(atm,type); if (volatilityType == ShiftedLognormal) { try { return blackFormulaImpliedStdDev(type, strike, atm, premium, 1.0, shift) / std::sqrt(exerciseTime()); } catch(...) { return blackFormulaImpliedStdDevChambers( type, strike, atm, premium, premiumAtm, 1.0, shift) / std::sqrt(exerciseTime()); } } else { return bachelierBlackFormulaImpliedVol(type, strike, atm, exerciseTime(), premium); } }
Real BdkSmileSection::volatilityImpl(Rate strike) const { Real vol = 0.0; try { vol = blackFormulaImpliedStdDev(Option::Call, strike, f_, optionPrice(strike)) / sqrt(source_->exerciseTime()); } catch (QuantLib::Error) { } return vol; }
Real Gaussian1dSmileSection::volatilityImpl(Rate strike) const { Real vol = 0.0; try { Option::Type type = strike >= atm_ ? Option::Call : Option::Put; Real o = optionPrice(strike, type); vol = blackFormulaImpliedStdDev(type, strike, atm_, o) / sqrt(exerciseTime()); } catch (...) { } return vol; }
Real KahaleSmileSection::volatilityImpl(Rate strike) const { strike = std::max ( strike, QL_KAHALE_EPS ); int i = index(strike); if(!interpolate_ && !(i==0 || i==(int) (rightIndex_-leftIndex_+1))) return source_->volatility(strike); Real c = cFunctions_[i]->operator()(strike); Real vol=0.0; try { vol = blackFormulaImpliedStdDev(Option::Call,strike,f_,c) / sqrt(exerciseTime()); } catch(...) { } return vol; }
Real blackFormulaImpliedStdDev( const boost::shared_ptr<PlainVanillaPayoff>& payoff, Real forward, Real blackPrice, Real discount, Real displacement, Real guess, Real accuracy, Natural maxIterations) { return blackFormulaImpliedStdDev(payoff->optionType(), payoff->strike(), forward, blackPrice, discount, displacement, guess, accuracy, maxIterations); }
void ImpliedStdDevQuote::performCalculations() const { static const Real discount = 1.0; static const Real displacement = 0.0; Real blackPrice = price_->value(); try { impliedStdev_ = blackFormulaImpliedStdDev(optionType_, strike_, forward_->value(), blackPrice, discount, displacement, impliedStdev_, accuracy_, maxIter_); } catch(Error&) { impliedStdev_ = 0.0; } }
Real SplineDensitySmileSection::volatilityImpl(Rate strike) const { strike = std::max(strike,0.00001); // assume only non shifted lognormal // here ... TODO later ... (should be // shifted lognormal with shift equal // to minus lowerBound_ Option::Type type = strike >= f_ ? Option::Call : Option::Put; Real p = optionPrice(strike,type); Real vol = 0.0; try { vol = blackFormulaImpliedStdDev(type, strike, f_, p) / sqrt(exerciseTime()); } catch (...) { } return vol; }
Real NoArbSabrSmileSection::volatilityImpl(Rate strike) const { Real impliedVol = 0.0; try { Option::Type type; if (strike >= forward_) type = Option::Call; else type = Option::Put; impliedVol = blackFormulaImpliedStdDev(type, strike, forward_, optionPrice(strike, type, 1.0), 1.0) / std::sqrt(exerciseTime()); } catch (...) { } if (impliedVol == 0.0) // fall back on Hagan 2002 expansion impliedVol = unsafeSabrVolatility(strike, forward_, exerciseTime(), params_[0], params_[1], params_[2], params_[3]); return impliedVol; }