QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
lognormalfwdrateiballand.cpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2009 Sun Xiuxin
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
25
26namespace QuantLib {
27
29 const ext::shared_ptr<MarketModel>& marketModel,
30 const BrownianGeneratorFactory& factory,
31 const std::vector<Size>& numeraires,
32 Size initialStep)
33 : marketModel_(marketModel),
34 numeraires_(numeraires),
35 initialStep_(initialStep),
36 numberOfRates_(marketModel->numberOfRates()),
37 numberOfFactors_(marketModel->numberOfFactors()),
38 curveState_(marketModel->evolution().rateTimes()),
39 forwards_(marketModel->initialRates()),
40 displacements_(marketModel->displacements()),
41 logForwards_(numberOfRates_), initialLogForwards_(numberOfRates_),
42 initialDrifts_(numberOfRates_), brownians_(numberOfFactors_),
43 correlatedBrownians_(numberOfRates_),
44 rateTaus_(marketModel->evolution().rateTaus()),
45 alive_(marketModel->evolution().firstAliveRate())
46 {
47 checkCompatibility(marketModel->evolution(), numeraires);
48 QL_REQUIRE( isInTerminalMeasure(marketModel->evolution(), numeraires),
49 "terminal measure required for iBalland " );
50
51 Size steps = marketModel->evolution().numberOfSteps();
52
54
56
57 calculators_.reserve(steps);
58 fixedDrifts_.reserve(steps);
59 for (Size j=0; j<steps; ++j) {
60 const Matrix& A = marketModel->pseudoRoot(j);
61 calculators_.emplace_back(A, displacements_, marketModel->evolution().rateTaus(),
62 numeraires[j], alive_[j]);
63 const Matrix& C = marketModel->covariance(j);
64 std::vector<Real> fixed(numberOfRates_);
65 for (Size k=0; k<numberOfRates_; ++k) {
66 Real variance = C[k][k];
67 fixed[k] = -0.5*variance;
68 }
69 fixedDrifts_.push_back(fixed);
70 }
71
72 setForwards(marketModel_->initialRates());
73 }
74
75 const std::vector<Size>& LogNormalFwdRateiBalland::numeraires() const {
76 return numeraires_;
77 }
78
79 void LogNormalFwdRateiBalland::setForwards(const std::vector<Real>& forwards)
80 {
81 QL_REQUIRE(forwards.size()==numberOfRates_,
82 "mismatch between forwards and rateTimes");
83 for (Size i=0; i<numberOfRates_; ++i)
84 initialLogForwards_[i] = std::log(forwards[i] +
86 calculators_[initialStep_].compute(forwards, initialDrifts_);
87 }
88
91 }
92
95 std::copy(initialLogForwards_.begin(), initialLogForwards_.end(),
96 logForwards_.begin());
97 return generator_->nextPath();
98 }
99
101 {
102 Real weight = generator_->nextStep(brownians_);
103 const Matrix& A = marketModel_->pseudoRoot(currentStep_);
104 const Matrix& C = marketModel_->covariance(currentStep_);
105 const std::vector<Real>& fixedDrift = fixedDrifts_[currentStep_];
106
107 Integer alive = alive_[currentStep_];
108 Integer i;
109 Real blFwd;
110 std::vector<Real> g_(numberOfRates_);
111
112 i = numberOfRates_-1;
113 if ( i >= alive )
114 {
115 logForwards_[i] += fixedDrift[i];
116 logForwards_[i] += std::inner_product( A.row_begin(i), A.row_end(i),
117 brownians_.begin(), Real(0.0) );
118 forwards_[i] = std::exp(logForwards_[i]) - displacements_[i];
119 blFwd = std::sqrt( marketModel_->initialRates()[i]*forwards_[i] );
120 g_[i] = rateTaus_[i]*( blFwd+displacements_[i] )/
121 ( 1.0+rateTaus_[i]*blFwd );
122 }
123
124 Real drifts2;
125 for ( i = numberOfRates_-2; i >= alive ; --i )
126 {
127 drifts2 = 0.0;
128 for ( Size j = i+1; j < numberOfRates_ ; ++j )
129 drifts2 -= g_[j]*C[i][j];
130 logForwards_[i] += drifts2 + fixedDrift[i];
131 logForwards_[i] += std::inner_product( A.row_begin(i), A.row_end(i),
132 brownians_.begin(), Real(0.0));
133 forwards_[i] = std::exp(logForwards_[i]) - displacements_[i];
134
135 blFwd = std::sqrt( marketModel_->initialRates()[i]*forwards_[i] );
136 g_[i] = rateTaus_[i]*( blFwd+displacements_[i] )/
137 ( 1.0+rateTaus_[i]*blFwd );
138 }
139
140 // update curve state
142
143 ++currentStep_;
144
145 return weight;
146 }
147
149 return currentStep_;
150 }
151
153 return curveState_;
154 }
155
156}
virtual ext::shared_ptr< BrownianGenerator > create(Size factors, Size steps) const =0
Curve state for market-model simulations
Definition: curvestate.hpp:41
virtual const std::vector< Rate > & forwardRates() const =0
void setOnForwardRates(const std::vector< Rate > &fwdRates, Size firstValidIndex=0)
const CurveState & currentState() const override
void setForwards(const std::vector< Real > &forwards)
std::vector< std::vector< Real > > fixedDrifts_
ext::shared_ptr< MarketModel > marketModel_
const std::vector< Size > & numeraires() const override
std::vector< LMMDriftCalculator > calculators_
ext::shared_ptr< BrownianGenerator > generator_
LogNormalFwdRateiBalland(const ext::shared_ptr< MarketModel > &, const BrownianGeneratorFactory &, const std::vector< Size > &numeraires, Size initialStep=0)
void setInitialState(const CurveState &) override
Matrix used in linear algebra.
Definition: matrix.hpp:41
const_row_iterator row_begin(Size i) const
Definition: matrix.hpp:360
const_row_iterator row_end(Size i) const
Definition: matrix.hpp:378
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
LinearInterpolation variance
QL_REAL Real
real number
Definition: types.hpp:50
QL_INTEGER Integer
integer number
Definition: types.hpp:35
std::size_t Size
size of a container
Definition: types.hpp:58
Drift computation for Libor market model.
Definition: any.hpp:35
void checkCompatibility(const EvolutionDescription &evolution, const std::vector< Size > &numeraires)
bool isInTerminalMeasure(const EvolutionDescription &evolution, const std::vector< Size > &numeraires)