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<SubPeriodsCoupon> {
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(SubPeriodsCoupon& 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(SubPeriodsCoupon& c) {
390 const ext::shared_ptr<SubPeriodsPricer> subPeriodsPricer =
391 ext::dynamic_pointer_cast<SubPeriodsPricer>(
pricer_);
393 "pricer not compatible with sub-period coupon");
394 c.setPricer(subPeriodsPricer);
397 void setCouponPricersFirstMatching(
const Leg& leg,
398 const std::vector<ext::shared_ptr<FloatingRateCouponPricer> >& p) {
399 std::vector<PricerSetter> setter;
400 setter.reserve(p.size());
401 for (
const auto& i : p) {
402 setter.emplace_back(i);
404 for (
const auto& i : leg) {
408 i->accept(setter[j]);
413 }
while (j < p.size());
420 PricerSetter setter(pricer);
421 for (
const auto& i : leg) {
428 const std::vector<ext::shared_ptr<FloatingRateCouponPricer> >&
430 Size nCashFlows = leg.size();
433 Size nPricers = pricers.size();
435 "mismatch between leg size (" << nCashFlows <<
436 ") and number of pricers (" << nPricers <<
")");
438 for (
Size i=0; i<nCashFlows; ++i) {
439 PricerSetter setter(i<nPricers ? pricers[i] : pricers[nPricers-1]);
440 leg[i]->accept(setter);
446 const ext::shared_ptr<FloatingRateCouponPricer>& p1,
447 const ext::shared_ptr<FloatingRateCouponPricer>& p2) {
448 std::vector<ext::shared_ptr<FloatingRateCouponPricer> > p;
451 setCouponPricersFirstMatching(leg, p);
456 const ext::shared_ptr<FloatingRateCouponPricer>& p1,
457 const ext::shared_ptr<FloatingRateCouponPricer>& p2,
458 const ext::shared_ptr<FloatingRateCouponPricer>& p3) {
459 std::vector<ext::shared_ptr<FloatingRateCouponPricer> > p;
463 setCouponPricersFirstMatching(leg, p);
468 const ext::shared_ptr<FloatingRateCouponPricer>& p1,
469 const ext::shared_ptr<FloatingRateCouponPricer>& p2,
470 const ext::shared_ptr<FloatingRateCouponPricer>& p3,
471 const ext::shared_ptr<FloatingRateCouponPricer>& p4) {
472 std::vector<ext::shared_ptr<FloatingRateCouponPricer> > p;
477 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
ext::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
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.