QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
montecarlocatbondengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2012, 2013 Grzegorz Andruszkiewicz
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/cashflows/cashflows.hpp>
21#include <ql/experimental/catbonds/montecarlocatbondengine.hpp>
22#include <ql/optional.hpp>
23#include <algorithm>
24#include <utility>
25
26namespace QuantLib {
27
29 ext::shared_ptr<CatRisk> catRisk,
30 Handle<YieldTermStructure> discountCurve,
31 const ext::optional<bool>& includeSettlementDateFlows)
32 : catRisk_(std::move(catRisk)), discountCurve_(std::move(discountCurve)),
33 includeSettlementDateFlows_(includeSettlementDateFlows) {
35 }
36
38 QL_REQUIRE(!discountCurve_.empty(),
39 "discounting term structure handle is empty");
40
41 results_.valuationDate = (*discountCurve_)->referenceDate();
42
43 bool includeRefDateFlows = includeSettlementDateFlows_ ? // NOLINT(readability-implicit-bool-conversion)
46
47 Real lossProbability;
48 Real exhaustionProbability;
49 Real expectedLoss;
50
51 results_.value = npv(includeRefDateFlows,
54 lossProbability,
55 exhaustionProbability,
56 expectedLoss);
57
58 results_.lossProbability = lossProbability;
59 results_.exhaustionProbability = exhaustionProbability;
60 results_.expectedLoss = expectedLoss;
61
62 // a bond's cashflow on settlement date is never taken into
63 // account, so we might have to play it safe and recalculate
64 if (!includeRefDateFlows
66 // same parameters as above, we can avoid another call
68 } else {
69 // no such luck
71 npv(includeRefDateFlows, arguments_.settlementDate, arguments_.settlementDate, lossProbability, exhaustionProbability, expectedLoss);
72 }
73 }
74
75 Real MonteCarloCatBondEngine::npv(bool includeSettlementDateFlows, Date settlementDate, Date npvDate, Real& lossProbability, Real &exhaustionProbability, Real& expectedLoss) const
76 {
77 const size_t MAX_PATHS = 10000; //TODO
78 lossProbability = 0.0;
79 exhaustionProbability = 0.0;
80 expectedLoss = 0.0;
81 if (arguments_.cashflows.empty())
82 return 0.0;
83
84 if (settlementDate == Date())
85 settlementDate = Settings::instance().evaluationDate();
86
87 if (npvDate == Date())
88 npvDate = settlementDate;
89
90 Real totalNPV = 0.0;
91 Date effectiveDate = std::max(arguments_.startDate, settlementDate);
92 Date maturityDate = (*arguments_.cashflows.rbegin())->date();
93 ext::shared_ptr<CatSimulation> catSimulation = catRisk_->newSimulation(effectiveDate, maturityDate);
94 std::vector<std::pair<Date, Real> > eventsPath;
95 NotionalPath notionalPath;
96 Real riskFreeNPV = pathNpv(includeSettlementDateFlows, settlementDate, notionalPath);
97 size_t pathCount=0;
98 while(catSimulation->nextPath(eventsPath) && pathCount<MAX_PATHS)
99 {
100 arguments_.notionalRisk->updatePath(eventsPath, notionalPath);
101 if(notionalPath.loss()>0) { //optimization, most paths will not include any loss
102 totalNPV += pathNpv(includeSettlementDateFlows, settlementDate, notionalPath);
103 lossProbability+=1;
104 if (notionalPath.loss()==1)
105 exhaustionProbability+=1;
106 expectedLoss+=notionalPath.loss();
107 } else {
108 totalNPV += riskFreeNPV;
109 }
110 pathCount++;
111 }
112 lossProbability/=pathCount;
113 exhaustionProbability/=pathCount;
114 expectedLoss/=pathCount;
115 return totalNPV/(pathCount*discountCurve_->discount(npvDate));
116 }
117
118 Real MonteCarloCatBondEngine::pathNpv(bool includeSettlementDateFlows,
119 Date settlementDate,
120 const NotionalPath& notionalPath) const {
121 Real totalNPV = 0.0;
122 for (auto& cashflow : arguments_.cashflows) {
123 if (!cashflow->hasOccurred(settlementDate, includeSettlementDateFlows)) {
124 Real amount = cashFlowRiskyValue(cashflow, notionalPath);
125 totalNPV += amount * discountCurve_->discount(cashflow->date());
126 }
127 }
128 return totalNPV;
129 }
130
131 Real MonteCarloCatBondEngine::cashFlowRiskyValue(const ext::shared_ptr<CashFlow>& cf,
132 const NotionalPath& notionalPath) const {
133 return cf->amount()*notionalPath.notionalRate(cf->date()); //TODO: fix for more complicated cashflows
134 }
135
136}
ext::shared_ptr< NotionalRisk > notionalRisk
Definition: catbond.hpp:69
Concrete date class.
Definition: date.hpp:125
Shared handle to an observable.
Definition: handle.hpp:41
Handle< YieldTermStructure > discountCurve_
MonteCarloCatBondEngine(ext::shared_ptr< CatRisk > catRisk, Handle< YieldTermStructure > discountCurve=Handle< YieldTermStructure >(), const ext::optional< bool > &includeSettlementDateFlows=ext::nullopt)
Real npv(bool includeSettlementDateFlows, Date settlementDate, Date npvDate, Real &lossProbability, Real &exhaustionProbability, Real &expectedLoss) const
Real pathNpv(bool includeSettlementDateFlows, Date settlementDate, const NotionalPath &notionalPath) const
Real cashFlowRiskyValue(const ext::shared_ptr< CashFlow > &cf, const NotionalPath &notionalPath) const
Rate notionalRate(const Date &date) const
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
bool & includeReferenceDateEvents()
Definition: settings.hpp:155
DateProxy & evaluationDate()
the date at which pricing is to be performed.
Definition: settings.hpp:147
static Settings & instance()
access to the unique instance
Definition: singleton.hpp:104
QL_REAL Real
real number
Definition: types.hpp:50
Definition: any.hpp:35
STL namespace.