32 class AverageBMACouponPricer :
public FloatingRateCouponPricer {
34 void initialize(
const FloatingRateCoupon& coupon)
override {
35 coupon_ =
dynamic_cast<const AverageBMACoupon*
>(&coupon);
38 Rate swapletRate()
const override {
39 const std::vector<Date>& fixingDates =
coupon_->fixingDates();
40 const ext::shared_ptr<InterestRateIndex>& index =
44 Date startDate =
coupon_->accrualStartDate() - cutoffDays,
45 endDate =
coupon_->accrualEndDate() - cutoffDays,
49 QL_REQUIRE(!fixingDates.empty(),
"fixing date list empty");
50 QL_REQUIRE (index->valueDate(fixingDates.front()) <= startDate,
51 "first fixing date valid after period start");
52 QL_REQUIRE (index->valueDate(fixingDates.back()) >= endDate,
53 "last fixing date valid before period end");
57 for (
Size i=0; i<fixingDates.size() - 1; ++i) {
58 Date valueDate = index->valueDate(fixingDates[i]);
59 Date nextValueDate = index->valueDate(fixingDates[i+1]);
61 if (fixingDates[i] >= endDate || valueDate >= endDate)
63 if (fixingDates[i+1] < startDate
64 || nextValueDate <= startDate)
67 d2 = std::min(nextValueDate, endDate);
69 avgBMA += index->fixing(fixingDates[i]) * (d2 - d1);
74 avgBMA /= (endDate - startDate);
77 "averaging days " <<
days <<
" differ from "
78 "interest days " << (endDate - startDate));
83 Real swapletPrice()
const override {
QL_FAIL(
"not available"); }
96 void adjustToPreviousValidFixingDate(Date&
d,
const ext::shared_ptr<BMAIndex>& index) {
104 const Date& startDate,
106 const ext::shared_ptr<BMAIndex>& index,
108 const Date& refPeriodStart,
109 const Date& refPeriodEnd,
112 index->fixingDays(), index, gearing, spread,
113 refPeriodStart, refPeriodEnd, dayCounter, false)
121 adjustToPreviousValidFixingDate(fixingStart,
index);
123 adjustToPreviousValidFixingDate(--fixingStart,
index);
128 setPricer(ext::shared_ptr<FloatingRateCouponPricer>(
129 new AverageBMACouponPricer));
133 QL_FAIL(
"no single fixing date for average-BMA coupon");
141 QL_FAIL(
"no single fixing for average-BMA coupon");
146 for (
Size i=0; i<fixings.size(); ++i)
152 QL_FAIL(
"not defined for average-BMA coupon");
166 : schedule_(
std::move(schedule)), index_(
std::move(index)) {}
174 const std::vector<Real>& notionals) {
192 gearings_ = std::vector<Real>(1,gearing);
197 const std::vector<Real>& gearings) {
203 spreads_ = std::vector<Spread>(1,spread);
208 const std::vector<Spread>& spreads) {
213 AverageBMALeg::operator
Leg()
const {
215 QL_REQUIRE(!notionals_.empty(),
"no notional given");
220 Calendar calendar = schedule_.calendar();
222 Date refStart, start, refEnd, end;
225 Size n = schedule_.size()-1;
226 for (
Size i=0; i<
n; ++i) {
227 refStart = start = schedule_.date(i);
228 refEnd = end = schedule_.date(i+1);
229 paymentDate = calendar.
adjust(end, paymentAdjustment_);
230 if (i == 0 && schedule_.hasIsRegular() && !schedule_.isRegular(i+1)
231 && schedule_.hasTenor())
232 refStart = calendar.
adjust(end - schedule_.tenor(),
234 if (i ==
n-1 && schedule_.hasIsRegular() && !schedule_.isRegular(i+1)
235 && schedule_.hasTenor())
236 refEnd = calendar.
adjust(start + schedule_.tenor(),
239 cashflows.push_back(ext::shared_ptr<CashFlow>(
new
247 paymentDayCounter_)));
const AverageBMACoupon * coupon_
coupon paying a weighted average of BMA-index fixings
degenerate base class for the Acyclic Visitor pattern
AverageBMACoupon(const Date &paymentDate, Real nominal, const Date &startDate, const Date &endDate, const ext::shared_ptr< BMAIndex > &index, Real gearing=1.0, Spread spread=0.0, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date(), const DayCounter &dayCounter=DayCounter())
std::vector< Date > fixingDates() const
fixing dates of the rates to be averaged
Rate indexFixing() const override
not applicable here; use indexFixings() instead
void accept(AcyclicVisitor &) override
std::vector< Rate > indexFixings() const
fixings of the underlying index to be averaged
Rate convexityAdjustment() const override
not applicable here
Date fixingDate() const override
not applicable here; use fixingDates() instead
helper class building a sequence of average BMA coupons
BusinessDayConvention paymentAdjustment_
AverageBMALeg & withSpreads(Spread spread)
AverageBMALeg & withGearings(Real gearing)
std::vector< Real > notionals_
std::vector< Spread > spreads_
AverageBMALeg & withPaymentDayCounter(const DayCounter &)
AverageBMALeg(Schedule schedule, ext::shared_ptr< BMAIndex > index)
AverageBMALeg & withPaymentAdjustment(BusinessDayConvention)
AverageBMALeg & withNotionals(Real notional)
std::vector< Real > gearings_
DayCounter paymentDayCounter_
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
static Date minDate()
earliest allowed date
base floating-rate coupon class
Natural fixingDays() const
fixing days
ext::shared_ptr< InterestRateIndex > index_
virtual void setPricer(const ext::shared_ptr< FloatingRateCouponPricer > &)
void accept(AcyclicVisitor &) override
const ext::shared_ptr< InterestRateIndex > & index() const
floating index
const std::vector< Date > & dates() const
const Date & date(Size i) const
Visitor for a specific class
virtual void visit(T &)=0
#define QL_ENSURE(condition, message)
throw an error if the given post-condition is not verified
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
#define QL_FAIL(message)
throw an error (possibly with file and line information)
BusinessDayConvention
Business Day conventions.
unsigned QL_INTEGER Natural
positive integer
QL_INTEGER Integer
integer number
Real Spread
spreads on interest rates
std::size_t Size
size of a container
T get(const std::vector< T > &v, Size i, U defaultValue)
Real days(const Period &p)
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
ext::shared_ptr< BlackVolTermStructure > v
Utilities for vector manipulation.