Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
linkablecalibratedmodel.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 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#include <ql/math/optimization/problem.hpp>
20#include <ql/math/optimization/projectedconstraint.hpp>
21#include <ql/math/optimization/projection.hpp>
22#include <ql/utilities/null_deleter.hpp>
24
25using QuantLib::ext::shared_ptr;
26using std::vector;
27
28namespace QuantExt {
29
31 : constraint_(new PrivateConstraint(arguments_)), endCriteria_(EndCriteria::None) {}
32
33class LinkableCalibratedModel::CalibrationFunction : public CostFunction {
34public:
35 CalibrationFunction(LinkableCalibratedModel* model, const vector<shared_ptr<CalibrationHelper> >& h,
36 const vector<Real>& weights, const Projection& projection)
37 : model_(model, null_deleter()), instruments_(h), weights_(weights), projection_(projection) {}
38
39 virtual ~CalibrationFunction() {}
40
41 virtual Real value(const Array& params) const override {
42 model_->setParams(projection_.include(params));
43 Real value = 0.0;
44 for (Size i = 0; i < instruments_.size(); i++) {
45 Real diff = instruments_[i]->calibrationError();
46 value += diff * diff * weights_[i];
47 }
48 return std::sqrt(value);
49 }
50
51 virtual Array values(const Array& params) const override {
52 model_->setParams(projection_.include(params));
53 Array values(instruments_.size());
54 for (Size i = 0; i < instruments_.size(); i++) {
55 values[i] = instruments_[i]->calibrationError() * std::sqrt(weights_[i]);
56 }
57 return values;
58 }
59
60 virtual Real finiteDifferenceEpsilon() const override { return 1e-6; }
61
62private:
63 shared_ptr<LinkableCalibratedModel> model_;
64 const vector<shared_ptr<CalibrationHelper> >& instruments_;
65 vector<Real> weights_;
66 const Projection projection_;
67};
68
69void LinkableCalibratedModel::calibrate(const vector<ext::shared_ptr<BlackCalibrationHelper> >& instruments,
70 OptimizationMethod& method, const EndCriteria& endCriteria,
71 const Constraint& additionalConstraint, const vector<Real>& weights,
72 const vector<bool>& fixParameters) {
73 vector<QuantLib::ext::shared_ptr<CalibrationHelper> > tmp(instruments.size());
74 for (Size i = 0; i < instruments.size(); ++i)
75 tmp[i] = ext::static_pointer_cast<CalibrationHelper>(instruments[i]);
76 calibrate(tmp, method, endCriteria, additionalConstraint, weights, fixParameters);
77}
78
79void LinkableCalibratedModel::calibrate(const vector<shared_ptr<CalibrationHelper> >& instruments,
80 OptimizationMethod& method, const EndCriteria& endCriteria,
81 const Constraint& additionalConstraint, const vector<Real>& weights,
82 const vector<bool>& fixParameters) {
83
84 QL_REQUIRE(weights.empty() || weights.size() == instruments.size(), "mismatch between number of instruments ("
85 << instruments.size() << ") and weights("
86 << weights.size() << ")");
87
88 Constraint c;
89 if (additionalConstraint.empty())
90 c = *constraint_;
91 else
92 c = CompositeConstraint(*constraint_, additionalConstraint);
93 vector<Real> w = weights.empty() ? vector<Real>(instruments.size(), 1.0) : weights;
94
95 Array prms = params();
96 vector<bool> all(prms.size(), false);
97 Projection proj(prms, fixParameters.size() > 0 ? fixParameters : all);
98 CalibrationFunction f(this, instruments, w, proj);
99 ProjectedConstraint pc(c, proj);
100 Problem prob(f, pc, proj.project(prms));
101 endCriteria_ = method.minimize(prob, endCriteria);
102 Array result(prob.currentValue());
103 setParams(proj.include(result));
104 problemValues_ = prob.values(result);
105
106 notifyObservers();
107}
108
109Real LinkableCalibratedModel::value(const Array& params,
110 const vector<QuantLib::ext::shared_ptr<BlackCalibrationHelper> >& instruments) {
111 vector<ext::shared_ptr<CalibrationHelper> > tmp(instruments.size());
112 for (Size i = 0; i < instruments.size(); ++i)
113 tmp[i] = ext::static_pointer_cast<CalibrationHelper>(instruments[i]);
114 return value(params, tmp);
115}
116
117Real LinkableCalibratedModel::value(const Array& params, const vector<shared_ptr<CalibrationHelper> >& instruments) {
118 vector<Real> w = vector<Real>(instruments.size(), 1.0);
119 Projection p(params);
120 CalibrationFunction f(this, instruments, w, p);
121 return f.value(params);
122}
123
125 Size size = 0, i;
126 for (i = 0; i < arguments_.size(); i++)
127 size += arguments_[i]->size();
128 Array params(size);
129 Size k = 0;
130 for (i = 0; i < arguments_.size(); i++) {
131 for (Size j = 0; j < arguments_[i]->size(); j++, k++) {
132 params[k] = arguments_[i]->params()[j];
133 }
134 }
135 return params;
136}
137
138void LinkableCalibratedModel::setParams(const Array& params) {
139 Array::const_iterator p = params.begin();
140 for (Size i = 0; i < arguments_.size(); ++i) {
141 for (Size j = 0; j < arguments_[i]->size(); ++j, ++p) {
142 QL_REQUIRE(p != params.end(), "parameter array too small");
143 arguments_[i]->setParam(j, *p);
144 }
145 }
146 QL_REQUIRE(p == params.end(), "parameter array too big!");
148 notifyObservers();
149}
150
151void LinkableCalibratedModel::setParam(Size idx, const Real value) {
152 int tmp = static_cast<int>(idx);
153 for (Size i = 0; i < arguments_.size(); ++i) {
154 for (Size j = 0; j < arguments_[i]->size(); ++j) {
155 if (tmp-- == 0)
156 arguments_[i]->setParam(j, value);
157 }
158 }
160 notifyObservers();
161}
162
163} // namespace QuantExt
Calibrated model class with linkable parameters.
Array params() const
Returns array of arguments on which calibration is done.
EndCriteria::Type endCriteria() const
Returns end criteria result.
virtual void setParam(Size idx, const Real value)
virtual void calibrate(const std::vector< QuantLib::ext::shared_ptr< CalibrationHelper > > &, OptimizationMethod &method, const EndCriteria &endCriteria, const Constraint &constraint=Constraint(), const std::vector< Real > &weights=std::vector< Real >(), const std::vector< bool > &fixParameters=std::vector< bool >())
Calibrate to a set of market instruments (usually caps/swaptions)
std::vector< QuantLib::ext::shared_ptr< Parameter > > arguments_
QuantLib::ext::shared_ptr< Constraint > constraint_
Real value(const Array &params, const std::vector< QuantLib::ext::shared_ptr< CalibrationHelper > > &)
virtual void setParams(const Array &params)
calibrated model class with linkable parameters
Swap::arguments * arguments_