Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
formulabasedcoupon.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2018 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
20
21#include <ql/cashflows/cashflowvectors.hpp>
22
23using namespace QuantLib;
24
25namespace QuantExt {
26
27FormulaBasedCoupon::FormulaBasedCoupon(const Currency& paymentCurrency, const Date& paymentDate, Real nominal,
28 const Date& startDate, const Date& endDate, Natural fixingDays,
29 const QuantLib::ext::shared_ptr<FormulaBasedIndex>& index, const Date& refPeriodStart,
30 const Date& refPeriodEnd, const DayCounter& dayCounter, bool isInArrears)
31 : FloatingRateCoupon(paymentDate, nominal, startDate, endDate, fixingDays, index, 1.0, 0.0, refPeriodStart,
32 refPeriodEnd, dayCounter, isInArrears),
33 paymentCurrency_(paymentCurrency), index_(index) {}
34
35void FormulaBasedCoupon::accept(AcyclicVisitor& v) {
36 Visitor<FormulaBasedCoupon>* v1 = dynamic_cast<Visitor<FormulaBasedCoupon>*>(&v);
37 if (v1 != 0)
38 v1->visit(*this);
39 else
40 FloatingRateCoupon::accept(v);
41}
42
43FormulaBasedLeg::FormulaBasedLeg(const Currency& paymentCurrency, const Schedule& schedule,
44 const QuantLib::ext::shared_ptr<FormulaBasedIndex>& index)
45 : paymentCurrency_(paymentCurrency), schedule_(schedule), index_(index), paymentAdjustment_(Following),
46 paymentLag_(0), inArrears_(false), zeroPayments_(false) {}
47
49 notionals_ = std::vector<Real>(1, notional);
50 return *this;
51}
52
53FormulaBasedLeg& FormulaBasedLeg::withNotionals(const std::vector<Real>& notionals) {
54 notionals_ = notionals;
55 return *this;
56}
57
59 paymentDayCounter_ = dayCounter;
60 return *this;
61}
62
63FormulaBasedLeg& FormulaBasedLeg::withPaymentAdjustment(BusinessDayConvention convention) {
64 paymentAdjustment_ = convention;
65 return *this;
66}
67
69 paymentLag_ = lag;
70 return *this;
71}
72
74 paymentCalendar_ = cal;
75 return *this;
76}
77
79 fixingDays_ = std::vector<Natural>(1, fixingDays);
80 return *this;
81}
82
83FormulaBasedLeg& FormulaBasedLeg::withFixingDays(const std::vector<Natural>& fixingDays) {
84 fixingDays_ = fixingDays;
85 return *this;
86}
87
89 inArrears_ = flag;
90 return *this;
91}
92
94 zeroPayments_ = flag;
95 return *this;
96}
97
98FormulaBasedLeg::operator Leg() const {
99
100 // unfortunately we have to copy this from ql/cashflows/cashflowvectors and modify it to
101 // match the formula based coupon ctor, which is a bit different from other flr coupons
102
103 Size n = schedule_.size() - 1;
104 QL_REQUIRE(!notionals_.empty(), "no notional given");
105 QL_REQUIRE(notionals_.size() <= n, "too many nominals (" << notionals_.size() << "), only " << n << " required");
106 QL_REQUIRE(!zeroPayments_ || !inArrears_, "in-arrears and zero features are not compatible");
107
108 Leg leg;
109 leg.reserve(n);
110
111 Calendar calendar = schedule_.calendar().empty() ? NullCalendar() : schedule_.calendar();
112 Calendar paymentCalendar = paymentCalendar_.empty() ? calendar : paymentCalendar_;
113
114 Date refStart, start, refEnd, end;
115 Date lastPaymentDate = paymentCalendar.advance(schedule_.date(n), paymentLag_, Days, paymentAdjustment_);
116
117 for (Size i = 0; i < n; ++i) {
118 refStart = start = schedule_.date(i);
119 refEnd = end = schedule_.date(i + 1);
120 Date paymentDate =
121 zeroPayments_ ? lastPaymentDate : paymentCalendar.advance(end, paymentLag_, Days, paymentAdjustment_);
122 if (i == 0 && schedule_.hasIsRegular() && !schedule_.isRegular(i + 1)) {
123 BusinessDayConvention bdc = schedule_.businessDayConvention();
124 refStart = calendar.adjust(end - schedule_.tenor(), bdc);
125 }
126 if (i == n - 1 && schedule_.hasIsRegular() && !schedule_.isRegular(i + 1)) {
127 BusinessDayConvention bdc = schedule_.businessDayConvention();
128 refEnd = calendar.adjust(start + schedule_.tenor(), bdc);
129 }
130 leg.push_back(QuantLib::ext::shared_ptr<CashFlow>(
131 new FormulaBasedCoupon(paymentCurrency_, paymentDate, detail::get(notionals_, i, 1.0), start, end,
132 detail::get(fixingDays_, i, index_->fixingDays()), index_, refStart, refEnd,
133 paymentDayCounter_, inArrears_)));
134 }
135 return leg;
136}
137
138} // namespace QuantExt
formula based coupon class
FormulaBasedCoupon(const Currency &paymentCurrency, const Date &paymentDate, Real nominal, const Date &startDate, const Date &endDate, Natural fixingDays, const QuantLib::ext::shared_ptr< FormulaBasedIndex > &index, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date(), const DayCounter &dayCounter=DayCounter(), bool isInArrears=false)
virtual void accept(AcyclicVisitor &) override
helper class building a sequence of formula based coupons
BusinessDayConvention paymentAdjustment_
FormulaBasedLeg & withPaymentCalendar(const Calendar &)
FormulaBasedLeg & inArrears(bool flag=true)
FormulaBasedLeg(const Currency &paymentCurrency, const Schedule &schedule, const QuantLib::ext::shared_ptr< FormulaBasedIndex > &index)
std::vector< Real > notionals_
FormulaBasedLeg & withPaymentDayCounter(const DayCounter &)
FormulaBasedLeg & withNotionals(Real notional)
FormulaBasedLeg & withPaymentLag(Natural lag)
std::vector< Natural > fixingDays_
FormulaBasedLeg & withFixingDays(Natural fixingDays)
FormulaBasedLeg & withZeroPayments(bool flag=true)
FormulaBasedLeg & withPaymentAdjustment(BusinessDayConvention)
formula based coupon