Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
basecorrelationstructure.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2022 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file basecorrelationstructure.hpp
20 \brief abstract base correlation structure and an 2d-interpolated base correlation structure
21*/
22
23#pragma once
24
25#include <boost/optional/optional.hpp>
26#include <ql/math/interpolations/bilinearinterpolation.hpp>
27#include <ql/patterns/lazyobject.hpp>
28#include <ql/quote.hpp>
29#include <ql/time/dategenerationrule.hpp>
30
32
33namespace QuantExt {
34
35using namespace QuantLib;
36
38public:
40
41 BaseCorrelationTermStructure(const Date& referenceDate, const Calendar& cal, BusinessDayConvention bdc,
42 const std::vector<Period>& tenors, const std::vector<double>& detachmentPoints,
43 const DayCounter& dc = DayCounter(), const Date& startDate = Date(),
44 boost::optional<DateGeneration::Rule> rule = boost::none);
45
46 BaseCorrelationTermStructure(Natural settlementDays, const Calendar& cal, BusinessDayConvention bdc,
47 const std::vector<Period>& tenors, const std::vector<double>& detachmentPoints,
48 const DayCounter& dc = DayCounter(), const Date& startDate = Date(),
49 boost::optional<DateGeneration::Rule> rule = boost::none);
50
51 virtual ~BaseCorrelationTermStructure() = default;
52
53 // TermStructure interface
54 virtual Date maxDate() const override { return dates_.back(); }
55
56 virtual Time maxTime() const override { return times_.back(); }
57 virtual Time minTime() const override { return times_.front(); }
58
59 virtual double minDetachmentPoint() const { return detachmentPoints_.front(); }
60 virtual double maxDetachmentPoint() const { return detachmentPoints_.back(); }
61
62 std::vector<double> times() const { return times_; }
63
64 std::vector<double> detachmentPoints() const { return detachmentPoints_; }
65
66 std::vector<Date> dates() const { return dates_; }
67
68 BusinessDayConvention businessDayConvention() const { return bdc_; }
69
70 Date startDate() const { return startDate_; }
71
72 boost::optional<DateGeneration::Rule> rule() const { return rule_; }
73
74private:
75 BusinessDayConvention bdc_;
77 boost::optional<DateGeneration::Rule> rule_;
78
79 void validate() const;
80
81 void initializeDatesAndTimes() const;
82
83protected:
84 virtual void checkRange(Time t, Real strike, bool extrapolate) const override;
85
86 std::vector<Period> tenors_;
87 std::vector<double> detachmentPoints_;
88 mutable std::vector<Date> dates_;
89 mutable std::vector<double> times_;
90};
91
92template <class Interpolator>
94public:
95 InterpolatedBaseCorrelationTermStructure(Natural settlementDays, const Calendar& cal, BusinessDayConvention bdc,
96 const std::vector<Period>& tenors,
97 const std::vector<Real>& detachmentPoints,
98 const std::vector<std::vector<Handle<Quote>>>& baseCorrelations,
99 const DayCounter& dc = DayCounter(), const Date& startDate = Date(),
100 boost::optional<DateGeneration::Rule> rule = boost::none,
101 Interpolator interpolator = Interpolator())
102 : BaseCorrelationTermStructure(settlementDays, cal, bdc, tenors, detachmentPoints, dc, startDate, rule),
103 quotes_(baseCorrelations), data_(detachmentPoints.size(), tenors.size(), 0.0), interpolator_(interpolator) {
104
105 // check quotes
106 QL_REQUIRE(quotes_.size() == detachmentPoints_.size(), "Mismatch between tenors and correlation quotes");
107 for (const auto& row : this->quotes_) {
108 QL_REQUIRE(row.size() == tenors_.size(),
109 "Mismatch between number of detachment points and quotes");
110 }
111
112 this->interpolation_ =
113 this->interpolator_.interpolate(this->times_.begin(), this->times_.end(), this->detachmentPoints_.begin(),
114 this->detachmentPoints_.end(), this->data_);
115 this->interpolation_.update();
116
117 // register with each of the quotes
118 for (Size i = 0; i < this->quotes_.size(); i++) {
119 for (Size j = 0; j < this->quotes_[i].size(); ++j) {
120
121 QL_REQUIRE(this->quotes_[i][j]->value() >= 0.0 && this->quotes_[i][j]->value() <= 1.0,
122 "correlation not in range (0.0,1.0): " << this->quotes_[i][j]->value());
123
124 registerWith(this->quotes_[i][j]);
125 }
126 }
127 }
128
129 //@}
130 //! \name Observer interface
131 //@{
132 void update() override;
133 //@}
134protected:
135 //! \name CorrelationTermStructure implementation
136 //@{
137 Real correlationImpl(Time t, Real detachmentPoint) const override;
138 //@}
139 std::vector<std::vector<Handle<Quote>>> quotes_;
140 mutable Matrix data_;
141
142
143private:
144 //! \name LazyObject interface
145 //@{
146 void performCalculations() const override;
147 //@}
148
149 Interpolator interpolator_;
150
151 mutable Interpolation2D interpolation_;
152
153
154};
155
157
158 for (Size i = 0; i < this->detachmentPoints_.size(); ++i)
159 for (Size j = 0; j < this->times_.size(); ++j)
160 this->data_[i][j] = quotes_[i][j]->value();
161 this->interpolation_ =
162 this->interpolator_.interpolate(this->times_.begin(), this->times_.end(), this->detachmentPoints_.begin(),
163 this->detachmentPoints_.end(), this->data_);
164 this->interpolation_.update();
165}
166
168 LazyObject::update();
169 BaseCorrelationTermStructure::update();
170}
171
172template <class T>
173Real InterpolatedBaseCorrelationTermStructure<T>::correlationImpl(Time t, Real detachmentPoint) const {
174 calculate();
175 return this->interpolation_(t, detachmentPoint, true);
176}
177
179
180}; // namespace QuantExt
virtual void checkRange(Time t, Real strike, bool extrapolate) const override
Extra time range check for minimum time, then calls TermStructure::checkRange.
std::vector< double > detachmentPoints() const
boost::optional< DateGeneration::Rule > rule_
virtual ~BaseCorrelationTermStructure()=default
BaseCorrelationTermStructure(const Date &referenceDate, const Calendar &cal, BusinessDayConvention bdc, const std::vector< Period > &tenors, const std::vector< double > &detachmentPoints, const DayCounter &dc=DayCounter(), const Date &startDate=Date(), boost::optional< DateGeneration::Rule > rule=boost::none)
boost::optional< DateGeneration::Rule > rule() const
virtual Time minTime() const override
The minimum time for which the curve can return values.
BusinessDayConvention businessDayConvention() const
Real correlationImpl(Time t, Real detachmentPoint) const override
Correlation calculation.
std::vector< std::vector< Handle< Quote > > > quotes_
InterpolatedBaseCorrelationTermStructure(Natural settlementDays, const Calendar &cal, BusinessDayConvention bdc, const std::vector< Period > &tenors, const std::vector< Real > &detachmentPoints, const std::vector< std::vector< Handle< Quote > > > &baseCorrelations, const DayCounter &dc=DayCounter(), const Date &startDate=Date(), boost::optional< DateGeneration::Rule > rule=boost::none, Interpolator interpolator=Interpolator())
Term structure of correlations.
InterpolatedBaseCorrelationTermStructure< QuantLib::Bilinear > BilinearBaseCorrelationCurve