/src/quantlib/ql/models/marketmodels/marketmodeldifferences.cpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2007 François du Vignaud |
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 | | <https://www.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/models/marketmodels/marketmodel.hpp> |
21 | | #include <ql/models/marketmodels/evolutiondescription.hpp> |
22 | | #include <ql/models/marketmodels/piecewiseconstantcorrelation.hpp> |
23 | | #include <ql/models/marketmodels/models/piecewiseconstantvariance.hpp> |
24 | | |
25 | | namespace QuantLib { |
26 | | |
27 | | std::vector<Volatility> rateVolDifferences( |
28 | | const MarketModel& marketModel1, |
29 | 0 | const MarketModel& marketModel2) { |
30 | 0 | QL_ENSURE(marketModel1.initialRates() == marketModel2.initialRates(), |
31 | 0 | "initialRates do not match"); |
32 | 0 | const EvolutionDescription& evolutionDescription1 |
33 | 0 | = marketModel1.evolution(); |
34 | 0 | const EvolutionDescription& evolutionDescription2 |
35 | 0 | = marketModel2.evolution(); |
36 | 0 | QL_ENSURE(evolutionDescription1.evolutionTimes() |
37 | 0 | == evolutionDescription2.evolutionTimes(), |
38 | 0 | "Evolution times do not match"); |
39 | | |
40 | 0 | const Matrix& totalCovariance1 |
41 | 0 | = marketModel1.totalCovariance(marketModel1.numberOfSteps()-1); |
42 | 0 | const Matrix& totalCovariance2 |
43 | 0 | = marketModel2.totalCovariance(marketModel2.numberOfSteps()-1); |
44 | 0 | const std::vector<Time>& maturities = |
45 | 0 | evolutionDescription1.evolutionTimes(); |
46 | |
|
47 | 0 | std::vector<Volatility> result(totalCovariance1.columns()); |
48 | 0 | for (Size i=0; i<totalCovariance1.columns(); ++i) { |
49 | 0 | Real diff = totalCovariance1[i][i]-totalCovariance2[i][i]; |
50 | 0 | result[i] = std::sqrt(diff/maturities[i]); |
51 | 0 | } |
52 | 0 | return result; |
53 | 0 | } |
54 | | |
55 | | std::vector<Spread> rateInstVolDifferences( |
56 | | const MarketModel& marketModel1, |
57 | | const MarketModel& marketModel2, |
58 | 0 | Size index) { |
59 | 0 | QL_ENSURE(marketModel1.initialRates() == marketModel2.initialRates(), |
60 | 0 | "initialRates do not match"); |
61 | 0 | const EvolutionDescription& evolutionDescription1 |
62 | 0 | = marketModel1.evolution(); |
63 | 0 | const EvolutionDescription& evolutionDescription2 |
64 | 0 | = marketModel2.evolution(); |
65 | 0 | QL_ENSURE(evolutionDescription1.evolutionTimes() |
66 | 0 | == evolutionDescription2.evolutionTimes(), |
67 | 0 | "Evolution times do not match"); |
68 | 0 | QL_ENSURE(index<evolutionDescription1.numberOfSteps(), |
69 | 0 | "the index given is greater than the number of steps"); |
70 | | |
71 | 0 | const std::vector<Time>& evolutionTimes |
72 | 0 | = evolutionDescription1.evolutionTimes(); |
73 | 0 | std::vector<Spread> result(evolutionTimes.size()); |
74 | |
|
75 | 0 | Time previousEvolutionTime = 0; |
76 | 0 | for (Size i=0; i<evolutionTimes.size(); ++i) { |
77 | 0 | Time currentEvolutionTime = evolutionTimes[i]; |
78 | 0 | Time dt = currentEvolutionTime - previousEvolutionTime; |
79 | 0 | const Matrix& covariance1 = marketModel1.covariance(i); |
80 | 0 | const Matrix& covariance2 = marketModel2.covariance(i); |
81 | 0 | Real diff = covariance1[index][index] - covariance2[index][index]; |
82 | 0 | result[i] = std::sqrt(diff/dt); |
83 | 0 | previousEvolutionTime = currentEvolutionTime; |
84 | 0 | } |
85 | 0 | return result; |
86 | 0 | } |
87 | | |
88 | | std::vector<Matrix> coterminalSwapPseudoRoots( |
89 | | const PiecewiseConstantCorrelation& piecewiseConstantCorrelation, |
90 | | const std::vector<ext::shared_ptr<PiecewiseConstantVariance> >& |
91 | 0 | piecewiseConstantVariances) { |
92 | 0 | QL_ENSURE(piecewiseConstantCorrelation.times() |
93 | 0 | == piecewiseConstantVariances.front()->rateTimes(), |
94 | 0 | "correlations and volatilities intertave"); |
95 | 0 | std::vector<Matrix> pseudoRoots; |
96 | 0 | const std::vector<Time>& rateTimes |
97 | 0 | = piecewiseConstantVariances.front()->rateTimes(); |
98 | 0 | for (Size i=1; i<rateTimes.size(); ++i) { |
99 | 0 | Time sqrtTau = std::sqrt(rateTimes[i]-rateTimes[i-1]); |
100 | 0 | const Matrix& correlations |
101 | 0 | = piecewiseConstantCorrelation.correlation(i); |
102 | 0 | Matrix pseudoRoot(correlations.rows(), correlations.rows()); |
103 | 0 | for (Size j=0; j<correlations.rows(); ++j) { |
104 | 0 | Real volatility |
105 | 0 | = piecewiseConstantVariances[j]->volatility(i)*sqrtTau; |
106 | 0 | std::transform(correlations.row_begin(j), |
107 | 0 | correlations.row_end(j), |
108 | 0 | pseudoRoot.row_begin(j), |
109 | 0 | [=](Real x) -> Real { return x * volatility; }); |
110 | 0 | } |
111 | 0 | pseudoRoots.push_back(pseudoRoot); |
112 | 0 | } |
113 | 0 | return pseudoRoots; |
114 | 0 | } |
115 | | |
116 | | } |
117 | | |