/src/quantlib/ql/experimental/catbonds/riskynotional.hpp
Line | Count | Source (jump to first uncovered line) |
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 | | /*! \file riskynotional.hpp |
21 | | \brief classes to track the notional of a cat bond |
22 | | */ |
23 | | |
24 | | #ifndef quantlib_risky_notional_hpp |
25 | | #define quantlib_risky_notional_hpp |
26 | | |
27 | | #include <ql/errors.hpp> |
28 | | #include <ql/shared_ptr.hpp> |
29 | | #include <ql/time/date.hpp> |
30 | | #include <algorithm> |
31 | | #include <utility> |
32 | | #include <vector> |
33 | | |
34 | | namespace QuantLib { |
35 | | |
36 | | class EventPaymentOffset { |
37 | | public: |
38 | | virtual ~EventPaymentOffset() = default; |
39 | | virtual Date paymentDate(const Date& eventDate) = 0; |
40 | | }; |
41 | | |
42 | | class NoOffset : public EventPaymentOffset { |
43 | | public: |
44 | 0 | Date paymentDate(const Date& eventDate) override { return eventDate; } |
45 | | }; |
46 | | |
47 | | class NotionalPath { |
48 | | public: |
49 | | NotionalPath(); |
50 | | |
51 | | Rate notionalRate(const Date& date) const; //The fraction of the original notional left on a given date |
52 | | |
53 | | void reset(); |
54 | | |
55 | | void addReduction(const Date &date, Rate newRate); |
56 | | |
57 | | Real loss(); |
58 | | |
59 | | private: |
60 | | std::vector<std::pair<Date, Real> > notionalRate_; |
61 | | }; |
62 | | |
63 | | class NotionalRisk { |
64 | | public: |
65 | | explicit NotionalRisk(ext::shared_ptr<EventPaymentOffset> paymentOffset) |
66 | 0 | : paymentOffset_(std::move(paymentOffset)) {} |
67 | 0 | virtual ~NotionalRisk() = default; |
68 | | |
69 | | virtual void updatePath(const std::vector<std::pair<Date, Real> >& events, |
70 | | NotionalPath& path) const = 0; |
71 | | |
72 | | protected: |
73 | | ext::shared_ptr<EventPaymentOffset> paymentOffset_; |
74 | | }; |
75 | | |
76 | | class DigitalNotionalRisk : public NotionalRisk { |
77 | | public: |
78 | | DigitalNotionalRisk(const ext::shared_ptr<EventPaymentOffset>& paymentOffset, |
79 | | Real threshold) |
80 | 0 | : NotionalRisk(paymentOffset), threshold_(threshold) {} |
81 | | |
82 | | void updatePath(const std::vector<std::pair<Date, Real> >& events, |
83 | | NotionalPath& path) const override; |
84 | | |
85 | | protected: |
86 | | Real threshold_; |
87 | | }; |
88 | | |
89 | | |
90 | | class ProportionalNotionalRisk : public NotionalRisk |
91 | | { |
92 | | public: |
93 | | ProportionalNotionalRisk(const ext::shared_ptr<EventPaymentOffset>& paymentOffset, |
94 | | Real attachement, |
95 | | Real exhaustion) |
96 | 0 | : NotionalRisk(paymentOffset), attachement_(attachement), exhaustion_(exhaustion) { |
97 | 0 | QL_REQUIRE(attachement < exhaustion, |
98 | 0 | "exhaustion level needs to be greater than attachement"); |
99 | 0 | } |
100 | | |
101 | | void updatePath(const std::vector<std::pair<Date, Real> >& events, |
102 | 0 | NotionalPath& path) const override { |
103 | 0 | path.reset(); |
104 | 0 | Real losses = 0; |
105 | 0 | Real previousNotional = 1; |
106 | 0 | for (const auto& event : events) { |
107 | 0 | losses += event.second; |
108 | 0 | if(losses>attachement_ && previousNotional>0) |
109 | 0 | { |
110 | 0 | previousNotional = std::max(0.0, (exhaustion_-losses)/(exhaustion_-attachement_)); |
111 | 0 | path.addReduction(paymentOffset_->paymentDate(event.first), previousNotional); |
112 | 0 | } |
113 | 0 | } |
114 | 0 | } |
115 | | |
116 | | protected: |
117 | | Real attachement_; |
118 | | Real exhaustion_; |
119 | | }; |
120 | | |
121 | | } |
122 | | |
123 | | #endif |