QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
collectnodedata.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006 Mark Joshi
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/models/marketmodels/callability/collectnodedata.hpp>
21#include <ql/models/marketmodels/discounter.hpp>
22#include <ql/models/marketmodels/utilities.hpp>
23#include <ql/models/marketmodels/multiproduct.hpp>
24#include <ql/models/marketmodels/evolver.hpp>
25#include <ql/models/marketmodels/callability/nodedataprovider.hpp>
26#include <ql/models/marketmodels/callability/exercisevalue.hpp>
27#include <ql/models/marketmodels/evolutiondescription.hpp>
28#include <ql/models/marketmodels/curvestate.hpp>
29#include <ql/methods/montecarlo/nodedata.hpp>
30#include <ql/errors.hpp>
31
32namespace QuantLib {
33
35
38 MarketModelNodeDataProvider& dataProvider,
41 Size numberOfPaths,
42 std::vector<std::vector<NodeData> >& collectedData) {
43
44 std::vector<Real> numerairesHeld;
45
46 QL_REQUIRE(product.numberOfProducts() == 1,
47 "a single product is required");
48
49 // TODO: check that all objects have compatible evolutions
50 // (same rate times; evolution times for product, basis
51 // system, rebate and control must be subsets of the passed
52 // evolution times; rebate, control and basis system must have
53 // the same exercise---not evolution---times)
54
55 std::vector<Size> numberCashFlowsThisStep(1);
56 std::vector<std::vector<CashFlow> > cashFlowsGenerated(1);
57 cashFlowsGenerated[0].resize(
59
60
61 std::vector<Time> rateTimes = product.evolution().rateTimes();
62
63 std::vector<Time> cashFlowTimes = product.possibleCashFlowTimes();
64 std::vector<Time> rebateTimes = rebate.possibleCashFlowTimes();
65 std::vector<Time> controlTimes = control.possibleCashFlowTimes();
66
67 Size i, n;
68
69 n = cashFlowTimes.size();
70 std::vector<MarketModelDiscounter> productDiscounters;
71 productDiscounters.reserve(n);
72 for (i=0; i<n; ++i)
73 productDiscounters.emplace_back(cashFlowTimes[i], rateTimes);
74
75 n = rebateTimes.size();
76 std::vector<MarketModelDiscounter> rebateDiscounters;
77 rebateDiscounters.reserve(n);
78 for (i=0; i<n; ++i)
79 rebateDiscounters.emplace_back(rebateTimes[i], rateTimes);
80 n = controlTimes.size();
81 std::vector<MarketModelDiscounter> controlDiscounters;
82 controlDiscounters.reserve(n);
83 for (i=0; i<n; ++i)
84 controlDiscounters.emplace_back(controlTimes[i], rateTimes);
85
86 EvolutionDescription evolution = product.evolution();
87 const std::vector<Size>& numeraires = evolver.numeraires();
88
89 const std::vector<Time>& evolutionTimes = evolution.evolutionTimes();
90
91 std::valarray<bool> isProductTime =
92 isInSubset(evolutionTimes,
93 product.evolution().evolutionTimes());
94 std::valarray<bool> isRebateTime =
95 isInSubset(evolutionTimes,
96 rebate.evolution().evolutionTimes());
97 std::valarray<bool> isControlTime =
98 isInSubset(evolutionTimes,
99 control.evolution().evolutionTimes());
100 std::valarray<bool> isBasisTime =
101 isInSubset(evolutionTimes,
102 dataProvider.evolution().evolutionTimes());
103 std::valarray<bool> isExerciseTime(false,evolutionTimes.size());
104 std::valarray<bool> v = rebate.isExerciseTime();
105 Size exercises = 0, idx = 0;
106 for (i=0; i<evolutionTimes.size(); ++i) {
107 if (isRebateTime[i]) {
108 if(v[idx++]) {
109 isExerciseTime[i] = true;
110 exercises++;
111 }
112 }
113 }
114
115 collectedData.resize(exercises+1);
116 for (i=0; i<collectedData.size(); ++i)
117 collectedData[i].resize(numberOfPaths);
118
119
120 for (i=0; i<numberOfPaths; ++i) {
121 evolver.startNewPath();
122 product.reset();
123 rebate.reset();
124 control.reset();
125 dataProvider.reset();
126 Real principalInNumerairePortfolio = 1.0;
127
128 bool done = false;
129 Size nextExercise = 0;
130 collectedData[0][i].cumulatedCashFlows = 0.0;
131 do {
132 Size currentStep = evolver.currentStep();
133 evolver.advanceStep();
134 const CurveState& currentState = evolver.currentState();
135 Size numeraire = numeraires[currentStep];
136
137 if (isRebateTime[currentStep])
138 rebate.nextStep(currentState);
139 if (isControlTime[currentStep])
140 control.nextStep(currentState);
141 if (isBasisTime[currentStep])
142 dataProvider.nextStep(currentState);
143
144 if (isExerciseTime[currentStep]) {
145 NodeData& data = collectedData[nextExercise+1][i];
146
147 CashFlow exerciseValue = rebate.value(currentState);
148 data.exerciseValue =
149 exerciseValue.amount *
150 rebateDiscounters[exerciseValue.timeIndex]
151 .numeraireBonds(currentState, numeraire) /
152 principalInNumerairePortfolio;
153
154 dataProvider.values(currentState,
155 data.values);
156
157 CashFlow controlValue = control.value(currentState);
158 data.controlValue =
159 controlValue.amount *
160 controlDiscounters[controlValue.timeIndex]
161 .numeraireBonds(currentState, numeraire) /
162 principalInNumerairePortfolio;
163
164 data.cumulatedCashFlows = 0.0;
165
166 data.isValid = true;
167
168 ++nextExercise;
169 }
170
171 if (isProductTime[currentStep]) {
172 done = product.nextTimeStep(currentState,
173 numberCashFlowsThisStep,
174 cashFlowsGenerated);
175
176 for (Size j=0; j<numberCashFlowsThisStep[0]; ++j) {
177 const CashFlow& cf = cashFlowsGenerated[0][j];
178 collectedData[nextExercise][i].cumulatedCashFlows +=
179 cf.amount *
180 productDiscounters[cf.timeIndex]
181 .numeraireBonds(currentState, numeraire) /
182 principalInNumerairePortfolio;
183 }
184 }
185
186 if (!done) {
187 Size nextNumeraire = numeraires[currentStep+1];
188 principalInNumerairePortfolio *=
189 currentState.discountRatio(numeraire,
190 nextNumeraire);
191 }
192 }
193 while (!done);
194
195 // fill the remaining (un)collected data with nulls
196 for (Size j = nextExercise; j < exercises; ++j) {
197 NodeData& data = collectedData[j+1][i];
198 data.exerciseValue = data.controlValue = 0.0;
199 data.cumulatedCashFlows = 0.0;
200 data.isValid = false;
201 }
202 }
203 }
204
205}
Base class for cash flows.
Definition: cashflow.hpp:40
virtual Real amount() const =0
returns the amount of the cash flow
Curve state for market-model simulations
Definition: curvestate.hpp:41
virtual Real discountRatio(Size i, Size j) const =0
Market-model evolution description.
const std::vector< Time > & rateTimes() const
const std::vector< Time > & evolutionTimes() const
Market-model evolver.
Definition: evolver.hpp:35
virtual const std::vector< Size > & numeraires() const =0
virtual Real advanceStep()=0
virtual const CurveState & currentState() const =0
virtual Size currentStep() const =0
virtual Real startNewPath()=0
virtual std::vector< Time > possibleCashFlowTimes() const =0
virtual MarketModelMultiProduct::CashFlow value(const CurveState &) const =0
virtual std::valarray< bool > isExerciseTime() const =0
virtual const EvolutionDescription & evolution() const =0
virtual void nextStep(const CurveState &)=0
virtual std::vector< Time > possibleCashFlowTimes() const =0
virtual Size numberOfProducts() const =0
virtual void reset()=0
during simulation put product at start of path
virtual Size maxNumberOfCashFlowsPerProductPerStep() const =0
virtual const EvolutionDescription & evolution() const =0
virtual bool nextTimeStep(const CurveState &currentState, std::vector< Size > &numberCashFlowsThisStep, std::vector< std::vector< CashFlow > > &cashFlowsGenerated)=0
return value indicates whether path is finished, TRUE means done
virtual void values(const CurveState &, std::vector< Real > &results) const =0
virtual const EvolutionDescription & evolution() const =0
virtual void nextStep(const CurveState &)=0
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
std::valarray< bool > isInSubset(const std::vector< Time > &set, const std::vector< Time > &subset)
Definition: utilities.cpp:56
void collectNodeData(MarketModelEvolver &evolver, MarketModelMultiProduct &product, MarketModelNodeDataProvider &dataProvider, MarketModelExerciseValue &rebate, MarketModelExerciseValue &control, Size numberOfPaths, std::vector< std::vector< NodeData > > &collectedData)
std::vector< Real > values
Definition: nodedata.hpp:32