45 ext::optional<bool> useIndexedCoupon)
46 : capletVol_(
std::move(
v)),
47 useIndexedCoupon_(useIndexedCoupon ?
68 Date nextFixingDate = coupon.
iborIndex()->fixingCalendar().advance(
82 "\n cannot calculate forward rate between "
84 <<
":\n non positive time (" << coupon.
spanningTime_ <<
") using "
85 << coupon.
iborIndex()->dayCounter().name() <<
" daycounter");
123 if (rateCurve.
empty()) {
127 if (paymentDate > rateCurve->referenceDate())
128 discount_ = rateCurve->discount(paymentDate);
146 return std::max(a -
b, 0.0);
150 "missing optionlet volatility");
168 Real effStrike)
const {
192 "missing optionlet volatility");
195 if (d1 <= referenceDate)
204 Spread adjustment = shiftedLn
205 ?
Real((fixing + shift) * (fixing + shift) *
206 variance * tau / (1.0 + fixing * tau))
212 const Date& d5 = d4 >= d3 ? d3 : d2;
213 Time tau2 =
index_->dayCounter().yearFraction(d5, d4);
220 (
index_->forwardingTermStructure()->discount(d5) /
221 index_->forwardingTermStructure()->discount(d4) -
224 adjustment -= shiftedLn
226 (fixing + shift) * (fixing2 + shift) /
227 (1.0 + fixing2 * tau2))
229 (1.0 + fixing2 * tau2));
232 return fixing + adjustment;
244 public Visitor<FloatingRateCoupon>,
245 public Visitor<CappedFlooredCoupon>,
248 public Visitor<CmsSpreadCoupon>,
249 public Visitor<CappedFlooredIborCoupon>,
250 public Visitor<CappedFlooredCmsCoupon>,
251 public Visitor<CappedFlooredCmsSpreadCoupon>,
252 public Visitor<DigitalIborCoupon>,
253 public Visitor<DigitalCmsCoupon>,
254 public Visitor<DigitalCmsSpreadCoupon>,
255 public Visitor<RangeAccrualFloatersCoupon>,
256 public Visitor<MultipleResetsCoupon> {
258 ext::shared_ptr<FloatingRateCouponPricer>
pricer_;
260 explicit PricerSetter(ext::shared_ptr<FloatingRateCouponPricer> pricer)
263 void visit(CashFlow& c)
override;
264 void visit(Coupon& c)
override;
265 void visit(FloatingRateCoupon& c)
override;
266 void visit(CappedFlooredCoupon& c)
override;
267 void visit(IborCoupon& c)
override;
268 void visit(CappedFlooredIborCoupon& c)
override;
269 void visit(DigitalIborCoupon& c)
override;
270 void visit(CmsCoupon& c)
override;
271 void visit(CmsSpreadCoupon& c)
override;
272 void visit(CappedFlooredCmsCoupon& c)
override;
273 void visit(CappedFlooredCmsSpreadCoupon& c)
override;
274 void visit(DigitalCmsCoupon& c)
override;
275 void visit(DigitalCmsSpreadCoupon& c)
override;
276 void visit(RangeAccrualFloatersCoupon& c)
override;
277 void visit(MultipleResetsCoupon& c)
override;
280 void PricerSetter::visit(CashFlow&) {
284 void PricerSetter::visit(Coupon&) {
288 void PricerSetter::visit(FloatingRateCoupon& c) {
292 void PricerSetter::visit(CappedFlooredCoupon& c) {
296 if (ext::dynamic_pointer_cast<IborCoupon>(c.underlying()) !=
nullptr) {
298 "pricer not compatible with Ibor Coupon");
299 }
else if (ext::dynamic_pointer_cast<CmsCoupon>(c.underlying()) !=
nullptr) {
301 "pricer not compatible with CMS Coupon");
302 }
else if (ext::dynamic_pointer_cast<CmsSpreadCoupon>(c.underlying()) !=
nullptr) {
304 "pricer not compatible with CMS spread Coupon");
309 void PricerSetter::visit(IborCoupon& c) {
310 const ext::shared_ptr<IborCouponPricer> iborCouponPricer =
311 ext::dynamic_pointer_cast<IborCouponPricer>(
pricer_);
313 "pricer not compatible with Ibor coupon");
314 c.setPricer(iborCouponPricer);
317 void PricerSetter::visit(DigitalIborCoupon& c) {
318 const ext::shared_ptr<IborCouponPricer> iborCouponPricer =
319 ext::dynamic_pointer_cast<IborCouponPricer>(
pricer_);
321 "pricer not compatible with Ibor coupon");
322 c.setPricer(iborCouponPricer);
325 void PricerSetter::visit(CappedFlooredIborCoupon& c) {
326 const ext::shared_ptr<IborCouponPricer> iborCouponPricer =
327 ext::dynamic_pointer_cast<IborCouponPricer>(
pricer_);
329 "pricer not compatible with Ibor coupon");
330 c.setPricer(iborCouponPricer);
333 void PricerSetter::visit(CmsCoupon& c) {
334 const ext::shared_ptr<CmsCouponPricer> cmsCouponPricer =
335 ext::dynamic_pointer_cast<CmsCouponPricer>(
pricer_);
337 "pricer not compatible with CMS coupon");
338 c.setPricer(cmsCouponPricer);
341 void PricerSetter::visit(CmsSpreadCoupon& c) {
342 const ext::shared_ptr<CmsSpreadCouponPricer> cmsSpreadCouponPricer =
343 ext::dynamic_pointer_cast<CmsSpreadCouponPricer>(
pricer_);
345 "pricer not compatible with CMS spread coupon");
346 c.setPricer(cmsSpreadCouponPricer);
349 void PricerSetter::visit(CappedFlooredCmsCoupon& c) {
350 const ext::shared_ptr<CmsCouponPricer> cmsCouponPricer =
351 ext::dynamic_pointer_cast<CmsCouponPricer>(
pricer_);
353 "pricer not compatible with CMS coupon");
354 c.setPricer(cmsCouponPricer);
357 void PricerSetter::visit(CappedFlooredCmsSpreadCoupon& c) {
358 const ext::shared_ptr<CmsSpreadCouponPricer> cmsSpreadCouponPricer =
359 ext::dynamic_pointer_cast<CmsSpreadCouponPricer>(
pricer_);
361 "pricer not compatible with CMS spread coupon");
362 c.setPricer(cmsSpreadCouponPricer);
365 void PricerSetter::visit(DigitalCmsCoupon& c) {
366 const ext::shared_ptr<CmsCouponPricer> cmsCouponPricer =
367 ext::dynamic_pointer_cast<CmsCouponPricer>(
pricer_);
369 "pricer not compatible with CMS coupon");
370 c.setPricer(cmsCouponPricer);
373 void PricerSetter::visit(DigitalCmsSpreadCoupon& c) {
374 const ext::shared_ptr<CmsSpreadCouponPricer> cmsSpreadCouponPricer =
375 ext::dynamic_pointer_cast<CmsSpreadCouponPricer>(
pricer_);
377 "pricer not compatible with CMS spread coupon");
378 c.setPricer(cmsSpreadCouponPricer);
381 void PricerSetter::visit(RangeAccrualFloatersCoupon& c) {
382 const ext::shared_ptr<RangeAccrualPricer> rangeAccrualPricer =
383 ext::dynamic_pointer_cast<RangeAccrualPricer>(
pricer_);
385 "pricer not compatible with range-accrual coupon");
386 c.setPricer(rangeAccrualPricer);
389 void PricerSetter::visit(MultipleResetsCoupon& c) {
390 const ext::shared_ptr<MultipleResetsPricer> pricer =
391 ext::dynamic_pointer_cast<MultipleResetsPricer>(
pricer_);
392 QL_REQUIRE(pricer,
"pricer not compatible with multiple-resets coupon");
396 void setCouponPricersFirstMatching(
const Leg& leg,
397 const std::vector<ext::shared_ptr<FloatingRateCouponPricer> >& p) {
398 std::vector<PricerSetter> setter;
399 setter.reserve(p.size());
400 for (
const auto& i : p) {
401 setter.emplace_back(i);
403 for (
const auto& i : leg) {
407 i->accept(setter[j]);
412 }
while (j < p.size());
419 PricerSetter setter(pricer);
420 for (
const auto& i : leg) {
427 const std::vector<ext::shared_ptr<FloatingRateCouponPricer> >&
429 Size nCashFlows = leg.size();
432 Size nPricers = pricers.size();
434 "mismatch between leg size (" << nCashFlows <<
435 ") and number of pricers (" << nPricers <<
")");
437 for (
Size i=0; i<nCashFlows; ++i) {
438 PricerSetter setter(i<nPricers ? pricers[i] : pricers[nPricers-1]);
439 leg[i]->accept(setter);
445 const ext::shared_ptr<FloatingRateCouponPricer>& p1,
446 const ext::shared_ptr<FloatingRateCouponPricer>& p2) {
447 std::vector<ext::shared_ptr<FloatingRateCouponPricer> > p;
450 setCouponPricersFirstMatching(leg, p);
455 const ext::shared_ptr<FloatingRateCouponPricer>& p1,
456 const ext::shared_ptr<FloatingRateCouponPricer>& p2,
457 const ext::shared_ptr<FloatingRateCouponPricer>& p3) {
458 std::vector<ext::shared_ptr<FloatingRateCouponPricer> > p;
462 setCouponPricersFirstMatching(leg, p);
467 const ext::shared_ptr<FloatingRateCouponPricer>& p1,
468 const ext::shared_ptr<FloatingRateCouponPricer>& p2,
469 const ext::shared_ptr<FloatingRateCouponPricer>& p3,
470 const ext::shared_ptr<FloatingRateCouponPricer>& p4) {
471 std::vector<ext::shared_ptr<FloatingRateCouponPricer> > p;
476 setCouponPricersFirstMatching(leg, p);
Floating rate coupon with additional cap/floor.
degenerate base class for the Acyclic Visitor pattern
const Handle< Quote > correlation_
void initialize(const FloatingRateCoupon &coupon) override
virtual Rate adjustedFixing(Rate fixing=Null< Rate >()) const
Real optionletPrice(Option::Type optionType, Real effStrike) const
const TimingAdjustment timingAdjustment_
Real optionletRate(Option::Type optionType, Real effStrike) const
const Date & accrualEndDate() const
end of the accrual period
Date date() const override
Time accrualPeriod() const
accrual period as fraction of year
base floating-rate coupon class
Real gearing() const
index gearing, i.e. multiplicative coefficient for the index
Spread spread() const
spread paid over the fixing of the underlying index
bool isInArrears() const
whether or not the coupon fixes in arrears
Shared handle to an observable.
bool empty() const
checks if the contained shared pointer points to anything
Coupon paying a Libor-type index
Rate indexFixing() const override
fixing of the underlying index
Time spanningTimeIndexMaturity_
const ext::shared_ptr< IborIndex > & iborIndex() const
bool cachedDataIsInitialized_
void initializeCachedData(const IborCoupon &coupon) const
void initialize(const FloatingRateCoupon &coupon) override
Handle< OptionletVolatilityStructure > capletVolatility() const
Handle< OptionletVolatilityStructure > capletVol_
const IborCoupon * coupon_
Time spanningTimeIndexMaturity_
IborCouponPricer(Handle< OptionletVolatilityStructure > v=Handle< OptionletVolatilityStructure >(), ext::optional< bool > useIndexedCoupon=ext::nullopt)
ext::shared_ptr< IborIndex > index_
template class providing a null value for a given type.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
global repository for run-time library settings
static Settings & instance()
access to the unique instance
Visitor for a specific class
ext::shared_ptr< FloatingRateCouponPricer > pricer_
Cms-rate coupon with digital call/put option.
Cms-spread-rate coupon with digital call/put option.
Floating-rate coupon with digital call/put option.
Ibor-rate coupon with digital call/put option.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
std::function< Real(Real)> b
LinearInterpolation variance
Real Time
continuous quantity with 1-year units
QL_INTEGER Integer
integer number
Real Spread
spreads on interest rates
std::size_t Size
size of a container
Coupon compounding or averaging multiple fixings.
void setCouponPricers(const Leg &leg, const std::vector< ext::shared_ptr< FloatingRateCouponPricer > > &pricers)
Real bachelierBlackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount)
void setCouponPricer(const Leg &leg, const ext::shared_ptr< FloatingRateCouponPricer > &pricer)
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Maps optional to either the boost or std implementation.
ext::shared_ptr< BlackVolTermStructure > v
Interest-rate term structure.