Real Gaussian1dSmileSection::optionPrice(Rate strike, Option::Type type, Real discount) const { if (swapIndex_ != NULL) { Swaption s = MakeSwaption(swapIndex_, fixingDate_, strike) .withUnderlyingType(type == Option::Call ? VanillaSwap::Payer : VanillaSwap::Receiver) .withPricingEngine(engine_); Real tmp = s.NPV(); return tmp / annuity_ * discount; } else { CapFloor c = MakeCapFloor(type == Option::Call ? CapFloor::Cap : CapFloor::Floor, iborIndex_->tenor(), iborIndex_, strike, 0 * Days) .withEffectiveDate(fixingDate_, false) .withPricingEngine(engine_); Real tmp = c.NPV(); return tmp / annuity_ * discount; } }
Gaussian1dSmileSection::Gaussian1dSmileSection( const Date &fixingDate, const boost::shared_ptr<IborIndex> &iborIndex, const boost::shared_ptr<Gaussian1dModel> &model, const DayCounter &dc, const boost::shared_ptr<Gaussian1dCapFloorEngine> capEngine) : SmileSection(fixingDate, dc, model->termStructure()->referenceDate()), fixingDate_(fixingDate), swapIndex_(boost::shared_ptr<SwapIndex>()), iborIndex_(iborIndex), model_(model), engine_(capEngine) { atm_ = model_->forwardRate(fixingDate_, Null<Date>(), 0.0, iborIndex_); CapFloor c = MakeCapFloor(CapFloor::Cap, iborIndex_->tenor(), iborIndex_, Null<Real>(), 0 * Days).withEffectiveDate(fixingDate_, false); annuity_ = iborIndex_->dayCounter().yearFraction(c.startDate(), c.maturityDate()) * model_->zerobond(c.maturityDate()); if (engine_ == NULL) { engine_ = boost::make_shared<Gaussian1dCapFloorEngine>( model_, 64, 7.0, true, false); // use model curve as discounting curve } }
void OptionletStripper2::performCalculations() const { //// optionletStripper data optionletDates_ = stripper1_->optionletFixingDates(); optionletPaymentDates_ = stripper1_->optionletPaymentDates(); optionletAccrualPeriods_ = stripper1_->optionletAccrualPeriods(); optionletTimes_ = stripper1_->optionletFixingTimes(); atmOptionletRate_ = stripper1_->atmOptionletRates(); for (Size i=0; i<optionletTimes_.size(); ++i) { optionletStrikes_[i] = stripper1_->optionletStrikes(i); optionletVolatilities_[i] = stripper1_->optionletVolatilities(i); } // atmCapFloorTermVolCurve data const std::vector<Period>& optionExpiriesTenors = atmCapFloorTermVolCurve_->optionTenors(); const std::vector<Time>& optionExpiriesTimes = atmCapFloorTermVolCurve_->optionTimes(); for (Size j=0; j<nOptionExpiries_; ++j) { Volatility atmOptionVol = atmCapFloorTermVolCurve_->volatility( optionExpiriesTimes[j], 33.3333); // dummy strike boost::shared_ptr<BlackCapFloorEngine> engine(new BlackCapFloorEngine(iborIndex_->forwardingTermStructure(), atmOptionVol, dc_)); caps_[j] = MakeCapFloor(CapFloor::Cap, optionExpiriesTenors[j], iborIndex_, Null<Rate>(), 0*Days).withPricingEngine(engine); atmCapFloorStrikes_[j] = caps_[j]->atmRate(**iborIndex_->forwardingTermStructure()); atmCapFloorPrices_[j] = caps_[j]->NPV(); } spreadsVolImplied_ = spreadsVolImplied(); StrippedOptionletAdapter adapter(stripper1_); Volatility unadjustedVol, adjustedVol; for (Size j=0; j<nOptionExpiries_; ++j) { for (Size i=0; i<optionletVolatilities_.size(); ++i) { if (i<=caps_[j]->floatingLeg().size()) { unadjustedVol = adapter.volatility(optionletTimes_[i], atmCapFloorStrikes_[j]); adjustedVol = unadjustedVol + spreadsVolImplied_[j]; // insert adjusted volatility std::vector<Rate>::const_iterator previous = std::lower_bound(optionletStrikes_[i].begin(), optionletStrikes_[i].end(), atmCapFloorStrikes_[j]); Size insertIndex = previous - optionletStrikes_[i].begin(); optionletStrikes_[i].insert( optionletStrikes_[i].begin() + insertIndex, atmCapFloorStrikes_[j]); optionletVolatilities_[i].insert( optionletVolatilities_[i].begin() + insertIndex, adjustedVol); } } } }