QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
averagebmacoupon.cpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Roland Lichters
5 Copyright (C) 2007 StatPro Italia srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
24#include <utility>
25
26namespace QuantLib {
27
28 namespace {
29
30 Integer bmaCutoffDays = 0; // to be verified
31
32 class AverageBMACouponPricer : public FloatingRateCouponPricer {
33 public:
34 void initialize(const FloatingRateCoupon& coupon) override {
35 coupon_ = dynamic_cast<const AverageBMACoupon*>(&coupon);
36 QL_ENSURE(coupon_, "wrong coupon type");
37 }
38 Rate swapletRate() const override {
39 const std::vector<Date>& fixingDates = coupon_->fixingDates();
40 const ext::shared_ptr<InterestRateIndex>& index =
41 coupon_->index();
42
43 Natural cutoffDays = 0; // to be verified
44 Date startDate = coupon_->accrualStartDate() - cutoffDays,
45 endDate = coupon_->accrualEndDate() - cutoffDays,
46 d1 = startDate,
47 d2 = startDate;
48
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");
54
55 Rate avgBMA = 0.0;
56 Integer days = 0;
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]);
60
61 if (fixingDates[i] >= endDate || valueDate >= endDate)
62 break;
63 if (fixingDates[i+1] < startDate
64 || nextValueDate <= startDate)
65 continue;
66
67 d2 = std::min(nextValueDate, endDate);
68
69 avgBMA += index->fixing(fixingDates[i]) * (d2 - d1);
70
71 days += d2 - d1;
72 d1 = d2;
73 }
74 avgBMA /= (endDate - startDate);
75
76 QL_ENSURE(days == endDate - startDate,
77 "averaging days " << days << " differ from "
78 "interest days " << (endDate - startDate));
79
80 return coupon_->gearing()*avgBMA + coupon_->spread();
81 }
82
83 Real swapletPrice() const override { QL_FAIL("not available"); }
84 Real capletPrice(Rate) const override { QL_FAIL("not available"); }
85 Rate capletRate(Rate) const override { QL_FAIL("not available"); }
86 Real floorletPrice(Rate) const override { QL_FAIL("not available"); }
87 Rate floorletRate(Rate) const override { QL_FAIL("not available"); }
88
89 private:
90 const AverageBMACoupon* coupon_;
91 };
92
93 }
94
95 namespace {
96 void adjustToPreviousValidFixingDate(Date& d, const ext::shared_ptr<BMAIndex>& index) {
97 while (!index->isValidFixingDate(d) && d > Date::minDate())
98 d--;
99 }
100 } // namespace
101
103 Real nominal,
104 const Date& startDate,
105 const Date& endDate,
106 const ext::shared_ptr<BMAIndex>& index,
107 Real gearing, Spread spread,
108 const Date& refPeriodStart,
109 const Date& refPeriodEnd,
110 const DayCounter& dayCounter)
111 : FloatingRateCoupon(paymentDate, nominal, startDate, endDate,
112 index->fixingDays(), index, gearing, spread,
113 refPeriodStart, refPeriodEnd, dayCounter, false)
114 {
115 Calendar cal = index->fixingCalendar();
116 auto fixingDays = Integer(index->fixingDays());
117 fixingDays += bmaCutoffDays;
118 Date fixingStart = cal.advance(startDate, -fixingDays*Days, Preceding);
119
120 // make sure that the value date associated to fixingStart is <= startDate
121 adjustToPreviousValidFixingDate(fixingStart, index);
122 while (index->valueDate(fixingStart) > startDate && fixingStart > Date::minDate()) {
123 adjustToPreviousValidFixingDate(--fixingStart, index);
124 }
125
126 fixingSchedule_ = index->fixingSchedule(fixingStart, endDate);
127
128 setPricer(ext::shared_ptr<FloatingRateCouponPricer>(
129 new AverageBMACouponPricer));
130 }
131
133 QL_FAIL("no single fixing date for average-BMA coupon");
134 }
135
136 std::vector<Date> AverageBMACoupon::fixingDates() const {
137 return fixingSchedule_.dates();
138 }
139
141 QL_FAIL("no single fixing for average-BMA coupon");
142 }
143
144 std::vector<Rate> AverageBMACoupon::indexFixings() const {
145 std::vector<Rate> fixings(fixingSchedule_.size());
146 for (Size i=0; i<fixings.size(); ++i)
147 fixings[i] = index_->fixing(fixingSchedule_.date(i));
148 return fixings;
149 }
150
152 QL_FAIL("not defined for average-BMA coupon");
153 }
154
156 auto* v1 = dynamic_cast<Visitor<AverageBMACoupon>*>(&v);
157 if (v1 != nullptr) {
158 v1->visit(*this);
159 } else {
161 }
162 }
163
164
165 AverageBMALeg::AverageBMALeg(Schedule schedule, ext::shared_ptr<BMAIndex> index)
166 : schedule_(std::move(schedule)), index_(std::move(index)) {}
167
169 notionals_ = std::vector<Real>(1,notional);
170 return *this;
171 }
172
174 const std::vector<Real>& notionals) {
175 notionals_ = notionals;
176 return *this;
177 }
178
180 const DayCounter& dayCounter) {
181 paymentDayCounter_ = dayCounter;
182 return *this;
183 }
184
186 BusinessDayConvention convention) {
187 paymentAdjustment_ = convention;
188 return *this;
189 }
190
192 gearings_ = std::vector<Real>(1,gearing);
193 return *this;
194 }
195
197 const std::vector<Real>& gearings) {
198 gearings_ = gearings;
199 return *this;
200 }
201
203 spreads_ = std::vector<Spread>(1,spread);
204 return *this;
205 }
206
208 const std::vector<Spread>& spreads) {
209 spreads_ = spreads;
210 return *this;
211 }
212
213 AverageBMALeg::operator Leg() const {
214
215 QL_REQUIRE(!notionals_.empty(), "no notional given");
216
217 Leg cashflows;
218
219 // the following is not always correct
220 Calendar calendar = schedule_.calendar();
221
222 Date refStart, start, refEnd, end;
223 Date paymentDate;
224
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(),
233 paymentAdjustment_);
234 if (i == n-1 && schedule_.hasIsRegular() && !schedule_.isRegular(i+1)
235 && schedule_.hasTenor())
236 refEnd = calendar.adjust(start + schedule_.tenor(),
237 paymentAdjustment_);
238
239 cashflows.push_back(ext::shared_ptr<CashFlow>(new
240 AverageBMACoupon(paymentDate,
241 detail::get(notionals_, i, notionals_.back()),
242 start, end,
243 index_,
244 detail::get(gearings_, i, 1.0),
245 detail::get(spreads_, i, 0.0),
246 refStart, refEnd,
247 paymentDayCounter_)));
248 }
249
250 return cashflows;
251 }
252
253}
254
const AverageBMACoupon * coupon_
coupon paying a weighted average of BMA-index fixings
degenerate base class for the Acyclic Visitor pattern
Definition: visitor.hpp:33
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_
calendar class
Definition: calendar.hpp:61
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Definition: calendar.cpp:84
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
Definition: calendar.cpp:130
Concrete date class.
Definition: date.hpp:125
static Date minDate()
earliest allowed date
Definition: date.cpp:766
day counter class
Definition: daycounter.hpp:44
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
Payment schedule.
Definition: schedule.hpp:40
const std::vector< Date > & dates() const
Definition: schedule.hpp:75
const Date & date(Size i) const
Definition: schedule.hpp:160
Size size() const
Definition: schedule.hpp:69
Visitor for a specific class
Definition: visitor.hpp:40
virtual void visit(T &)=0
Coupon pricers.
#define QL_ENSURE(condition, message)
throw an error if the given post-condition is not verified
Definition: errors.hpp:130
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
Date d
BusinessDayConvention
Business Day conventions.
QL_REAL Real
real number
Definition: types.hpp:50
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
QL_INTEGER Integer
integer number
Definition: types.hpp:35
Real Spread
spreads on interest rates
Definition: types.hpp:74
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
T get(const std::vector< T > &v, Size i, U defaultValue)
Definition: vectors.hpp:35
Definition: any.hpp:35
Real days(const Period &p)
Definition: period.cpp:330
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78
STL namespace.
ext::shared_ptr< BlackVolTermStructure > v
Utilities for vector manipulation.