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; }
MakeSwaption::operator ext::shared_ptr<Swaption>() const { const Calendar& fixingCalendar = swapIndex_->fixingCalendar(); Date refDate = Settings::instance().evaluationDate(); // if the evaluation date is not a business day // then move to the next business day refDate = fixingCalendar.adjust(refDate); if (fixingDate_ == Null<Date>()) fixingDate_ = fixingCalendar.advance(refDate, optionTenor_, optionConvention_); if (exerciseDate_ == Null<Date>()) { exercise_ = ext::shared_ptr<Exercise>(new EuropeanExercise(fixingDate_)); } else { QL_REQUIRE(exerciseDate_ <= fixingDate_, "exercise date (" << exerciseDate_ << ") must be less " "than or equal to fixing date (" << fixingDate_ << ")"); exercise_ = ext::shared_ptr<Exercise>(new EuropeanExercise(exerciseDate_)); } Rate usedStrike = strike_; if (strike_ == Null<Rate>()) { // ATM on curve(s) attached to index QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(), "null term structure set to this instance of " << swapIndex_->name()); ext::shared_ptr<VanillaSwap> temp = swapIndex_->underlyingSwap(fixingDate_); temp->setPricingEngine( ext::shared_ptr<PricingEngine>(new DiscountingSwapEngine( swapIndex_->exogenousDiscount() ? swapIndex_->discountingTermStructure() : swapIndex_->forwardingTermStructure(), false))); usedStrike = temp->fairRate(); } BusinessDayConvention bdc = swapIndex_->fixedLegConvention(); underlyingSwap_ = MakeVanillaSwap(swapIndex_->tenor(), swapIndex_->iborIndex(), usedStrike) .withEffectiveDate(swapIndex_->valueDate(fixingDate_)) .withFixedLegCalendar(swapIndex_->fixingCalendar()) .withFixedLegDayCount(swapIndex_->dayCounter()) .withFixedLegTenor(swapIndex_->fixedLegTenor()) .withFixedLegConvention(bdc) .withFixedLegTerminationDateConvention(bdc) .withType(underlyingType_) .withNominal(nominal_); ext::shared_ptr<Swaption> swaption(new Swaption(underlyingSwap_, exercise_, delivery_)); swaption->setPricingEngine(engine_); return swaption; }
void TreeSwaptionEngine::calculate() const { QL_REQUIRE(arguments_.settlementType==Settlement::Physical, "cash-settled swaptions not priced with tree engine"); QL_REQUIRE(!model_.empty(), "no model specified"); Date referenceDate; DayCounter dayCounter; boost::shared_ptr<TermStructureConsistentModel> tsmodel = boost::dynamic_pointer_cast<TermStructureConsistentModel>(*model_); if (tsmodel) { referenceDate = tsmodel->termStructure()->referenceDate(); dayCounter = tsmodel->termStructure()->dayCounter(); } else { referenceDate = termStructure_->referenceDate(); dayCounter = termStructure_->dayCounter(); } boost::shared_ptr<DiscretizedSwaption> swaption(new DiscretizedSwaption(arguments_, referenceDate, dayCounter)); if (additionalResultCalculator_) { additionalResultCalculator_->setupDiscretizedAsset(swaption); } boost::shared_ptr<Lattice> lattice; if (lattice_) { lattice = lattice_; } else { std::vector<Time> times = swaption->mandatoryTimes(); TimeGrid timeGrid(times.begin(), times.end(), timeSteps_); lattice = model_->tree(timeGrid, additionalResultCalculator_); } std::vector<Time> stoppingTimes(arguments_.exercise->dates().size()); for (Size i=0; i<stoppingTimes.size(); ++i) stoppingTimes[i] = dayCounter.yearFraction(referenceDate, arguments_.exercise->date(i)); swaption->initialize(lattice, stoppingTimes.back()); Time nextExercise = *std::find_if(stoppingTimes.begin(), stoppingTimes.end(), std::bind2nd(std::greater_equal<Time>(), 0.0)); swaption->rollback(nextExercise); results_.value = swaption->presentValue(); if (additionalResultCalculator_) { additionalResultCalculator_->calculateAdditionalResults(); results_.additionalResults = additionalResultCalculator_->additionalResults(); } }
MakeSwaption::operator boost::shared_ptr<Swaption>() const { const Date& evaluationDate = Settings::instance().evaluationDate(); const Calendar& fixingCalendar = swapIndex_->fixingCalendar(); fixingDate_ = fixingCalendar.advance(evaluationDate, optionTenor_, optionConvention_); if (exerciseDate_ == Null<Date>()) { exercise_ = boost::shared_ptr<Exercise>(new EuropeanExercise(fixingDate_)); } else { QL_REQUIRE(exerciseDate_ <= fixingDate_, "exercise date (" << exerciseDate_ << ") must be less " "than or equal to fixing date (" << fixingDate_ << ")"); exercise_ = boost::shared_ptr<Exercise>(new EuropeanExercise(exerciseDate_)); } Rate usedStrike = strike_; if (strike_ == Null<Rate>()) { // ATM on the forecasting curve QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(), "null term structure set to this instance of " << swapIndex_->name()); boost::shared_ptr<VanillaSwap> temp = swapIndex_->underlyingSwap(fixingDate_); temp->setPricingEngine(boost::shared_ptr<PricingEngine>( new DiscountingSwapEngine( swapIndex_->forwardingTermStructure(), false))); usedStrike = temp->fairRate(); } BusinessDayConvention bdc = swapIndex_->fixedLegConvention(); underlyingSwap_ = MakeVanillaSwap(swapIndex_->tenor(), swapIndex_->iborIndex(), usedStrike) .withEffectiveDate(swapIndex_->valueDate(fixingDate_)) .withFixedLegCalendar(swapIndex_->fixingCalendar()) .withFixedLegDayCount(swapIndex_->dayCounter()) .withFixedLegConvention(bdc) .withFixedLegTerminationDateConvention(bdc); boost::shared_ptr<Swaption> swaption(new Swaption(underlyingSwap_, exercise_, delivery_)); swaption->setPricingEngine(engine_); return swaption; }