QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
lognormalfwdrateipc.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006 Ferdinando Ametrano
5 Copyright (C) 2006 Mark Joshi
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 <http://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/models/marketmodels/evolvers/lognormalfwdrateipc.hpp>
22#include <ql/models/marketmodels/marketmodel.hpp>
23#include <ql/models/marketmodels/evolutiondescription.hpp>
24#include <ql/models/marketmodels/browniangenerator.hpp>
25#include <ql/models/marketmodels/driftcomputation/lmmdriftcalculator.hpp>
26
27namespace QuantLib {
28
30 const ext::shared_ptr<MarketModel>& marketModel,
31 const BrownianGeneratorFactory& factory,
32 const std::vector<Size>& numeraires,
33 Size initialStep)
34 : marketModel_(marketModel),
35 numeraires_(numeraires),
36 initialStep_(initialStep),
37 numberOfRates_(marketModel->numberOfRates()),
38 numberOfFactors_(marketModel->numberOfFactors()),
39 curveState_(marketModel->evolution().rateTimes()),
40 forwards_(marketModel->initialRates()),
41 displacements_(marketModel->displacements()),
42 logForwards_(numberOfRates_), initialLogForwards_(numberOfRates_),
43 drifts1_(numberOfRates_), initialDrifts_(numberOfRates_),
44 g_(numberOfRates_), brownians_(numberOfFactors_),
45 correlatedBrownians_(numberOfRates_),
46 rateTaus_(marketModel->evolution().rateTaus()),
47 alive_(marketModel->evolution().firstAliveRate())
48 {
49 checkCompatibility(marketModel->evolution(), numeraires);
50 QL_REQUIRE(isInTerminalMeasure(marketModel->evolution(), numeraires),
51 "terminal measure required for ipc ");
52
53 Size steps = marketModel->evolution().numberOfSteps();
54
56
58
59 calculators_.reserve(steps);
60 fixedDrifts_.reserve(steps);
61 for (Size j=0; j<steps; ++j) {
62 const Matrix& A = marketModel->pseudoRoot(j);
63 calculators_.emplace_back(A, displacements_, marketModel->evolution().rateTaus(),
64 numeraires[j], alive_[j]);
65 const Matrix& C = marketModel->covariance(j);
66 std::vector<Real> fixed(numberOfRates_);
67 for (Size k=0; k<numberOfRates_; ++k) {
68 Real variance = C[k][k];
69 fixed[k] = -0.5*variance;
70 }
71 fixedDrifts_.push_back(fixed);
72 }
73
74 setForwards(marketModel_->initialRates());
75 }
76
77 const std::vector<Size>& LogNormalFwdRateIpc::numeraires() const {
78 return numeraires_;
79 }
80
81 void LogNormalFwdRateIpc::setForwards(const std::vector<Real>& forwards)
82 {
83 QL_REQUIRE(forwards.size()==numberOfRates_,
84 "mismatch between forwards and rateTimes");
85 for (Size i=0; i<numberOfRates_; ++i)
86 initialLogForwards_[i] = std::log(forwards[i] +
88 calculators_[initialStep_].compute(forwards, initialDrifts_);
89 }
90
93 }
94
97 std::copy(initialLogForwards_.begin(), initialLogForwards_.end(),
98 logForwards_.begin());
99 return generator_->nextPath();
100 }
101
103 {
104 // we're going from T1 to T2:
105
106 // a) compute drifts D1 at T1;
109 } else {
110 std::copy(initialDrifts_.begin(), initialDrifts_.end(),
111 drifts1_.begin());
112 }
113
114 Real weight = generator_->nextStep(brownians_);
115 const Matrix& A = marketModel_->pseudoRoot(currentStep_);
116 const Matrix& C = marketModel_->covariance(currentStep_);
117 const std::vector<Real>& fixedDrift = fixedDrifts_[currentStep_];
118
119 Integer alive = alive_[currentStep_];
120 Real drifts2;
121 for (Integer i=numberOfRates_-1; i>=alive; --i) {
122 drifts2 = 0.0;
123 for (Size j=i+1; j<numberOfRates_; ++j) {
124 drifts2 -= g_[j]*C[i][j];
125 }
126 logForwards_[i] += 0.5*(drifts1_[i]+drifts2) + fixedDrift[i];
127 logForwards_[i] +=
128 std::inner_product(A.row_begin(i), A.row_end(i),
129 brownians_.begin(), Real(0.0));
130 forwards_[i] = std::exp(logForwards_[i]) - displacements_[i];
131 g_[i] = rateTaus_[i]*(forwards_[i]+displacements_[i])/
132 (1.0+rateTaus_[i]*forwards_[i]);
133 }
134
135 // update curve state
137
138 ++currentStep_;
139
140 return weight;
141 }
142
144 return currentStep_;
145 }
146
148 return curveState_;
149 }
150
151}
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_
std::vector< Rate > initialLogForwards_
ext::shared_ptr< MarketModel > marketModel_
LogNormalFwdRateIpc(const ext::shared_ptr< MarketModel > &, const BrownianGeneratorFactory &, const std::vector< Size > &numeraires, Size initialStep=0)
const std::vector< Size > & numeraires() const override
std::vector< LMMDriftCalculator > calculators_
ext::shared_ptr< BrownianGenerator > generator_
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
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
Definition: any.hpp:35
void checkCompatibility(const EvolutionDescription &evolution, const std::vector< Size > &numeraires)
bool isInTerminalMeasure(const EvolutionDescription &evolution, const std::vector< Size > &numeraires)