QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
accountingengine.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/accountingengine.hpp>
21#include <ql/models/marketmodels/curvestate.hpp>
22#include <ql/models/marketmodels/discounter.hpp>
23#include <ql/models/marketmodels/evolutiondescription.hpp>
24#include <ql/models/marketmodels/evolver.hpp>
25#include <algorithm>
26#include <utility>
27
28namespace QuantLib {
29
30 AccountingEngine::AccountingEngine(ext::shared_ptr<MarketModelEvolver> evolver,
31 const Clone<MarketModelMultiProduct>& product,
32 Real initialNumeraireValue)
33 : evolver_(std::move(evolver)), product_(product),
34 initialNumeraireValue_(initialNumeraireValue), numberProducts_(product->numberOfProducts()),
35 numerairesHeld_(product->numberOfProducts()),
36 numberCashFlowsThisStep_(product->numberOfProducts()),
37 cashFlowsGenerated_(product->numberOfProducts()) {
38 for (Size i=0; i<numberProducts_; ++i)
39 cashFlowsGenerated_[i].resize(
40 product_->maxNumberOfCashFlowsPerProductPerStep());
41
42 const std::vector<Time>& cashFlowTimes =
43 product_->possibleCashFlowTimes();
44 const std::vector<Rate>& rateTimes = product_->evolution().rateTimes();
45 discounters_.reserve(cashFlowTimes.size());
46 for (Real cashFlowTime : cashFlowTimes)
47 discounters_.emplace_back(cashFlowTime, rateTimes);
48 }
49
50 Real AccountingEngine::singlePathValues(std::vector<Real>& values) {
51 std::fill(numerairesHeld_.begin(), numerairesHeld_.end(), 0.0);
52 Real weight = evolver_->startNewPath();
53 product_->reset();
54 Real principalInNumerairePortfolio = 1.0;
55
56 bool done = false;
57 do {
58 Size thisStep = evolver_->currentStep();
59 weight *= evolver_->advanceStep();
60 done = product_->nextTimeStep(evolver_->currentState(),
63 Size numeraire =
64 evolver_->numeraires()[thisStep];
65
66 // for each product...
67 for (Size i=0; i<numberProducts_; ++i) {
68 // ...and each cash flow...
69 const std::vector<MarketModelMultiProduct::CashFlow>& cashflows =
71 for (Size j=0; j<numberCashFlowsThisStep_[i]; ++j) {
72 // ...convert the cash flow to numeraires.
73 // This is done by calculating the number of
74 // numeraire bonds corresponding to such cash flow...
75 const MarketModelDiscounter& discounter =
76 discounters_[cashflows[j].timeIndex];
77
78 Real bonds = cashflows[j].amount *
79 discounter.numeraireBonds(evolver_->currentState(),
80 numeraire);
81
82 // ...and adding the newly bought bonds to the number
83 // of numeraires held.
84 numerairesHeld_[i] += bonds/principalInNumerairePortfolio;
85 }
86 }
87
88 if (!done) {
89
90 // The numeraire might change between steps. This implies
91 // that we might have to convert the numeraire bonds for
92 // this step into a corresponding amount of numeraire
93 // bonds for the next step. This can be done by changing
94 // the principal of the numeraire and updating the number
95 // of bonds in the numeraire portfolio accordingly.
96
97 Size nextNumeraire = evolver_->numeraires()[thisStep+1];
98
99 principalInNumerairePortfolio *=
100 evolver_->currentState().discountRatio(numeraire,
101 nextNumeraire);
102 }
103
104 } while (!done);
105
106 for (Size i=0; i<numerairesHeld_.size(); ++i)
108
109 return weight;
110 }
111
113 Size numberOfPaths)
114 {
115 std::vector<Real> values(product_->numberOfProducts());
116 for (Size i=0; i<numberOfPaths; ++i) {
117 Real weight = singlePathValues(values);
118 stats.add(values,weight);
119 }
120 }
121
122}
ext::shared_ptr< MarketModelEvolver > evolver_
std::vector< MarketModelDiscounter > discounters_
void multiplePathValues(SequenceStatisticsInc &stats, Size numberOfPaths)
std::vector< std::vector< MarketModelMultiProduct::CashFlow > > cashFlowsGenerated_
std::vector< Size > numberCashFlowsThisStep_
std::vector< Real > numerairesHeld_
Real singlePathValues(std::vector< Real > &values)
AccountingEngine(ext::shared_ptr< MarketModelEvolver > evolver, const Clone< MarketModelMultiProduct > &product, Real initialNumeraireValue)
Clone< MarketModelMultiProduct > product_
cloning proxy to an underlying object
Definition: clone.hpp:40
Statistics analysis of N-dimensional (sequence) data.
void add(const Sequence &sample, Real weight=1.0)
Real numeraireBonds(const CurveState &, Size numeraire) const
Definition: discounter.cpp:43
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
STL namespace.