/src/quantlib/ql/instruments/makecapfloor.cpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2006, 2007 Ferdinando Ametrano |
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 | | <https://www.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 | | |
21 | | #include <ql/instruments/makecapfloor.hpp> |
22 | | #include <ql/cashflows/cashflows.hpp> |
23 | | #include <ql/pricingengines/capfloor/blackcapfloorengine.hpp> |
24 | | |
25 | | namespace QuantLib { |
26 | | |
27 | | MakeCapFloor::MakeCapFloor(CapFloor::Type capFloorType, |
28 | | const Period& tenor, |
29 | | const ext::shared_ptr<IborIndex>& iborIndex, |
30 | | Rate strike, |
31 | | const Period& forwardStart) |
32 | 0 | : capFloorType_(capFloorType), strike_(strike), firstCapletExcluded_(forwardStart == 0 * Days), |
33 | | // setting the fixed leg tenor avoids that MakeVanillaSwap throws |
34 | | // because of an unknown fixed leg default tenor for a currency, |
35 | | // notice that only the floating leg of the swap is used anyway |
36 | 0 | makeVanillaSwap_(MakeVanillaSwap(tenor, iborIndex, 0.0, forwardStart) |
37 | 0 | .withFixedLegTenor(1 * Years) |
38 | 0 | .withFixedLegDayCount(Actual365Fixed())) {} |
39 | | |
40 | 0 | MakeCapFloor::operator CapFloor() const { |
41 | 0 | ext::shared_ptr<CapFloor> capfloor = *this; |
42 | 0 | return *capfloor; |
43 | 0 | } |
44 | | |
45 | 0 | MakeCapFloor::operator ext::shared_ptr<CapFloor>() const { |
46 | |
|
47 | 0 | VanillaSwap swap = makeVanillaSwap_; |
48 | |
|
49 | 0 | Leg leg = swap.floatingLeg(); |
50 | 0 | if (firstCapletExcluded_) |
51 | 0 | leg.erase(leg.begin()); |
52 | | |
53 | | // only leaves the last coupon |
54 | 0 | if (asOptionlet_ && leg.size() > 1) { |
55 | 0 | auto end = leg.end(); // Sun Studio needs an lvalue |
56 | 0 | leg.erase(leg.begin(), --end); |
57 | 0 | } |
58 | |
|
59 | 0 | std::vector<Rate> strikeVector(1, strike_); |
60 | 0 | if (strike_ == Null<Rate>()) { |
61 | | |
62 | | // temporary patch... |
63 | | // should be fixed for every CapFloor::Engine |
64 | 0 | ext::shared_ptr<BlackCapFloorEngine> temp = |
65 | 0 | ext::dynamic_pointer_cast<BlackCapFloorEngine>(engine_); |
66 | 0 | QL_REQUIRE(temp, |
67 | 0 | "cannot calculate ATM without a BlackCapFloorEngine"); |
68 | 0 | Handle<YieldTermStructure> discountCurve = temp->termStructure(); |
69 | 0 | strikeVector[0] = CashFlows::atmRate(leg, |
70 | 0 | **discountCurve, |
71 | 0 | false, |
72 | 0 | discountCurve->referenceDate()); |
73 | 0 | } |
74 | | |
75 | 0 | ext::shared_ptr<CapFloor> capFloor(new |
76 | 0 | CapFloor(capFloorType_, leg, strikeVector)); |
77 | 0 | capFloor->setPricingEngine(engine_); |
78 | 0 | return capFloor; |
79 | 0 | } |
80 | | |
81 | 0 | MakeCapFloor& MakeCapFloor::withNominal(Real n) { |
82 | 0 | makeVanillaSwap_.withNominal(n); |
83 | 0 | return *this; |
84 | 0 | } |
85 | | |
86 | | MakeCapFloor& MakeCapFloor::withEffectiveDate(const Date& effectiveDate, |
87 | 0 | bool firstCapletExcluded) { |
88 | 0 | makeVanillaSwap_.withEffectiveDate(effectiveDate); |
89 | 0 | firstCapletExcluded_ = firstCapletExcluded; |
90 | 0 | return *this; |
91 | 0 | } |
92 | | |
93 | 0 | MakeCapFloor& MakeCapFloor::withTenor(const Period& t) { |
94 | 0 | makeVanillaSwap_.withFloatingLegTenor(t); |
95 | 0 | return *this; |
96 | 0 | } |
97 | | |
98 | | |
99 | 0 | MakeCapFloor& MakeCapFloor::withCalendar(const Calendar& cal) { |
100 | 0 | makeVanillaSwap_.withFloatingLegCalendar(cal); |
101 | 0 | return *this; |
102 | 0 | } |
103 | | |
104 | | |
105 | 0 | MakeCapFloor& MakeCapFloor::withConvention(BusinessDayConvention bdc) { |
106 | 0 | makeVanillaSwap_.withFloatingLegConvention(bdc); |
107 | 0 | return *this; |
108 | 0 | } |
109 | | |
110 | | |
111 | | MakeCapFloor& |
112 | 0 | MakeCapFloor::withTerminationDateConvention(BusinessDayConvention bdc) { |
113 | 0 | makeVanillaSwap_.withFloatingLegTerminationDateConvention(bdc); |
114 | 0 | return *this; |
115 | 0 | } |
116 | | |
117 | | |
118 | 0 | MakeCapFloor& MakeCapFloor::withRule(DateGeneration::Rule r) { |
119 | 0 | makeVanillaSwap_.withFloatingLegRule(r); |
120 | 0 | return *this; |
121 | 0 | } |
122 | | |
123 | 0 | MakeCapFloor& MakeCapFloor::withEndOfMonth(bool flag) { |
124 | 0 | makeVanillaSwap_.withFloatingLegEndOfMonth(flag); |
125 | 0 | return *this; |
126 | 0 | } |
127 | | |
128 | | |
129 | 0 | MakeCapFloor& MakeCapFloor::withFirstDate(const Date& d) { |
130 | 0 | makeVanillaSwap_.withFloatingLegFirstDate(d); |
131 | 0 | return *this; |
132 | 0 | } |
133 | | |
134 | 0 | MakeCapFloor& MakeCapFloor::withNextToLastDate(const Date& d) { |
135 | 0 | makeVanillaSwap_.withFloatingLegNextToLastDate(d); |
136 | 0 | return *this; |
137 | 0 | } |
138 | | |
139 | 0 | MakeCapFloor& MakeCapFloor::withDayCount(const DayCounter& dc) { |
140 | 0 | makeVanillaSwap_.withFloatingLegDayCount(dc); |
141 | 0 | return *this; |
142 | 0 | } |
143 | | |
144 | 0 | MakeCapFloor& MakeCapFloor::asOptionlet(bool b) { |
145 | 0 | asOptionlet_ = b; |
146 | 0 | return *this; |
147 | 0 | } |
148 | | |
149 | | MakeCapFloor& MakeCapFloor::withPricingEngine( |
150 | 0 | const ext::shared_ptr<PricingEngine>& engine) { |
151 | 0 | engine_ = engine; |
152 | 0 | return *this; |
153 | 0 | } |
154 | | |
155 | | } |
156 | | |