22#include <ql/utilities/vectors.hpp>
29 Natural fixingDays,
const QuantLib::ext::shared_ptr<EquityIndex2>& equityCurve,
30 const DayCounter& dayCounter,
bool isTotalReturn, Real dividendFactor,
bool notionalReset,
31 Real initialPrice, Real quantity,
const Date& fixingStartDate,
const Date& fixingEndDate,
32 const Date& refPeriodStart,
const Date& refPeriodEnd,
const Date& exCouponDate, Real multiplier,
33 const QuantLib::ext::shared_ptr<FxIndex>& fxIndex,
const bool initialPriceIsInTargetCcy)
34 :
Coupon(paymentDate, nominal, startDate, endDate, refPeriodStart, refPeriodEnd, exCouponDate),
35 fixingDays_(fixingDays), equityCurve_(equityCurve), dayCounter_(dayCounter), isTotalReturn_(isTotalReturn),
36 dividendFactor_(dividendFactor), notionalReset_(notionalReset), initialPrice_(initialPrice),
37 initialPriceIsInTargetCcy_(initialPriceIsInTargetCcy), quantity_(quantity), fixingStartDate_(fixingStartDate),
38 fixingEndDate_(fixingEndDate), fxIndex_(fxIndex), marginFactor_(marginFactor),
39 fixedRate_(InterestRate(rate, dayCounter, Simple, Annual)), multiplier_(multiplier) {
41 QL_REQUIRE(
dividendFactor_ > 0.0,
"Dividend factor should not be negative. It is expected to be between 0 and 1.");
42 QL_REQUIRE(
equityCurve_,
"Equity underlying an equity swap coupon cannot be empty.");
56 registerWith(Settings::instance().evaluationDate());
60 "EquityCoupon: notional required if notional does not reset");
97 if (d <= accrualStartDate_ || d > paymentDate_) {
100 Time fullPeriod =
dayCounter().yearFraction(accrualStartDate_, accrualEndDate_, refPeriodStart_, refPeriodEnd_);
102 dayCounter().yearFraction(accrualStartDate_, std::min(d, accrualEndDate_), refPeriodStart_, refPeriodEnd_);
103 return nominal() *
rate() * thisPeriod / fullPeriod;
121 QL_REQUIRE(
pricer_,
"pricer not set");
127 const QuantLib::ext::shared_ptr<FxIndex>& fxIndex)
128 : schedule_(schedule), equityCurve_(equityCurve), fxIndex_(fxIndex) {}
131 const DayCounter& dc,
146 const DayCounter& dc,
150 for (Size i=0; i<rates.size(); ++i)
151 couponRates_[i] = InterestRate(rates[i], dc, comp, freq);
156 const std::vector<InterestRate>& interestRates) {
241EquityMarginLeg::operator Leg()
const {
247 InterestRate rate = couponRates_[0];
250 if (!paymentCalendar_.empty()) {
251 calendar = paymentCalendar_;
253 calendar = schedule_.calendar();
256 Size numPeriods = schedule_.size() - 1;
258 if (valuationSchedule_.size() > 0) {
259 QL_REQUIRE(valuationSchedule_.size() == schedule_.size(),
260 "mismatch in valuationSchedule (" << valuationSchedule_.size() <<
") and scheduleData (" << schedule_.size() <<
") sizes");
263 for (Size i = 0; i < numPeriods; ++i) {
264 startDate = schedule_.date(i);
265 endDate = schedule_.date(i + 1);
266 paymentDate = calendar.advance(endDate, paymentLag_, Days, paymentAdjustment_);
268 Date fixingStartDate = Date();
269 Date fixingEndDate = Date();
270 if (valuationSchedule_.size() > 0) {
271 fixingStartDate = valuationSchedule_.date(i);
272 fixingEndDate = valuationSchedule_.date(i + 1);
276 if ((i-1) < couponRates_.size())
277 rate = couponRates_[i-1];
279 rate = couponRates_.back();
281 Real initialPrice = (i == 0) ? initialPrice_ : Null<Real>();
282 bool initialPriceIsInTargetCcy = initialPrice != Null<Real>() ? initialPriceIsInTargetCcy_ :
false;
283 Real quantity = Null<Real>(), notional = Null<Real>();
284 if (notionalReset_) {
285 if (quantity_ != Null<Real>()) {
286 quantity = quantity_;
287 QL_REQUIRE(notionals_.empty(),
"EquityMarginLeg: notional and quantity are given at the same time");
289 QL_REQUIRE(fxIndex_ ==
nullptr,
290 "EquityMarginLeg: can not compute quantity from nominal when fx conversion is required");
291 QL_REQUIRE(!notionals_.empty(),
"EquityMarginLeg: can not compute qunantity, since no notional is given");
292 quantity = notionals_.front() ;
295 if (!notionals_.empty()) {
296 notional = detail::get(notionals_, i, 0.0);
297 QL_REQUIRE(quantity_ == Null<Real>(),
"EquityMarginLeg: notional and quantity are given at the same time");
299 QL_REQUIRE(fxIndex_ ==
nullptr,
300 "EquityMarginLeg: can not compute notional from quantity when fx conversion is required");
301 QL_REQUIRE(quantity_ != Null<Real>(),
302 "EquityMarginLeg: can not compute notional, since no quantity is given");
303 notional = quantity_;
307 QuantLib::ext::shared_ptr<EquityMarginCoupon> cashflow(
308 new EquityMarginCoupon(paymentDate, notional, rate, marginFactor_, startDate, endDate, fixingDays_, equityCurve_, paymentDayCounter_,
309 isTotalReturn_, dividendFactor_, notionalReset_, initialPrice, quantity, fixingStartDate,
310 fixingEndDate, Date(), Date(), Date(), multiplier_, fxIndex_, initialPriceIsInTargetCcy));
313 cashflow->setPricer(pricer);
315 cashflows.push_back(cashflow);
QuantLib::ext::shared_ptr< QuantExt::EquityIndex2 > equityCurve_
QuantLib::ext::shared_ptr< FxIndex > fxIndex_
std::vector< Date > fixingDates() const
return both fixing dates
void setPricer(const QuantLib::ext::shared_ptr< EquityMarginCouponPricer > &)
bool initialPriceIsInTargetCcy_
bool initialPriceIsInTargetCcy() const
initial price is in target ccy (if applicable, i.e. if fxIndex != null, otherwise ignored)
Rate rate() const override
Real amount() const override
Real fxRate() const
FX conversion rate (or 1.0 if not applicable)
Real nominal() const override
DayCounter dayCounter() const override
Real accruedAmount(const Date &) const override
QuantLib::ext::shared_ptr< EquityMarginCouponPricer > pricer_
QuantLib::ext::shared_ptr< EquityMarginCouponPricer > pricer() const
EquityMarginCoupon(const Date &paymentDate, Real nominal, Rate rate, Real marginFactor, const Date &startDate, const Date &endDate, Natural fixingDays, const QuantLib::ext::shared_ptr< QuantExt::EquityIndex2 > &equityCurve, const DayCounter &dayCounter, bool isTotalReturn=false, Real dividendFactor=1.0, bool notionalReset=false, Real initialPrice=Null< Real >(), Real quantity=Null< Real >(), const Date &fixingStartDate=Date(), const Date &fixingEndDate=Date(), const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date(), const Date &exCouponDate=Date(), Real multiplier=Null< Real >(), const QuantLib::ext::shared_ptr< FxIndex > &fxIndex=nullptr, const bool initialPriceIsInTargetCcy=false)
Date fixingStartDate() const
The date at which the starting equity price is fixed.
Real initialPrice() const
initial price
Pricer for equity margin coupons.
helper class building a sequence of equity margin coupons
EquityMarginLeg & withPaymentCalendar(const Calendar &calendar)
EquityMarginLeg & withPaymentLag(Natural paymentLag)
EquityMarginLeg & withQuantity(Real)
BusinessDayConvention paymentAdjustment_
EquityMarginLeg & withNotionalReset(bool)
EquityMarginLeg & withNotionals(const std::vector< Real > ¬ionals)
Calendar paymentCalendar_
EquityMarginLeg & withFixingDays(Natural)
Schedule valuationSchedule_
std::vector< InterestRate > couponRates_
EquityMarginLeg & withDividendFactor(Real)
bool initialPriceIsInTargetCcy_
EquityMarginLeg(const Schedule &schedule, const QuantLib::ext::shared_ptr< QuantExt::EquityIndex2 > &equityCurve, const QuantLib::ext::shared_ptr< FxIndex > &fxIndex=nullptr)
EquityMarginLeg & withInitialPrice(Real)
std::vector< Real > notionals_
EquityMarginLeg & withNotional(Real notional)
EquityMarginLeg & withInitialPriceIsInTargetCcy(bool)
EquityMarginLeg & withPaymentAdjustment(BusinessDayConvention convention)
EquityMarginLeg & withTotalReturn(bool)
EquityMarginLeg & withPaymentDayCounter(const DayCounter &dayCounter)
EquityMarginLeg & withMultiplier(Real)
EquityMarginLeg & withValuationSchedule(const Schedule &valuationSchedule)
EquityMarginLeg & withInitialMarginFactor(const Real &marginFactor)
EquityMarginLeg & withCouponRates(Rate, const DayCounter &paymentDayCounter, Compounding comp=Simple, Frequency freq=Annual)
DayCounter paymentDayCounter_
coupon paying the return on an equity
Pricer for equity margin coupons.