22#include <ql/cashflows/cashflowvectors.hpp>
23#include <ql/cashflows/couponpricer.hpp>
24#include <ql/cashflows/fixedratecoupon.hpp>
25#include <ql/termstructures/yieldtermstructure.hpp>
26#include <ql/time/calendars/weekendsonly.hpp>
27#include <ql/utilities/vectors.hpp>
37 const QuantLib::ext::shared_ptr<OvernightIndex>& overnightIndex, Real gearing,
38 Spread spread, Natural rateCutoff,
const DayCounter& dayCounter,
39 const Period& lookback,
const Size fixingDays,
40 const Date& rateComputationStartDate,
const Date& rateComputationEndDate,
41 const bool telescopicValueDates)
42 :
FloatingRateCoupon(paymentDate, nominal, startDate, endDate, fixingDays, overnightIndex, gearing, spread, Date(),
43 Date(), dayCounter, false),
44 overnightIndex_(overnightIndex), rateCutoff_(rateCutoff), lookback_(lookback),
45 rateComputationStartDate_(rateComputationStartDate), rateComputationEndDate_(rateComputationEndDate) {
50 BusinessDayConvention bdc =
lookback.length() > 0 ? Preceding : Following;
56 Date tmpEndDate = valueEnd;
57 if(telescopicValueDates) {
59 Date evalDate = Settings::instance().evaluationDate();
60 tmpEndDate =
overnightIndex->fixingCalendar().advance(std::max(valueStart, evalDate), 7, Days, Following);
61 tmpEndDate = std::min(tmpEndDate, valueEnd);
64 Schedule sch = MakeSchedule()
73 if (telescopicValueDates) {
78 while (tmp1 <= tmp2) {
81 tmp1 =
overnightIndex->fixingCalendar().advance(tmp1, 1, Days, Following);
96 "internal error: first two value dates of on coupon are equal: " <<
valueDates_[0]);
104 valueDates_[i], -
static_cast<Integer
>(FloatingRateCoupon::fixingDays()), Days, Preceding);
113 <<
") must be less than number of fixings in period ("
126 Rate cutoffFixing =
fixings_[i - 1];
138 Visitor<AverageONIndexedCoupon>* v1 =
dynamic_cast<Visitor<AverageONIndexedCoupon>*
>(&v);
142 FloatingRateCoupon::accept(v);
149 LazyObject::alwaysForwardNotifications();
159 QL_REQUIRE(
underlying_->pricer(),
"pricer not set");
161 if (
floor_ != Null<Real>() ||
cap_ != Null<Real>())
162 pricer()->initialize(*
this);
163 Rate floorletRate = 0.;
164 if (
floor_ != Null<Real>())
166 Rate capletRate = 0.;
167 if (
cap_ != Null<Real>())
169 rate_ = swapletRate + floorletRate - capletRate;
170 auto p = QuantLib::ext::dynamic_pointer_cast<CapFlooredAverageONIndexedCouponPricer>(pricer());
171 QL_REQUIRE(p,
"CapFlooredAverageONIndexedCoupon::performCalculations(): internal error, could not cast to "
172 "CapFlooredAverageONIndexedCouponPricer");
189 if (
cap_ == Null<Real>())
221 if (
floor_ == Null<Real>())
249 Visitor<CappedFlooredAverageONIndexedCoupon>* v1 =
dynamic_cast<Visitor<CappedFlooredAverageONIndexedCoupon>*
>(&v);
253 FloatingRateCoupon::accept(v);
257 const ext::shared_ptr<AverageONIndexedCoupon>& underlying, Real cap, Real floor,
bool nakedOption,
258 bool localCapFloor,
bool includeSpread)
259 :
FloatingRateCoupon(underlying->date(), underlying->nominal(), underlying->accrualStartDate(),
260 underlying->accrualEndDate(), underlying->fixingDays(), underlying->index(),
261 underlying->gearing(), underlying->spread(), underlying->referencePeriodStart(),
262 underlying->referencePeriodEnd(), underlying->dayCounter(), false),
263 underlying_(underlying), cap_(cap), floor_(floor), nakedOption_(nakedOption), localCapFloor_(localCapFloor),
264 includeSpread_(includeSpread) {
266 "CappedFlooredAverageONIndexedCoupon: if include spread = true, only a gearing 1.0 is allowed - scale "
267 "the notional in this case instead.");
276 const Handle<OptionletVolatilityStructure>& v,
const bool effectiveVolatilityInput)
277 : capletVol_(v), effectiveVolatilityInput_(effectiveVolatilityInput) {
296 : schedule_(schedule), overnightIndex_(i), paymentAdjustment_(Following), paymentLag_(0),
297 telescopicValueDates_(false), paymentCalendar_(schedule.calendar()), rateCutoff_(0), lookback_(0 * Days),
298 fixingDays_(Null<Size>()), includeSpread_(false), nakedOption_(false), localCapFloor_(false), inArrears_(true) {}
321 gearings_ = std::vector<Real>(1, gearing);
331 spreads_ = std::vector<Spread>(1, spread);
371 caps_ = std::vector<Rate>(1, cap);
381 floors_ = std::vector<Rate>(1, floor);
432 const QuantLib::ext::shared_ptr<CapFlooredAverageONIndexedCouponPricer>& couponPricer) {
437AverageONLeg::operator Leg()
const {
439 QL_REQUIRE(!notionals_.empty(),
"No notional given for average overnight leg.");
443 Calendar calendar = schedule_.calendar();
444 Calendar paymentCalendar = paymentCalendar_;
446 if (calendar.empty())
447 calendar = paymentCalendar;
448 if (calendar.empty())
449 calendar = WeekendsOnly();
450 if (paymentCalendar.empty())
451 paymentCalendar = calendar;
453 Date refStart, start, refEnd, end;
456 Size n = schedule_.size() - 1;
459 if (!paymentDates_.empty()) {
460 QL_REQUIRE(paymentDates_.size() == n,
"Expected the number of explicit payment dates ("
461 << paymentDates_.size()
462 <<
") to equal the number of calculation periods ("
466 for (Size i = 0; i < n; ++i) {
467 refStart = start = schedule_.date(i);
468 refEnd = end = schedule_.date(i + 1);
471 if (!paymentDates_.empty()) {
472 paymentDate = paymentDates_[i];
474 paymentDate = paymentCalendar.advance(end, paymentLag_, Days, paymentAdjustment_);
479 if (i == 0 && schedule_.hasIsRegular() && !schedule_.isRegular(i + 1))
480 refStart = calendar.adjust(end - schedule_.tenor(), paymentAdjustment_);
481 if (i == n - 1 && schedule_.hasIsRegular() && !schedule_.isRegular(i + 1))
482 refEnd = calendar.adjust(start + schedule_.tenor(), paymentAdjustment_);
489 Date rateComputationStartDate, rateComputationEndDate;
492 rateComputationStartDate = start;
493 rateComputationEndDate = end;
498 rateComputationStartDate = schedule_.date(i - 1);
499 rateComputationEndDate = schedule_.date(i);
502 rateComputationEndDate = start;
503 if (schedule_.hasTenor() && schedule_.tenor() != 0 * Days)
504 rateComputationStartDate = calendar.adjust(start - schedule_.tenor(), Preceding);
506 rateComputationStartDate = calendar.adjust(start - (end - start), Preceding);
510 if (lastRecentPeriod_) {
511 rateComputationStartDate = (lastRecentPeriodCalendar_.empty() ? calendar : lastRecentPeriodCalendar_)
512 .advance(rateComputationEndDate, -*lastRecentPeriod_);
517 if (
close_enough(detail::get(gearings_, i, 1.0), 0.0)) {
519 cashflows.push_back(QuantLib::ext::make_shared<FixedRateCoupon>(paymentDate, detail::get(notionals_, i, 1.0),
520 detail::get(spreads_, i, 0.0), paymentDayCounter_,
521 start, end, refStart, refEnd));
524 auto cpn = QuantLib::ext::make_shared<AverageONIndexedCoupon>(
525 paymentDate, detail::get(notionals_, i, notionals_.back()), start, end, overnightIndex_,
526 detail::get(gearings_, i, 1.0), detail::get(spreads_, i, 0.0), rateCutoff_, paymentDayCounter_,
527 lookback_, fixingDays_, rateComputationStartDate, rateComputationEndDate, telescopicValueDates_);
529 cpn->setPricer(couponPricer_);
531 Real cap = detail::get(caps_, i, Null<Real>());
532 Real floor = detail::get(floors_, i, Null<Real>());
533 if (cap == Null<Real>() && floor == Null<Real>()) {
534 cashflows.push_back(cpn);
536 auto cfCpn = ext::make_shared<CappedFlooredAverageONIndexedCoupon>(cpn, cap, floor, nakedOption_,
537 localCapFloor_, includeSpread_);
538 if (capFlooredCouponPricer_) {
539 cfCpn->setPricer(capFlooredCouponPricer_);
541 cashflows.push_back(cfCpn);
coupon paying the weighted average of the daily overnight rate
Pricer for average overnight indexed coupons.
Date rateComputationStartDate_
std::vector< Date > fixingDates_
const ext::shared_ptr< OvernightIndex > & overnightIndex() const
the underlying index
AverageONIndexedCoupon(const Date &paymentDate, Real nominal, const Date &startDate, const Date &endDate, const QuantLib::ext::shared_ptr< OvernightIndex > &overnightIndex, Real gearing=1.0, Spread spread=0.0, Natural rateCutoff=0, const DayCounter &dayCounter=DayCounter(), const Period &lookback=0 *Days, const Size fixingDays=Null< Size >(), const Date &rateComputationStartDate=Null< Date >(), const Date &rateComputationEndDate=Null< Date >(), const bool telescopicValueDates=false)
void accept(AcyclicVisitor &) override
std::vector< Rate > fixings_
const Period & lookback() const
lookback period
std::vector< Date > valueDates_
Date rateComputationEndDate_
const std::vector< Rate > & indexFixings() const
fixings to be averaged
Date fixingDate() const override
the date when the coupon is fully determined
helper class building a sequence of overnight coupons
AverageONLeg & withGearing(Real gearing)
AverageONLeg & withLastRecentPeriod(const boost::optional< Period > &lastRecentPeriod)
AverageONLeg & withPaymentDates(const std::vector< QuantLib::Date > &paymentDates)
BusinessDayConvention paymentAdjustment_
std::vector< Rate > caps_
bool telescopicValueDates_
AverageONLeg & withSpread(Spread spread)
AverageONLeg & withPaymentDayCounter(const DayCounter &dayCounter)
AverageONLeg & includeSpreadInCapFloors(bool includeSpread)
AverageONLeg & withPaymentLag(Natural lag)
Calendar paymentCalendar_
AverageONLeg & withNotional(Real notional)
AverageONLeg & withLookback(const Period &lookback)
AverageONLeg & withRateCutoff(Natural rateCutoff)
boost::optional< Period > lastRecentPeriod_
std::vector< QuantLib::Date > paymentDates_
AverageONLeg & withLastRecentPeriodCalendar(const Calendar &lastRecentPeriodCalendar)
AverageONLeg & withPaymentCalendar(const Calendar &calendar)
Calendar lastRecentPeriodCalendar_
AverageONLeg & withNakedOption(const bool nakedOption)
QuantLib::ext::shared_ptr< CapFlooredAverageONIndexedCouponPricer > capFlooredCouponPricer_
std::vector< Real > notionals_
std::vector< Spread > spreads_
AverageONLeg & withLocalCapFloor(const bool localCapFloor)
AverageONLeg & withTelescopicValueDates(bool telescopicValueDates)
AverageONLeg & withPaymentAdjustment(BusinessDayConvention convention)
AverageONLeg & withNotionals(const std::vector< Real > ¬ionals)
AverageONLeg & withSpreads(const std::vector< Spread > &spreads)
AverageONLeg & withInArrears(const bool inArrears)
AverageONLeg & withCaps(Rate cap)
AverageONLeg & withFloors(Rate floor)
AverageONLeg & withCapFlooredAverageONIndexedCouponPricer(const QuantLib::ext::shared_ptr< CapFlooredAverageONIndexedCouponPricer > &couponPricer)
QuantLib::ext::shared_ptr< AverageONIndexedCouponPricer > couponPricer_
std::vector< Rate > floors_
AverageONLeg & withAverageONIndexedCouponPricer(const QuantLib::ext::shared_ptr< AverageONIndexedCouponPricer > &couponPricer)
AverageONLeg & withFixingDays(const Size fixingDays)
AverageONLeg & withGearings(const std::vector< Real > &gearings)
std::vector< Real > gearings_
AverageONLeg(const Schedule &schedule, const QuantLib::ext::shared_ptr< OvernightIndex > &overnightIndex)
DayCounter paymentDayCounter_
bool effectiveVolatilityInput() const
Real effectiveCapletVolatility() const
Real effectiveCapletVolatility_
Handle< OptionletVolatilityStructure > capletVolatility() const
Handle< OptionletVolatilityStructure > capletVol_
Real effectiveFloorletVolatility() const
Real effectiveFloorletVolatility_
bool effectiveVolatilityInput_
CapFlooredAverageONIndexedCouponPricer(const Handle< OptionletVolatilityStructure > &v, const bool effectiveVolatilityInput=false)
void performCalculations() const override
Real effectiveCapletVolatility() const
effective caplet volatility
bool includeSpread() const
Real effectiveCapletVolatility_
void deepUpdate() override
Rate rate() const override
virtual void accept(AcyclicVisitor &) override
CappedFlooredAverageONIndexedCoupon(const ext::shared_ptr< AverageONIndexedCoupon > &underlying, Real cap=Null< Real >(), Real floor=Null< Real >(), bool nakedOption=false, bool localCapFloor=false, bool includeSpread=false)
Real effectiveFloorletVolatility() const
effective floorlet volatility
Rate effectiveCap() const
effective cap of fixing
Real effectiveFloorletVolatility_
Rate effectiveFloor() const
effective floor of fixing
Rate convexityAdjustment() const override
void alwaysForwardNotifications() override
ext::shared_ptr< AverageONIndexedCoupon > underlying_
Filter close_enough(const RandomVariable &x, const RandomVariable &y)