/src/quantlib/ql/indexes/swapindex.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright (C) 2006, 2009 Ferdinando Ametrano |
3 | | Copyright (C) 2006, 2007, 2009 StatPro Italia srl |
4 | | |
5 | | This file is part of QuantLib, a free-software/open-source library |
6 | | for financial quantitative analysts and developers - http://quantlib.org/ |
7 | | |
8 | | QuantLib is free software: you can redistribute it and/or modify it |
9 | | under the terms of the QuantLib license. You should have received a |
10 | | copy of the license along with this program; if not, please email |
11 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
12 | | <https://www.quantlib.org/license.shtml>. |
13 | | |
14 | | |
15 | | This program is distributed in the hope that it will be useful, but |
16 | | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
17 | | or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ |
18 | | |
19 | | #include <ql/indexes/iborindex.hpp> |
20 | | #include <ql/indexes/swapindex.hpp> |
21 | | #include <ql/instruments/makeois.hpp> |
22 | | #include <ql/instruments/makevanillaswap.hpp> |
23 | | #include <ql/time/schedule.hpp> |
24 | | #include <sstream> |
25 | | #include <utility> |
26 | | |
27 | | namespace QuantLib { |
28 | | |
29 | | SwapIndex::SwapIndex(const std::string& familyName, |
30 | | const Period& tenor, |
31 | | Natural settlementDays, |
32 | | const Currency& currency, |
33 | | const Calendar& fixingCalendar, |
34 | | const Period& fixedLegTenor, |
35 | | BusinessDayConvention fixedLegConvention, |
36 | | const DayCounter& fixedLegDayCounter, |
37 | | ext::shared_ptr<IborIndex> iborIndex) |
38 | 0 | : InterestRateIndex( |
39 | 0 | familyName, tenor, settlementDays, currency, fixingCalendar, fixedLegDayCounter), |
40 | 0 | tenor_(tenor), iborIndex_(std::move(iborIndex)), fixedLegTenor_(fixedLegTenor), |
41 | 0 | fixedLegConvention_(fixedLegConvention), exogenousDiscount_(false) { |
42 | 0 | registerWith(iborIndex_); |
43 | 0 | } |
44 | | |
45 | | SwapIndex::SwapIndex(const std::string& familyName, |
46 | | const Period& tenor, |
47 | | Natural settlementDays, |
48 | | const Currency& currency, |
49 | | const Calendar& fixingCalendar, |
50 | | const Period& fixedLegTenor, |
51 | | BusinessDayConvention fixedLegConvention, |
52 | | const DayCounter& fixedLegDayCounter, |
53 | | ext::shared_ptr<IborIndex> iborIndex, |
54 | | Handle<YieldTermStructure> discount) |
55 | 0 | : InterestRateIndex( |
56 | 0 | familyName, tenor, settlementDays, currency, fixingCalendar, fixedLegDayCounter), |
57 | 0 | tenor_(tenor), iborIndex_(std::move(iborIndex)), fixedLegTenor_(fixedLegTenor), |
58 | 0 | fixedLegConvention_(fixedLegConvention), exogenousDiscount_(true), |
59 | 0 | discount_(std::move(discount)) { |
60 | 0 | registerWith(iborIndex_); |
61 | 0 | registerWith(discount_); |
62 | 0 | } |
63 | | |
64 | 0 | Handle<YieldTermStructure> SwapIndex::forwardingTermStructure() const { |
65 | 0 | return iborIndex_->forwardingTermStructure(); |
66 | 0 | } |
67 | | |
68 | 0 | Handle<YieldTermStructure> SwapIndex::discountingTermStructure() const { |
69 | 0 | return discount_; // empty if not exogenous |
70 | 0 | } |
71 | | |
72 | 0 | Rate SwapIndex::forecastFixing(const Date& fixingDate) const { |
73 | 0 | return underlyingSwap(fixingDate)->fairRate(); |
74 | 0 | } |
75 | | |
76 | | ext::shared_ptr<VanillaSwap> |
77 | 0 | SwapIndex::underlyingSwap(const Date& fixingDate) const { |
78 | |
|
79 | 0 | QL_REQUIRE(fixingDate!=Date(), "null fixing date"); |
80 | | |
81 | | // caching mechanism |
82 | 0 | if (lastFixingDate_!=fixingDate) { |
83 | 0 | Rate fixedRate = 0.0; |
84 | 0 | if (exogenousDiscount_) |
85 | 0 | lastSwap_ = MakeVanillaSwap(tenor_, iborIndex_, fixedRate) |
86 | 0 | .withEffectiveDate(valueDate(fixingDate)) |
87 | 0 | .withFixedLegCalendar(fixingCalendar()) |
88 | 0 | .withFixedLegDayCount(dayCounter_) |
89 | 0 | .withFixedLegTenor(fixedLegTenor_) |
90 | 0 | .withFixedLegConvention(fixedLegConvention_) |
91 | 0 | .withFixedLegTerminationDateConvention(fixedLegConvention_) |
92 | 0 | .withDiscountingTermStructure(discount_); |
93 | 0 | else |
94 | 0 | lastSwap_ = MakeVanillaSwap(tenor_, iborIndex_, fixedRate) |
95 | 0 | .withEffectiveDate(valueDate(fixingDate)) |
96 | 0 | .withFixedLegCalendar(fixingCalendar()) |
97 | 0 | .withFixedLegDayCount(dayCounter_) |
98 | 0 | .withFixedLegTenor(fixedLegTenor_) |
99 | 0 | .withFixedLegConvention(fixedLegConvention_) |
100 | 0 | .withFixedLegTerminationDateConvention(fixedLegConvention_); |
101 | 0 | lastFixingDate_ = fixingDate; |
102 | 0 | } |
103 | 0 | return lastSwap_; |
104 | 0 | } |
105 | | |
106 | 0 | Date SwapIndex::maturityDate(const Date& valueDate) const { |
107 | 0 | Date fixDate = fixingDate(valueDate); |
108 | 0 | return underlyingSwap(fixDate)->maturityDate(); |
109 | 0 | } |
110 | | |
111 | | ext::shared_ptr<SwapIndex> |
112 | 0 | SwapIndex::clone(const Handle<YieldTermStructure>& forwarding) const { |
113 | |
|
114 | 0 | if (exogenousDiscount_) |
115 | 0 | return ext::make_shared<SwapIndex>(familyName(), |
116 | 0 | tenor(), |
117 | 0 | fixingDays(), |
118 | 0 | currency(), |
119 | 0 | fixingCalendar(), |
120 | 0 | fixedLegTenor(), |
121 | 0 | fixedLegConvention(), |
122 | 0 | dayCounter(), |
123 | 0 | iborIndex_->clone(forwarding), |
124 | 0 | discount_); |
125 | 0 | else |
126 | 0 | return ext::make_shared<SwapIndex>(familyName(), |
127 | 0 | tenor(), |
128 | 0 | fixingDays(), |
129 | 0 | currency(), |
130 | 0 | fixingCalendar(), |
131 | 0 | fixedLegTenor(), |
132 | 0 | fixedLegConvention(), |
133 | 0 | dayCounter(), |
134 | 0 | iborIndex_->clone(forwarding)); |
135 | 0 | } |
136 | | |
137 | | ext::shared_ptr<SwapIndex> |
138 | | SwapIndex::clone(const Handle<YieldTermStructure>& forwarding, |
139 | 0 | const Handle<YieldTermStructure>& discounting) const { |
140 | 0 | return ext::make_shared<SwapIndex>(familyName(), |
141 | 0 | tenor(), |
142 | 0 | fixingDays(), |
143 | 0 | currency(), |
144 | 0 | fixingCalendar(), |
145 | 0 | fixedLegTenor(), |
146 | 0 | fixedLegConvention(), |
147 | 0 | dayCounter(), |
148 | 0 | iborIndex_->clone(forwarding), |
149 | 0 | discounting); |
150 | 0 | } |
151 | | |
152 | | ext::shared_ptr<SwapIndex> |
153 | 0 | SwapIndex::clone(const Period& tenor) const { |
154 | |
|
155 | 0 | if (exogenousDiscount_) |
156 | 0 | return ext::make_shared<SwapIndex>(familyName(), |
157 | 0 | tenor, |
158 | 0 | fixingDays(), |
159 | 0 | currency(), |
160 | 0 | fixingCalendar(), |
161 | 0 | fixedLegTenor(), |
162 | 0 | fixedLegConvention(), |
163 | 0 | dayCounter(), |
164 | 0 | iborIndex(), |
165 | 0 | discountingTermStructure()); |
166 | 0 | else |
167 | 0 | return ext::make_shared<SwapIndex>(familyName(), |
168 | 0 | tenor, |
169 | 0 | fixingDays(), |
170 | 0 | currency(), |
171 | 0 | fixingCalendar(), |
172 | 0 | fixedLegTenor(), |
173 | 0 | fixedLegConvention(), |
174 | 0 | dayCounter(), |
175 | 0 | iborIndex()); |
176 | |
|
177 | 0 | } |
178 | | |
179 | | OvernightIndexedSwapIndex::OvernightIndexedSwapIndex( |
180 | | const std::string& familyName, |
181 | | const Period& tenor, |
182 | | Natural settlementDays, |
183 | | const Currency& currency, |
184 | | const ext::shared_ptr<OvernightIndex>& overnightIndex, |
185 | | bool telescopicValueDates, |
186 | | RateAveraging::Type averagingMethod) |
187 | 0 | : SwapIndex(familyName, |
188 | 0 | tenor, |
189 | 0 | settlementDays, |
190 | 0 | currency, |
191 | 0 | overnightIndex->fixingCalendar(), |
192 | 0 | 1 * Years, |
193 | 0 | ModifiedFollowing, |
194 | 0 | overnightIndex->dayCounter(), |
195 | 0 | overnightIndex), |
196 | 0 | overnightIndex_(overnightIndex), |
197 | 0 | telescopicValueDates_(telescopicValueDates), |
198 | 0 | averagingMethod_(averagingMethod) {} |
199 | | |
200 | | |
201 | | ext::shared_ptr<OvernightIndexedSwap> |
202 | 0 | OvernightIndexedSwapIndex::underlyingSwap(const Date& fixingDate) const { |
203 | |
|
204 | 0 | QL_REQUIRE(fixingDate!=Date(), "null fixing date"); |
205 | | |
206 | | // caching mechanism |
207 | 0 | if (lastFixingDate_!=fixingDate) { |
208 | 0 | Rate fixedRate = 0.0; |
209 | 0 | lastSwap_ = MakeOIS(tenor_, overnightIndex_, fixedRate) |
210 | 0 | .withEffectiveDate(valueDate(fixingDate)) |
211 | 0 | .withFixedLegDayCount(dayCounter_) |
212 | 0 | .withTelescopicValueDates(telescopicValueDates_) |
213 | 0 | .withAveragingMethod(averagingMethod_); |
214 | 0 | lastFixingDate_ = fixingDate; |
215 | 0 | } |
216 | 0 | return lastSwap_; |
217 | 0 | } |
218 | | |
219 | | } |