Real LinearTsrPricer::optionletPrice(Option::Type optionType, Real strike) const { if (optionType == Option::Call && strike >= settings_.upperRateBound_) return 0.0; if (optionType == Option::Put && strike <= settings_.lowerRateBound_) return 0.0; // determine lower or upper integration bound (depending on option type) Real lower = strike, upper = strike; switch (settings_.strategy_) { case Settings::RateBound: { if (optionType == Option::Call) upper = settings_.upperRateBound_; else lower = settings_.lowerRateBound_; break; } case Settings::VegaRatio: { // strikeFromVegaRatio ensures that returned strike is on the // expected side of strike Real bound = strikeFromVegaRatio(settings_.vegaRatio_, optionType, strike); if (optionType == Option::Call) upper = std::min(bound, settings_.upperRateBound_); else lower = std::max(bound, settings_.lowerRateBound_); break; } case Settings::PriceThreshold: { // strikeFromPrice ensures that returned strike is on the expected // side of strike Real bound = strikeFromPrice(settings_.vegaRatio_, optionType, strike); if (optionType == Option::Call) upper = std::min(bound, settings_.upperRateBound_); else lower = std::max(bound, settings_.lowerRateBound_); break; } default: QL_FAIL("Unknown strategy (" << settings_.strategy_ << ")"); } // compute the relevant integral Real result = 0.0; Real tmpBound; if (upper > lower) { tmpBound = std::min(upper, swapRateValue_); if (tmpBound > lower) { result += integrator_->operator()( std::bind1st(std::mem_fun(&LinearTsrPricer::integrand), this), lower, tmpBound); } tmpBound = std::max(lower, swapRateValue_); if (upper > tmpBound) { result += integrator_->operator()( std::bind1st(std::mem_fun(&LinearTsrPricer::integrand), this), tmpBound, upper); } result *= (optionType == Option::Call ? 1.0 : -1.0); } result += singularTerms(optionType, strike); return annuity_ * result * couponDiscountRatio_ * coupon_->accrualPeriod(); }
Real LinearTsrPricer::optionletPrice(Option::Type optionType, Real strike) const { if (optionType == Option::Call && strike >= adjustedUpperBound_) return 0.0; if (optionType == Option::Put && strike <= adjustedLowerBound_) return 0.0; // determine lower or upper integration bound (depending on option type) Real lower = strike, upper = strike; switch (settings_.strategy_) { case Settings::RateBound: { if (optionType == Option::Call) upper = adjustedUpperBound_; else lower = adjustedLowerBound_; break; } case Settings::VegaRatio: { // strikeFromVegaRatio ensures that returned strike is on the // expected side of strike Real bound = strikeFromVegaRatio(settings_.vegaRatio_, optionType, strike); if (optionType == Option::Call) upper = std::min(bound, adjustedUpperBound_); else lower = std::max(bound, adjustedLowerBound_); break; } case Settings::PriceThreshold: { // strikeFromPrice ensures that returned strike is on the expected // side of strike Real bound = strikeFromPrice(settings_.vegaRatio_, optionType, strike); if (optionType == Option::Call) upper = std::min(bound, adjustedUpperBound_); else lower = std::max(bound, adjustedLowerBound_); break; } case Settings::BSStdDevs : { Real atm = smileSection_->atmLevel(); Real atmVol = smileSection_->volatility(atm); Real shift = smileSection_->shift(); Real lowerTmp, upperTmp; if (smileSection_->volatilityType() == ShiftedLognormal) { upperTmp = (atm + shift) * std::exp(settings_.stdDevs_ * atmVol - 0.5 * atmVol * atmVol * smileSection_->exerciseTime()) - shift; lowerTmp = (atm + shift) * std::exp(-settings_.stdDevs_ * atmVol - 0.5 * atmVol * atmVol * smileSection_->exerciseTime()) - shift; } else { Real tmp = settings_.stdDevs_ * atmVol * std::sqrt(smileSection_->exerciseTime()); upperTmp = atm + tmp; lowerTmp = atm - tmp; } upper = std::min(upperTmp - shift, adjustedUpperBound_); lower = std::max(lowerTmp - shift, adjustedLowerBound_); break; } default: QL_FAIL("Unknown strategy (" << settings_.strategy_ << ")"); } // compute the relevant integral Real result = 0.0; Real tmpBound; if (upper > lower) { tmpBound = std::min(upper, swapRateValue_); if (tmpBound > lower) { result += (*integrator_)(integrand_f(this), lower, tmpBound); } tmpBound = std::max(lower, swapRateValue_); if (upper > tmpBound) { result += (*integrator_)(integrand_f(this), tmpBound, upper); } result *= (optionType == Option::Call ? 1.0 : -1.0); } result += singularTerms(optionType, strike); return annuity_ * result * couponDiscountRatio_ * coupon_->accrualPeriod(); }