Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
fdgaussiancam.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2024 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
25
31#include <qle/models/lgmfdsolver.hpp>
33
34#include <ql/math/comparison.hpp>
35#include <ql/quotes/simplequote.hpp>
36
37namespace ore {
38namespace data {
39
40using namespace QuantLib;
41using namespace QuantExt;
42
43FdGaussianCam::FdGaussianCam(const Handle<CrossAssetModel>& cam, const std::string& currency,
44 const Handle<YieldTermStructure>& curve,
45 const std::vector<std::pair<std::string, QuantLib::ext::shared_ptr<InterestRateIndex>>>& irIndices,
46 const std::set<Date>& simulationDates, const Size stateGridPoints,
47 const Size timeStepsPerYear, const Real mesherEpsilon,
48 const IborFallbackConfig& iborFallbackConfig)
49 : ModelImpl(curve->dayCounter(), stateGridPoints, {currency}, irIndices, {}, {}, {}, simulationDates,
50 iborFallbackConfig),
51 cam_(cam), currency_(currency), curve_(curve), simulationDates_(simulationDates),
52 stateGridPoints_(stateGridPoints), timeStepsPerYear_(timeStepsPerYear), mesherEpsilon_(mesherEpsilon),
53 iborFallbackConfig_(iborFallbackConfig) {
54
55 // check inputs
56
57 QL_REQUIRE(!cam_.empty(), "model is empty");
58
59 // register with observables
60
61 registerWith(curve_);
62 registerWith(cam_);
63} // FdGaussianCam ctor
64
65const Date& FdGaussianCam::referenceDate() const {
66 calculate();
67 return referenceDate_;
68}
69
71
73
74 if (simulationDates_.empty())
75 return;
76
77 // set ref date
78
79 referenceDate_ = curve_->referenceDate();
80
81 // build solver
82
83 solver_ = std::unique_ptr<LgmBackwardSolver>(
84 new LgmFdSolver(cam_->lgm(0), timeFromReference(*simulationDates_.rbegin()), QuantLib::FdmSchemeDesc::Douglas(),
86
87 // set up eff sim dates
88
91 for (auto const& d : simulationDates_) {
92 if (d >= referenceDate())
94 }
95
96 // set additional results provided by this model
97
98 auto ar = getAdditionalResultsMap(cam_->lgm(0)->getCalibrationInfo());
99 additionalResults_.insert(ar.begin(), ar.end());
100}
101
102RandomVariable FdGaussianCam::getFutureBarrierProb(const std::string& index, const Date& obsdate1, const Date& obsdate2,
103 const RandomVariable& barrier, const bool above) const {
104 QL_FAIL("getFutureBarrierProb not implemented by FdGaussianCam");
105}
106
107RandomVariable FdGaussianCam::getIndexValue(const Size indexNo, const Date& d, const Date& fwd) const {
108 QL_FAIL("FdGaussianGam::getIndexValue(): non-ir indices are not allowed, got fx/eq/com index #" << indexNo);
109}
110
111RandomVariable FdGaussianCam::getIrIndexValue(const Size indexNo, const Date& d, const Date& fwd) const {
112 Date fixingDate = d;
113 if (fwd != Null<Date>())
114 fixingDate = fwd;
115 // ensure a valid fixing date
116 fixingDate = irIndices_[indexNo].second->fixingCalendar().adjust(fixingDate);
117 // look up required fixing in cache and return it if found
118 if (auto cacheValue = irIndexValueCache_.find(std::make_tuple(indexNo, d, fixingDate));
119 cacheValue != irIndexValueCache_.end()) {
120 return cacheValue->second;
121 }
122 // compute value, add to cache and return it
123 LgmVectorised lgmv(cam_->irlgm1f(0));
124 auto result = lgmv.fixing(irIndices_[indexNo].second, fixingDate, timeFromReference(d),
125 solver_->stateGrid(timeFromReference(d)));
126 result.setTime(timeFromReference(d));
127 irIndexValueCache_[std::make_tuple(indexNo, d, fixingDate)] = result;
128 return result;
129}
130
131RandomVariable FdGaussianCam::getInfIndexValue(const Size indexNo, const Date& d, const Date& fwd) const {
132 QL_FAIL("FdGaussianGam::getInfIndexValue(): non-ir indices are not allowed, got inf index #" << indexNo);
133}
134
135RandomVariable FdGaussianCam::fwdCompAvg(const bool isAvg, const std::string& indexInput, const Date& obsdate,
136 const Date& start, const Date& end, const Real spread, const Real gearing,
137 const Integer lookback, const Natural rateCutoff, const Natural fixingDays,
138 const bool includeSpread, const Real cap, const Real floor,
139 const bool nakedOption, const bool localCapFloor) const {
140 calculate();
141 auto ir = std::find_if(irIndices_.begin(), irIndices_.end(),
142 [&indexInput](const std::pair<IndexInfo, QuantLib::ext::shared_ptr<InterestRateIndex>>& p) {
143 return p.first.name() == indexInput;
144 });
145 QL_REQUIRE(ir != irIndices_.end(),
146 "FdGaussianCam::fwdComp() ir index " << indexInput << " not found, this is unexpected");
147 LgmVectorised lgmv(cam_->lgm(0)->parametrization());
148 auto on = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(ir->second);
149 QL_REQUIRE(on, "FdGaussianCam::fwdCompAvg(): expected on index for " << indexInput);
150 // only used to extract fixing and value dates
151 auto coupon = QuantLib::ext::make_shared<QuantExt::OvernightIndexedCoupon>(
152 end, 1.0, start, end, on, gearing, spread, Date(), Date(), DayCounter(), false, includeSpread, lookback * Days,
153 rateCutoff, fixingDays);
154 // get model time and state
155 Date effobsdate = std::max(referenceDate(), obsdate);
156 if (isAvg) {
157 return lgmv.averagedOnRate(on, coupon->fixingDates(), coupon->valueDates(), coupon->dt(), rateCutoff,
158 includeSpread, spread, gearing, lookback * Days, cap, floor, localCapFloor,
159 nakedOption, timeFromReference(effobsdate),
160 solver_->stateGrid(timeFromReference(effobsdate)));
161 } else {
162 return lgmv.compoundedOnRate(on, coupon->fixingDates(), coupon->valueDates(), coupon->dt(), rateCutoff,
163 includeSpread, spread, gearing, lookback * Days, cap, floor, localCapFloor,
164 nakedOption, timeFromReference(effobsdate),
165 solver_->stateGrid(timeFromReference(effobsdate)));
166 }
167}
168
169RandomVariable FdGaussianCam::getDiscount(const Size idx, const Date& s, const Date& t) const {
170 LgmVectorised lgmv(cam_->lgm(0)->parametrization());
172}
173
175 LgmVectorised lgmv(cam_->lgm(0)->parametrization());
176 return lgmv.numeraire(timeFromReference(s), solver_->stateGrid(timeFromReference(s)));
177}
178
179Real FdGaussianCam::getFxSpot(const Size idx) const {
180 QL_FAIL("FdGaussianCam::getFxSpot(): this is a single ccy model, there is no fx spot for idx " << idx
181 << " available.");
182}
183
184RandomVariable FdGaussianCam::pay(const RandomVariable& amount, const Date& obsdate, const Date& paydate,
185 const std::string& currency) const {
186 auto result = ModelImpl::pay(amount, obsdate, paydate, currency);
187 result.setTime(timeFromReference(obsdate));
188 return result;
189}
190
191RandomVariable FdGaussianCam::npv(const RandomVariable& amount, const Date& obsdate, const Filter& filter,
192 const boost::optional<long>& memSlot, const RandomVariable& addRegressor1,
193 const RandomVariable& addRegressor2) const {
194
195 QL_REQUIRE(!memSlot, "FdGaussianCam::npv(): mem slot not allowed.");
196 QL_REQUIRE(!filter.initialised(), "FdGaussianCam::npv(): filter not allowed");
197 QL_REQUIRE(!addRegressor1.initialised(), "FdGaussianCam::npv(). addRegressor1 not allowed");
198 QL_REQUIRE(!addRegressor2.initialised(), "FdGaussianCam::npv(). addRegressor2 not allowed");
199
200 calculate();
201
202 Real t1 = amount.time();
203 Real t0 = timeFromReference(obsdate);
204
205 // handle case when amount is deterministic
206
207 if (amount.deterministic()) {
208 RandomVariable result(amount);
209 result.setTime(t0);
210 return result;
211 }
212
213 // handle stochastic amount
214
215 QL_REQUIRE(t1 != Null<Real>(),
216 "FdGaussianCam::npv(): can not roll back amount wiithout time attached (to t0=" << t0 << ")");
217 RandomVariable result = solver_->rollback(amount, t1, t0);
218 result.setTime(t0);
219 return result;
220}
221
223
224 calculate();
225
226 // roll back to today (if necessary)
227
228 RandomVariable r = npv(result, referenceDate(), Filter(), boost::none, RandomVariable(), RandomVariable());
229
230 // we expect the results to be determinstic as per LgmBackwardSolver interface
231
232 QL_REQUIRE(r.deterministic(), "FdGaussianCam::extractT0Result(): internal error, expected result to be "
233 "deterministic after rollback to time t = 0");
234
235 return r.at(0);
236}
237
238} // namespace data
239} // namespace ore
RandomVariable discountBond(const Time t, const Time T, const RandomVariable &x, const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >()) const
RandomVariable fixing(const boost::shared_ptr< InterestRateIndex > &index, const Date &fixingDate, const Time t, const RandomVariable &x) const
RandomVariable averagedOnRate(const boost::shared_ptr< OvernightIndex > &index, const std::vector< Date > &fixingDates, const std::vector< Date > &valueDates, const std::vector< Real > &dt, const Natural rateCutoff, const bool includeSpread, const Real spread, const Real gearing, const Period lookback, Real cap, Real floor, const bool localCapFloor, const bool nakedOption, const Time t, const RandomVariable &x) const
RandomVariable numeraire(const Time t, const RandomVariable &x, const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >()) const
RandomVariable compoundedOnRate(const boost::shared_ptr< OvernightIndex > &index, const std::vector< Date > &fixingDates, const std::vector< Date > &valueDates, const std::vector< Real > &dt, const Natural rateCutoff, const bool includeSpread, const Real spread, const Real gearing, const Period lookback, Real cap, Real floor, const bool localCapFloor, const bool nakedOption, const Time t, const RandomVariable &x) const
std::set< Date > simulationDates_
RandomVariable getInfIndexValue(const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const override
void performCalculations() const override
void releaseMemory() override
RandomVariable getFutureBarrierProb(const std::string &index, const Date &obsdate1, const Date &obsdate2, const RandomVariable &barrier, const bool above) const override
RandomVariable getIrIndexValue(const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const override
RandomVariable npv(const RandomVariable &amount, const Date &obsdate, const Filter &filter, const boost::optional< long > &memSlot, const RandomVariable &addRegressor1, const RandomVariable &addRegressor2) const override
std::unique_ptr< LgmBackwardSolver > solver_
Real getFxSpot(const Size idx) const override
std::map< std::tuple< Size, Date, Date >, RandomVariable > irIndexValueCache_
const Date & referenceDate() const override
RandomVariable getNumeraire(const Date &s) const override
Handle< CrossAssetModel > cam_
Handle< YieldTermStructure > curve_
Real extractT0Result(const RandomVariable &result) const override
std::set< Date > effectiveSimulationDates_
RandomVariable pay(const RandomVariable &amount, const Date &obsdate, const Date &paydate, const std::string &currency) const override
RandomVariable getDiscount(const Size idx, const Date &s, const Date &t) const override
RandomVariable getIndexValue(const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const override
RandomVariable fwdCompAvg(const bool isAvg, const std::string &index, const Date &obsdate, const Date &start, const Date &end, const Real spread, const Real gearing, const Integer lookback, const Natural rateCutoff, const Natural fixingDays, const bool includeSpread, const Real cap, const Real floor, const bool nakedOption, const bool localCapFloor) const override
FdGaussianCam(const Handle< CrossAssetModel > &cam, const std::string &currency, const Handle< YieldTermStructure > &curve, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< InterestRateIndex > > > &irIndices, const std::set< Date > &simulationDates, const Size stateGridPoints=50, const Size timeStepsPerYear=24, const Real mesherEpsilon=1E-4, const IborFallbackConfig &iborFallbackConfig=IborFallbackConfig::defaultConfig())
std::map< std::string, boost::any > additionalResults_
Definition: model.hpp:153
Real timeFromReference(const Date &d) const
Definition: model.hpp:92
std::vector< std::pair< IndexInfo, QuantLib::ext::shared_ptr< InterestRateIndex > > > irIndices_
Definition: modelimpl.hpp:112
RandomVariable pay(const RandomVariable &amount, const Date &obsdate, const Date &paydate, const std::string &currency) const override
Definition: modelimpl.cpp:101
SafeStack< Filter > filter
fd gaussian cross asset model for single underlying ir model
Map text representations to QuantLib/QuantExt types.
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
QuantLib::Date fixingDate(const QuantLib::Date &d, const QuantLib::Period obsLag, const QuantLib::Frequency freq, bool interpolated)
std::map< std::string, boost::any > getAdditionalResultsMap(const LgmCalibrationInfo &info)
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
Real at(const Size i) const
bool deterministic() const
void setTime(const Real time)
string conversion utilities