Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
spreadeddiscountcurve.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 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
20
21#include <ql/math/interpolations/loginterpolation.hpp>
22
23namespace QuantExt {
24
25SpreadedDiscountCurve::SpreadedDiscountCurve(const Handle<YieldTermStructure>& referenceCurve,
26 const std::vector<Time>& times, const std::vector<Handle<Quote>>& quotes,
27 const Interpolation interpolation, const Extrapolation extrapolation)
28 : YieldTermStructure(referenceCurve->dayCounter()), referenceCurve_(referenceCurve), times_(times), quotes_(quotes),
29 interpolation_(interpolation), extrapolation_(extrapolation), data_(times_.size(), 1.0) {
30 QL_REQUIRE(times_.size() > 1, "SpreadedDiscountCurve: at least two times required");
31 QL_REQUIRE(times_.size() == quotes.size(), "SpreadedDiscountCurve: size of time and quote vectors do not match");
32 QL_REQUIRE(times_[0] == 0.0, "SpreadedDiscountCurve: first time must be 0, got " << times_[0]);
33 for (Size i = 0; i < quotes.size(); ++i) {
34 registerWith(quotes_[i]);
35 }
37 dataInterpolation_ = QuantLib::ext::make_shared<LogLinearInterpolation>(times_.begin(), times_.end(), data_.begin());
38 } else {
39 dataInterpolation_ = QuantLib::ext::make_shared<LinearInterpolation>(times_.begin(), times_.end(), data_.begin());
40 }
41 dataInterpolation_->enableExtrapolation();
42 registerWith(referenceCurve_);
43}
44
45Date SpreadedDiscountCurve::maxDate() const { return referenceCurve_->maxDate(); }
46
48 LazyObject::update();
49 TermStructure::update();
50}
51
52const Date& SpreadedDiscountCurve::referenceDate() const { return referenceCurve_->referenceDate(); }
53
54Calendar SpreadedDiscountCurve::calendar() const { return referenceCurve_->calendar(); }
55
56Natural SpreadedDiscountCurve::settlementDays() const { return referenceCurve_->settlementDays(); }
57
59 for (Size i = 0; i < times_.size(); ++i) {
60 QL_REQUIRE(!quotes_[i].empty(), "SpreadedDiscountCurve: quote at index " << i << " is empty");
61 data_[i] = quotes_[i]->value();
62 QL_REQUIRE(data_[i] > 0, "SpreadedDiscountCurve: invalid value " << data_[i] << " at index " << i);
63 }
65 for (Size i = 0; i < times_.size(); ++i) {
66 data_[i] = -std::log(data_[std::max<Size>(i, 1)]) / times_[std::max<Size>(i, 1)];
67 }
68 }
69 dataInterpolation_->update();
70}
71
72DiscountFactor SpreadedDiscountCurve::discountImpl(Time t) const {
73 calculate();
74 Time tMax = this->times_.back();
75 DiscountFactor dMax =
76 interpolation_ == Interpolation::logLinear ? this->data_.back() : std::exp(-this->data_.back() * tMax);
77 if (t <= this->times_.back()) {
78 Real tmp = (*dataInterpolation_)(t, true);
80 return referenceCurve_->discount(t) * tmp;
81 else
82 return referenceCurve_->discount(t) * std::exp(-tmp * t);
83 }
85 Rate instFwdMax = -(*dataInterpolation_).derivative(tMax) / dMax;
86 return referenceCurve_->discount(t) * dMax * std::exp(-instFwdMax * (t - tMax));
87 } else {
88 return referenceCurve_->discount(t) * std::pow(dMax, t / tMax);
89 }
90}
91
92} // namespace QuantExt
Calendar calendar() const override
Handle< YieldTermStructure > referenceCurve_
DiscountFactor discountImpl(Time t) const override
const Date & referenceDate() const override
Natural settlementDays() const override
std::vector< Handle< Quote > > quotes_
SpreadedDiscountCurve(const Handle< YieldTermStructure > &referenceCurve, const std::vector< Time > &times, const std::vector< Handle< Quote > > &quotes, const Interpolation interpolation=Interpolation::logLinear, const Extrapolation extrapolation=Extrapolation::flatFwd)
times should be consistent with reference ts day counter
QuantLib::ext::shared_ptr< QuantLib::Interpolation > dataInterpolation_
spreaded discount term structure