QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
gaussian1dcapfloorengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2013 Peter Caspers
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/pricingengines/capfloor/gaussian1dcapfloorengine.hpp>
21#include <ql/math/interpolations/cubicinterpolation.hpp>
22#include <ql/payoff.hpp>
23
24namespace QuantLib {
25
27
28 for (Real spread : arguments_.spreads)
29 QL_REQUIRE(spread == 0.0, "Non zero spreads (" << spread << ") are not allowed.");
30
31 Size optionlets = arguments_.startDates.size();
32 std::vector<Real> values(optionlets, 0.0);
33 std::vector<Real> forwards(optionlets, 0.0);
34 Real value = 0.0;
35
36 Date settlement = model_->termStructure()->referenceDate();
37
38 CapFloor::Type type = arguments_.type;
39
41 Array p(z.size());
42
43 for (Size i = 0; i < optionlets; ++i) {
44
45 Date valueDate = arguments_.startDates[i];
46 Date paymentDate = arguments_.endDates[i];
47 ext::shared_ptr<IborIndex> iborIndex =
48 ext::dynamic_pointer_cast<IborIndex>(arguments_.indexes[i]);
49 // if we do not find an ibor index with associated forwarding curve
50 // we fall back on the model curve
51
52 if (paymentDate > settlement) {
53
54 Real f = arguments_.nominals[i] * arguments_.gearings[i];
55 Date fixingDate = arguments_.fixingDates[i];
56 Time fixingTime =
57 model_->termStructure()->timeFromReference(fixingDate);
58
59 Real strike;
60
61 if (type == CapFloor::Cap || type == CapFloor::Collar) {
62 strike = arguments_.capRates[i];
63 if (fixingDate <= settlement) {
64 values[i] =
65 std::max(arguments_.forwards[i] - strike, 0.0) * f *
66 arguments_.accrualTimes[i];
67 } else {
68
69 // todo add openmp support later on (as in gaussian1dswaptionengine)
70
71 for (Size j = 0; j < z.size(); j++) {
72 Real floatingLegNpv;
73 if (iborIndex != nullptr)
74 floatingLegNpv =
75 arguments_.accrualTimes[i] *
76 model_->forwardRate(fixingDate, fixingDate,
77 z[j], iborIndex) *
78 model_->zerobond(paymentDate, fixingDate,
79 z[j], discountCurve_);
80 else
81 floatingLegNpv =
82 (model_->zerobond(valueDate, fixingDate,
83 z[j]) -
84 model_->zerobond(paymentDate, fixingDate,
85 z[j]));
86 Real fixedLegNpv =
87 arguments_.capRates[i] *
88 arguments_.accrualTimes[i] *
89 model_->zerobond(paymentDate, fixingDate, z[j]);
90 p[j] =
91 std::max((floatingLegNpv - fixedLegNpv), 0.0) /
92 model_->numeraire(fixingTime, z[j],
94 }
95 CubicInterpolation payoff(
96 z.begin(), z.end(), p.begin(),
100 Real price = 0.0;
101 for (Size j = 0; j < z.size() - 1; j++) {
103 0.0, payoff.cCoefficients()[j],
104 payoff.bCoefficients()[j],
105 payoff.aCoefficients()[j], p[j], z[j], z[j],
106 z[j + 1]);
107 }
108 if (extrapolatePayoff_) {
110 price +=
112 0.0, 0.0, 0.0, 0.0, p[z.size() - 2],
113 z[z.size() - 2], z[z.size() - 1],
114 100.0);
115 price +=
117 0.0, 0.0, 0.0, 0.0, p[0], z[0], -100.0,
118 z[0]);
119 } else {
120 price +=
122 0.0,
123 payoff.cCoefficients()[z.size() - 2],
124 payoff.bCoefficients()[z.size() - 2],
125 payoff.aCoefficients()[z.size() - 2],
126 p[z.size() - 2], z[z.size() - 2],
127 z[z.size() - 1], 100.0);
128 }
129 }
130 values[i] =
131 price *
132 model_->numeraire(0.0, 0.0, discountCurve_) * f;
133 }
134 }
135 if (type == CapFloor::Floor || type == CapFloor::Collar) {
136 strike = arguments_.floorRates[i];
137 Real floorlet;
138 if (fixingDate <= settlement) {
139 floorlet =
140 std::max(-(arguments_.forwards[i] - strike), 0.0) *
141 f * arguments_.accrualTimes[i];
142 } else {
143 for (Size j = 0; j < z.size(); j++) {
144 Real floatingLegNpv;
145 if (iborIndex != nullptr)
146 floatingLegNpv =
147 arguments_.accrualTimes[i] *
148 model_->forwardRate(fixingDate, fixingDate,
149 z[j], iborIndex) *
150 model_->zerobond(paymentDate, fixingDate,
151 z[j], discountCurve_);
152 else
153 floatingLegNpv =
154 (model_->zerobond(valueDate, fixingDate,
155 z[j]) -
156 model_->zerobond(paymentDate, fixingDate,
157 z[j]));
158 Real fixedLegNpv =
159 arguments_.floorRates[i] *
160 arguments_.accrualTimes[i] *
161 model_->zerobond(paymentDate, fixingDate, z[j]);
162 p[j] =
163 std::max(-(floatingLegNpv - fixedLegNpv), 0.0) /
164 model_->numeraire(fixingTime, z[j],
166 }
167 CubicInterpolation payoff(
168 z.begin(), z.end(), p.begin(),
172 Real price = 0.0;
173 for (Size j = 0; j < z.size() - 1; j++) {
175 0.0, payoff.cCoefficients()[j],
176 payoff.bCoefficients()[j],
177 payoff.aCoefficients()[j], p[j], z[j], z[j],
178 z[j + 1]);
179 }
180 if (extrapolatePayoff_) {
182 price +=
184 0.0, 0.0, 0.0, 0.0, p[z.size() - 2],
185 z[z.size() - 2], z[z.size() - 1],
186 100.0);
187 price +=
189 0.0, 0.0, 0.0, 0.0, p[0], z[0], -100.0,
190 z[0]);
191 } else {
192 price +=
194 0.0, payoff.cCoefficients()[0],
195 payoff.bCoefficients()[0],
196 payoff.aCoefficients()[0], p[0], z[0],
197 -100.0, z[0]);
198 }
199 }
200 floorlet = price *
201 model_->numeraire(0.0, 0.0, discountCurve_) *
202 f;
203 }
204 if (type == CapFloor::Floor) {
205 values[i] = floorlet;
206 } else {
207 // a collar is long a cap and short a floor
208 values[i] -= floorlet;
209 }
210 }
211
212 value += values[i];
213 }
214 }
215
216 results_.value = value;
217
218 results_.additionalResults["optionletsPrice"] = values;
219 results_.additionalResults["optionletsAtmForward"] = forwards;
220 }
221
222}
1-D array used in linear algebra.
Definition: array.hpp:52
const_iterator end() const
Definition: array.hpp:511
Size size() const
dimension of the array
Definition: array.hpp:495
const_iterator begin() const
Definition: array.hpp:503
Cubic interpolation between discrete points.
Concrete date class.
Definition: date.hpp:125
const Handle< YieldTermStructure > discountCurve_
static Real gaussianShiftedPolynomialIntegral(Real a, Real b, Real c, Real d, Real e, Real h, Real x0, Real x1)
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35