32 ext::shared_ptr<LogNormalFwdRateEuler> evolver,
34 ext::shared_ptr<MarketModel> pseudoRootStructure,
35 Real initialNumeraireValue)
36 : evolver_(
std::move(evolver)), product_(product),
37 pseudoRootStructure_(
std::move(pseudoRootStructure)),
38 initialNumeraireValue_(initialNumeraireValue), numberProducts_(product->numberOfProducts()),
39 doDeflation_(!product->alreadyDeflated()), numerairesHeld_(product->numberOfProducts()),
42 deflatorAndDerivatives_(pseudoRootStructure_->numberOfRates() + 1) {
67 product_->maxNumberOfCashFlowsPerProductPerStep());
87 const std::vector<Time>& cashFlowTimes =
91 const std::vector<Time>& rateTimes =
product_->evolution().rateTimes();
92 const std::vector<Time>& evolutionTimes =
product_->evolution().evolutionTimes();
95 for (
Real cashFlowTime : cashFlowTimes)
110 std::upper_bound(evolutionTimes.begin(), evolutionTimes.end(), cashFlowTimes[i]);
111 if (it != evolutionTimes.begin())
113 Size index = it - evolutionTimes.begin();
154 Size storeStep = thisStep+1;
197 bool flowsFound =
false;
199 Integer finalStepDone = thisStep;
203 Integer stepToUse = std::min<Integer>(currentStep, finalStepDone)+1;
214 flowsFound = flowsFound || !noFlows;
240 V_[j][stepToUse][i-1] += thisDerivative;
250 Integer nextStepToUse = std::min<Integer>(currentStep-1, finalStepDone);
251 Integer nextStepIndex = nextStepToUse+1;
252 if (nextStepIndex != stepToUse)
260 for (
Size f=0;
f < factors; ++
f)
265 Real thisPartialTerm = libor*V*pseudo;
279 V_[i][nextStepIndex][j] = nextV;
281 Real summandTerm = 0.0;
282 for (
Size f=0;
f < factors; ++
f)
283 summandTerm += thisPseudoRoot_[j][
f]*
partials_[
f][j];
287 V_[i][nextStepIndex][j] += summandTerm;
316 for (
Size i=0; i<numberOfPaths; ++i)
319 stats.
add(values,weight);
328 ext::shared_ptr<LogNormalFwdRateEuler> evolver,
330 ext::shared_ptr<MarketModel> pseudoRootStructure,
331 const std::vector<std::vector<Matrix> >& vegaBumps,
332 Real initialNumeraireValue)
333 : evolver_(
std::move(evolver)), product_(product),
334 pseudoRootStructure_(
std::move(pseudoRootStructure)),
335 initialNumeraireValue_(initialNumeraireValue), numberProducts_(product->numberOfProducts()),
336 doDeflation_(!product->alreadyDeflated()), numerairesHeld_(product->numberOfProducts()),
339 stepsDiscounts_(pseudoRootStructure_->numberOfRates() + 1),
340 vegasThisPath_(product->numberOfProducts(), vegaBumps[0].size()),
341 deflatorAndDerivatives_(pseudoRootStructure_->numberOfRates() + 1) {
360 Size thisSize = vegaBumps[i].size();
391 product_->maxNumberOfCashFlowsPerProductPerStep());
398 V_.push_back(VModel);
411 const std::vector<Time>& cashFlowTimes =
415 const std::vector<Time>& rateTimes =
product_->evolution().rateTimes();
416 const std::vector<Time>& evolutionTimes =
product_->evolution().evolutionTimes();
419 for (
Real cashFlowTime : cashFlowTimes)
434 std::upper_bound(evolutionTimes.begin(), evolutionTimes.end(), cashFlowTimes[i]);
435 if (it != evolutionTimes.begin())
437 Size index = it - evolutionTimes.begin();
481 Size storeStep = thisStep+1;
533 bool flowsFound =
false;
535 Integer finalStepDone = thisStep;
539 Integer stepToUse = std::min<Integer>(currentStep, finalStepDone)+1;
550 flowsFound = flowsFound || !noFlows;
579 V_[j][stepToUse][i-1] += thisDerivative;
601 Integer nextStepToUse = std::min<Integer>(currentStep-1, finalStepDone);
602 Integer nextStepIndex = nextStepToUse+1;
603 if (nextStepIndex != stepToUse)
611 for (
Size f=0;
f < factors; ++
f)
616 Real thisPartialTerm = libor*V*pseudo;
631 V_[i][nextStepIndex][j] = nextV;
633 Real summandTerm = 0.0;
634 for (
Size f=0;
f < factors; ++
f)
635 summandTerm += thisPseudoRoot_[j][
f]*
partials_[
f][j];
639 V_[i][nextStepIndex][j] += summandTerm;
645 if (nextStepIndex >0)
681 means.resize(values.size());
682 errors.resize(values.size());
683 std::vector<Real> sums(values.size(),0.0);
684 std::vector<Real> sumsqs(values.size(),0.0);
688 for (
Size i=0; i<numberOfPaths; ++i)
692 for (
Size j=0; j < values.size(); ++j)
694 sums[j] += values[j];
695 sumsqs[j] += values[j]*values[j];
700 for (
Size j=0; j < values.size(); ++j)
702 means[j] = sums[j]/numberOfPaths;
703 Real meanSq = sumsqs[j]/numberOfPaths;
705 errors[j] = std::sqrt(
variance/numberOfPaths);
714 ext::shared_ptr<LogNormalFwdRateEuler> evolver,
716 ext::shared_ptr<MarketModel> pseudoRootStructure,
717 const std::vector<std::vector<Matrix> >& vegaBumps,
718 Real initialNumeraireValue)
719 : evolver_(
std::move(evolver)), product_(product),
720 pseudoRootStructure_(
std::move(pseudoRootStructure)), vegaBumps_(vegaBumps),
721 initialNumeraireValue_(initialNumeraireValue), numberProducts_(product->numberOfProducts()),
722 doDeflation_(!product->alreadyDeflated()), numerairesHeld_(product->numberOfProducts()),
725 stepsDiscounts_(pseudoRootStructure_->numberOfRates() + 1),
726 elementary_vegas_ThisPath_(product->numberOfProducts()),
727 deflatorAndDerivatives_(pseudoRootStructure_->numberOfRates() + 1) {
741 QL_REQUIRE(vegaBumps.size() ==
numberSteps_,
"we need precisely one vector of vega bumps for each step.");
745 std::vector<Matrix> jacobiansThisPathsModel;
783 product_->maxNumberOfCashFlowsPerProductPerStep());
790 V_.push_back(VModel);
803 const std::vector<Time>& cashFlowTimes =
807 const std::vector<Time>& rateTimes =
product_->evolution().rateTimes();
808 const std::vector<Time>& evolutionTimes =
product_->evolution().evolutionTimes();
811 for (
Real cashFlowTime : cashFlowTimes)
826 std::upper_bound(evolutionTimes.begin(), evolutionTimes.end(), cashFlowTimes[i]);
827 if (it != evolutionTimes.begin())
829 Size index = it - evolutionTimes.begin();
896 Size storeStep = thisStep+1;
950 bool flowsFound =
false;
952 Integer finalStepDone = thisStep;
956 Integer stepToUse = std::min<Integer>(currentStep, finalStepDone)+1;
967 flowsFound = flowsFound || !noFlows;
996 V_[j][stepToUse][i-1] += thisDerivative;
1006 Integer nextStepToUse = std::min<Integer>(currentStep-1, finalStepDone);
1007 Integer nextStepIndex = nextStepToUse+1;
1008 if (nextStepIndex != stepToUse)
1016 for (
Size f=0;
f < factors; ++
f)
1021 Real thisPartialTerm = libor*V*pseudo;
1036 V_[i][nextStepIndex][j] = nextV;
1038 Real summandTerm = 0.0;
1039 for (
Size f=0;
f < factors; ++
f)
1040 summandTerm += thisPseudoRoot_[j][
f]*
partials_[
f][j];
1044 V_[i][nextStepIndex][j] += summandTerm;
1063 Size nextIndex = j+1;
1071 Real sensitivity =0.0;
1116 std::vector<Real> values(
product_->numberOfProducts()*(1+
numberRates_+numberOfElementaryVegas));
1117 means.resize(values.size());
1118 errors.resize(values.size());
1119 std::vector<Real> sums(values.size(),0.0);
1120 std::vector<Real> sumsqs(values.size(),0.0);
1124 for (
Size i=0; i<numberOfPaths; ++i)
1128 for (
Size j=0; j < values.size(); ++j)
1130 sums[j] += values[j];
1131 sumsqs[j] += values[j]*values[j];
1136 for (
Size j=0; j < values.size(); ++j)
1138 means[j] = sums[j]/numberOfPaths;
1139 Real meanSq = sumsqs[j]/numberOfPaths;
1141 errors[j] = std::sqrt(
variance/numberOfPaths);
1148 std::vector<Real> allMeans;
1149 std::vector<Real> allErrors;
1163 means[i+p*outDataPerProduct] = allMeans[i+p*inDataPerProduct];
1164 errors[i+p*outDataPerProduct] = allErrors[i+p*inDataPerProduct];
1178 means[p*outDataPerProduct+1+
numberRates_+bump] = thisVega;
cloning proxy to an underlying object
Market-model evolution description.
const std::vector< Time > & rateTaus() const
const std::vector< Size > & firstAliveRate() const
Statistics analysis of N-dimensional (sequence) data.
void add(const Sequence &sample, Real weight=1.0)
Matrix used in linear algebra.
std::vector< Real > deflatorAndDerivatives_
ext::shared_ptr< LogNormalFwdRateEuler > evolver_
std::vector< std::vector< MarketModelPathwiseMultiProduct::CashFlow > > cashFlowsGenerated_
PathwiseAccountingEngine(ext::shared_ptr< LogNormalFwdRateEuler > evolver, const Clone< MarketModelPathwiseMultiProduct > &product, ext::shared_ptr< MarketModel > pseudoRootStructure, Real initialNumeraireValue)
std::vector< std::vector< Size > > numberCashFlowsThisIndex_
Matrix StepsDiscountsSquared_
Real initialNumeraireValue_
void multiplePathValues(SequenceStatisticsInc &stats, Size numberOfPaths)
std::vector< Real > currentForwards_
ext::shared_ptr< MarketModel > pseudoRootStructure_
std::vector< Size > numberCashFlowsThisStep_
std::vector< Real > numerairesHeld_
std::vector< Matrix > totalCashFlowsThisIndex_
Size numberCashFlowTimes_
std::vector< Real > lastForwards_
std::vector< std::vector< Size > > cashFlowIndicesThisStep_
Real singlePathValues(std::vector< Real > &values)
Clone< MarketModelPathwiseMultiProduct > product_
std::vector< MarketModelPathwiseDiscounter > discounters_
std::vector< Real > fullDerivatives_
void multiplePathValues(std::vector< Real > &means, std::vector< Real > &errors, Size numberOfPaths)
PathwiseVegasAccountingEngine(ext::shared_ptr< LogNormalFwdRateEuler > evolver, const Clone< MarketModelPathwiseMultiProduct > &product, ext::shared_ptr< MarketModel > pseudoRootStructure, const std::vector< std::vector< Matrix > > &VegaBumps, Real initialNumeraireValue)
std::vector< Real > deflatorAndDerivatives_
ext::shared_ptr< LogNormalFwdRateEuler > evolver_
std::vector< std::vector< MarketModelPathwiseMultiProduct::CashFlow > > cashFlowsGenerated_
std::vector< std::vector< Size > > numberCashFlowsThisIndex_
Matrix StepsDiscountsSquared_
Real initialNumeraireValue_
std::vector< Real > currentForwards_
std::vector< RatePseudoRootJacobian > jacobianComputers_
ext::shared_ptr< MarketModel > pseudoRootStructure_
std::vector< Size > numberCashFlowsThisStep_
std::vector< Size > numeraires_
std::vector< Real > numerairesHeld_
std::vector< Real > stepsDiscounts_
std::vector< Matrix > totalCashFlowsThisIndex_
Size numberCashFlowTimes_
std::vector< Matrix > jacobiansThisPaths_
std::vector< Real > lastForwards_
std::vector< std::vector< Size > > cashFlowIndicesThisStep_
Real singlePathValues(std::vector< Real > &values)
Clone< MarketModelPathwiseMultiProduct > product_
std::vector< MarketModelPathwiseDiscounter > discounters_
std::vector< Real > fullDerivatives_
void multiplePathValues(std::vector< Real > &means, std::vector< Real > &errors, Size numberOfPaths)
Use to get vegas with respect to VegaBumps.
std::vector< Real > deflatorAndDerivatives_
ext::shared_ptr< LogNormalFwdRateEuler > evolver_
void multiplePathValuesElementary(std::vector< Real > &means, std::vector< Real > &errors, Size numberOfPaths)
Use to get vegas with respect to pseudo-root-elements.
std::vector< std::vector< MarketModelPathwiseMultiProduct::CashFlow > > cashFlowsGenerated_
std::vector< std::vector< Size > > numberCashFlowsThisIndex_
Matrix StepsDiscountsSquared_
std::vector< std::vector< Matrix > > vegaBumps_
Real initialNumeraireValue_
Size numberElementaryVegas_
std::vector< std::vector< Matrix > > jacobiansThisPaths_
std::vector< std::vector< Matrix > > elementary_vegas_ThisPath_
std::vector< Real > currentForwards_
ext::shared_ptr< MarketModel > pseudoRootStructure_
std::vector< Size > numberCashFlowsThisStep_
PathwiseVegasOuterAccountingEngine(ext::shared_ptr< LogNormalFwdRateEuler > evolver, const Clone< MarketModelPathwiseMultiProduct > &product, ext::shared_ptr< MarketModel > pseudoRootStructure, const std::vector< std::vector< Matrix > > &VegaBumps, Real initialNumeraireValue)
std::vector< Size > numeraires_
std::vector< Real > numerairesHeld_
std::vector< Real > stepsDiscounts_
std::vector< Matrix > totalCashFlowsThisIndex_
std::vector< RatePseudoRootJacobianAllElements > jacobianComputers_
Size numberCashFlowTimes_
std::vector< Real > lastForwards_
std::vector< std::vector< Size > > cashFlowIndicesThisStep_
Real singlePathValues(std::vector< Real > &values)
Clone< MarketModelPathwiseMultiProduct > product_
std::vector< MarketModelPathwiseDiscounter > discounters_
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
LinearInterpolation variance
QL_INTEGER Integer
integer number
std::size_t Size
size of a container
std::vector< Size > moneyMarketMeasure(const EvolutionDescription &evol)
ext::shared_ptr< YieldTermStructure > r
std::vector< Size > numberCashFlowsThisStep_
std::vector< std::vector< CashFlow > > cashFlowsGenerated_