• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lballabio / QuantLib / 10558053048

26 Aug 2024 10:24AM UTC coverage: 72.653%. Remained the same
10558053048

push

github

web-flow
Deprecate some experimental code (#2064)

55094 of 75832 relevant lines covered (72.65%)

8654926.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/ql/experimental/risk/sensitivityanalysis.cpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2008 Ferdinando Ametrano
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/experimental/risk/sensitivityanalysis.hpp>
21
#include <ql/quotes/simplequote.hpp>
22
#include <ql/instrument.hpp>
23

24
using std::vector;
25
using std::pair;
26

27
namespace QuantLib {
28

29
    QL_DEPRECATED_DISABLE_WARNING
30

31
    std::ostream& operator<<(std::ostream& out,
×
32
                             SensitivityAnalysis s) {
33
        switch (s) {
×
34
          case OneSide:
×
35
            return out << "OneSide";
×
36
          case Centered:
×
37
            return out << "Centered";
×
38
          default:
×
39
            QL_FAIL("unknown SensitivityAnalysis (" << Integer(s) << ")");
×
40
        }
41
    }
42

43
    Real aggregateNPV(const vector<ext::shared_ptr<Instrument> >& instruments,
×
44
                      const vector<Real>& quant) {
45
        Size n = instruments.size();
46
        Real npv = 0.0;
47
        if (quant.empty() || (quant.size()==1 && quant[0]==1.0)) {
×
48
            for (Size k=0; k<n; ++k)
×
49
                npv += instruments[k]->NPV();
×
50
        } else {
51
            QL_REQUIRE(quant.size()==n,
×
52
                       "dimension mismatch between instruments (" << n <<
53
                       ") and quantities (" << quant.size() << ")");
54
            for (Size k=0; k<n; ++k)
×
55
                npv += quant[k] * instruments[k]->NPV();
×
56
        }
57
        return npv;
×
58
    }
59

60
    pair<Real, Real>
61
    parallelAnalysis(const vector<Handle<SimpleQuote> >& quotes,
×
62
                     const vector<ext::shared_ptr<Instrument> >& instruments,
63
                     const vector<Real>& quantities,
64
                     Real shift,
65
                     SensitivityAnalysis type,
66
                     Real referenceNpv)
67
    {
68
        QL_REQUIRE(!quotes.empty(), "empty SimpleQuote vector");
×
69
        Size n = quotes.size();
70

71
        QL_REQUIRE(shift!=0.0, "zero shift not allowed");
×
72

73
        pair<Real, Real> result(0.0, 0.0);
74
        if (instruments.empty()) return result;
×
75

76
        if (referenceNpv==Null<Real>())
×
77
            referenceNpv = aggregateNPV(instruments, quantities);
×
78

79
        vector<Real> quoteValues(n, Null<Real>());
×
80
        for (Size i=0; i<n; ++i)
×
81
            if (quotes[i]->isValid())
×
82
                quoteValues[i] = quotes[i]->value();
×
83
        try {
84
            for (Size i=0; i<n; ++i)
×
85
                if (quotes[i]->isValid())
×
86
                    quotes[i]->setValue(quoteValues[i]+shift);
×
87
            Real npv = aggregateNPV(instruments, quantities);
×
88
            switch (type) {
×
89
              case OneSide:
×
90
                result.first = (npv-referenceNpv)/shift;
×
91
                result.second = Null<Real>();
92
                break;
×
93
              case Centered:
94
                {
95
                for (Size i=0; i<n; ++i)
×
96
                    if (quotes[i]->isValid())
×
97
                        quotes[i]->setValue(quoteValues[i]-shift);
×
98
                Real npv2 = aggregateNPV(instruments, quantities);
×
99
                result.first = (npv-npv2)/(2.0*shift);
×
100
                result.second = (npv-2.0*referenceNpv+npv2)/(shift*shift);
×
101
                }
102
                break;
×
103
              default:
×
104
                  QL_FAIL("unknown SensitivityAnalysis (" <<
×
105
                          Integer(type) << ")");
106
            }
107
            for (Size i=0; i<n; ++i)
×
108
                if (quotes[i]->isValid())
×
109
                    quotes[i]->setValue(quoteValues[i]);
×
110
        } catch (...) {
×
111
            for (Size i=0; i<n; ++i)
×
112
                if (quoteValues[i]!=Null<Real>())
×
113
                    quotes[i]->setValue(quoteValues[i]);
×
114
            throw;
×
115
        }
×
116

117
        return result;
×
118
    }
119

120
    pair<Real, Real> bucketAnalysis(const Handle<SimpleQuote>& quote,
×
121
                                    const vector<ext::shared_ptr<Instrument> >& instruments,
122
                                    const vector<Real>& quantities,
123
                                    Real shift,
124
                                    SensitivityAnalysis type,
125
                                    Real referenceNpv) {
126
        QL_REQUIRE(shift!=0.0, "zero shift not allowed");
×
127

128
        pair<Real, Real> result(0.0, 0.0);
129
        if (instruments.empty()) return result;
×
130

131
        if (referenceNpv==Null<Real>())
×
132
            referenceNpv = aggregateNPV(instruments, quantities);
×
133

134
        if (!quote->isValid()) return result;
×
135
        Real quoteValue = quote->value();
×
136

137
        try {
138
            quote->setValue(quoteValue+shift);
×
139
            Real npv = aggregateNPV(instruments, quantities);
×
140
            switch (type) {
×
141
              case OneSide:
×
142
                result.first = (npv-referenceNpv)/shift;
×
143
                result.second = Null<Real>();
144
                break;
×
145
              case Centered:
×
146
                {
147
                quote->setValue(quoteValue-shift);
×
148
                Real npv2 = aggregateNPV(instruments, quantities);
×
149
                result.first = (npv-npv2)/(2.0*shift);
×
150
                result.second = (npv-2.0*referenceNpv+npv2)/(shift*shift);
×
151
                }
152
                break;
×
153
              default:
×
154
                  QL_FAIL("unknown SensitivityAnalysis (" <<
×
155
                          Integer(type) << ")");
156
            }
157
            quote->setValue(quoteValue);
×
158
        } catch (...) {
×
159
            quote->setValue(quoteValue);
×
160
            throw;
×
161
        }
×
162

163
        return result;
×
164
    }
165

166

167
    void bucketAnalysis(vector<Real>& deltaVector, // delta result
×
168
                        vector<Real>& gammaVector, // gamma result
169
                        vector<Real>& refVals,
170
                        const Handle<SimpleQuote>& quote,
171
                        const vector<Handle<Quote> >& params,
172
                        Real shift,
173
                        SensitivityAnalysis type) {
174
        QL_REQUIRE(shift!=0.0, "zero shift not allowed");
×
175

176
        QL_REQUIRE(!params.empty(), "empty parameters vector");
×
177
        Size m = params.size();
178
        deltaVector.resize(m);
×
179
        gammaVector.resize(m);
×
180

181
        if (!quote->isValid()) {
×
182
            for (Size j=0; j<m; ++j) {
×
183
                deltaVector[j]=Null<Real>();
×
184
                gammaVector[j]=Null<Real>();
×
185
            }
186
            return;
187
        }
188
        Real quoteValue = quote->value();
×
189

190
        if (!refVals.empty()) {
×
191
            QL_REQUIRE(refVals.size()==m,
×
192
                       "referenceValues has size " <<
193
                       refVals.size() << ", instead of " << m);
194
        } else {
195
            // calculate parameters' reference values
196
            refVals = vector<Real>(m, Null<Real>());
×
197
            for (Size j=0; j<m; ++j) {
×
198
                if (params[j]->isValid()) // fault tolerant
×
199
                    refVals[j] = params[j]->value();
×
200
            }
201
        }
202

203
        try {
204
            switch (type) {
×
205
              case OneSide:
×
206
                {
207
                    quote->setValue(quoteValue+shift);
×
208
                    for (Size j=0; j<m; ++j) {
×
209
                        gammaVector[j] = Null<Real>();
×
210
                        if (refVals[j] != Null<Real>())
×
211
                            deltaVector[j] = (params[j]->value()-refVals[j])/shift;
×
212
                        else
213
                            deltaVector[j] = Null<Real>();
×
214
                    }
215
                }
216
                break;
217
              case Centered:
×
218
                {
219
                    quote->setValue(quoteValue+shift);
×
220
                    vector<Real> plus(m);
×
221
                    for (Size j=0; j<m; ++j) {
×
222
                        if (refVals[j] != Null<Real>())
×
223
                            plus[j] = params[j]->value();
×
224
                    }
225
                    quote->setValue(quoteValue-shift);
×
226
                    for (Size j=0; j<m; ++j) {
×
227
                        if (refVals[j] != Null<Real>()) {
×
228
                            Real minus = params[j]->value();
×
229
                            deltaVector[j] = (plus[j]-minus)/(2.0*shift);
×
230
                            gammaVector[j] = (plus[j]-2.0*refVals[j]+minus)/(shift*shift);
×
231
                        } else {
232
                            deltaVector[j] = Null<Real>();
×
233
                            gammaVector[j] = Null<Real>();
×
234
                        }
235
                    }
236
                }
237
                break;
×
238
              default:
×
239
                  QL_FAIL("unknown SensitivityAnalysis (" <<
×
240
                          Integer(type) << ")");
241
            } // end switch
242

243
            // restore the quote to its original state
244
            quote->setValue(quoteValue);
×
245

246
            return;
247
        } catch (...) {
×
248
            // restore the quote to its original state
249
            quote->setValue(quoteValue);
×
250
            throw;
×
251
        }
×
252

253
    }
254

255

256

257

258

259
    pair<vector<Real>, vector<Real> >
260
    bucketAnalysis(const vector<Handle<SimpleQuote> >& quotes,
×
261
                   const vector<ext::shared_ptr<Instrument> >& instr,
262
                   const vector<Real>& quant,
263
                   Real shift,
264
                   SensitivityAnalysis type)
265
    {
266
        QL_REQUIRE(!quotes.empty(), "empty SimpleQuote vector");
×
267
        Size n = quotes.size();
268
        pair<vector<Real>, vector<Real> > result(vector<Real>(n, 0.0),
×
269
                                                 vector<Real>(n, 0.0));
×
270

271
        if (instr.empty()) return result;
×
272

273
        Real npv = aggregateNPV(instr, quant);
×
274

275
        pair<Real, Real> tmp;
276
        for (Size i=0; i<n; ++i) {
×
277
            tmp = bucketAnalysis(quotes[i], instr, quant, shift, type, npv);
×
278
            result.first[i] = tmp.first;
×
279
            result.second[i] = tmp.second;
×
280
        }
281

282
        return result;
283
    }
284

285
    void
286
    bucketAnalysis(std::vector<std::vector<Real> >& deltaMatrix, // result
×
287
                   std::vector<std::vector<Real> >& gammaMatrix, // result
288
                   const vector<Handle<SimpleQuote> >& quotes,
289
                   const vector<Handle<Quote> >& parameters,
290
                   Real shift,
291
                   SensitivityAnalysis type)
292
    {
293
        QL_REQUIRE(!quotes.empty(), "empty SimpleQuote vector");
×
294
        QL_REQUIRE(!parameters.empty(), "empty parameters vector");
×
295

296
        Size n = quotes.size();
297
        deltaMatrix.resize(n);
×
298
        gammaMatrix.resize(n);
×
299

300
        Size m = parameters.size();
301
        vector<Real> referenceValues(m, Null<Real>());
×
302
        for (Size i=0; i<m; ++i) {
×
303
            if (parameters[i]->isValid())
×
304
                referenceValues[i] = parameters[i]->value();
×
305
        }
306

307
        for (Size i=0; i<n; ++i) {
×
308
            bucketAnalysis(deltaMatrix[i], gammaMatrix[i], referenceValues,
×
309
                           quotes[i], parameters, shift, type);
310
        }
311
    }
×
312

313
    pair<vector<vector<Real> >, vector<vector<Real> > >
314
    bucketAnalysis(const vector<vector<Handle<SimpleQuote> > >& quotes,
×
315
                   const vector<ext::shared_ptr<Instrument> >& instr,
316
                   const vector<Real>& quant,
317
                   Real shift,
318
                   SensitivityAnalysis type)
319
    {
320
        QL_REQUIRE(!quotes.empty(), "empty SimpleQuote range");
×
321
        Size n = quotes.size();
322
        vector<vector<Real> > first(n);
×
323
        vector<vector<Real> > second(n);
×
324
        for (Size i=0; i<n; ++i) {
×
325
            Size tmp = quotes[i].size();
326
            first[i] = vector<Real>(tmp, 0.0);
×
327
            second[i] = vector<Real>(tmp, 0.0);
×
328
        }
329

330
        pair<vector<vector<Real> >, vector<vector<Real> > >
331
            result(first, second);
×
332

333
        if (instr.empty()) return result;
×
334

335
        Real npv = aggregateNPV(instr, quant);
×
336

337
        pair<Real, Real> tmp;
338
        for (Size i=0; i<n; ++i) {
×
339
          for (Size j=0; j<quotes[i].size(); ++j) {
×
340
            tmp = bucketAnalysis(quotes[i][j], instr, quant, shift, type, npv);
×
341
            result.first[i][j] = tmp.first;
×
342
            result.second[i][j] = tmp.second;
×
343
          }
344
        }
345

346
        return result;
347
    }
×
348

349
    QL_DEPRECATED_ENABLE_WARNING
350
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc