QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
hestonslvmcmodel.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2015 Johannes Göttker-Schnetmann
5 Copyright (C) 2015 Klaus Spanderen
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
24#include <ql/math/functional.hpp>
25#include <ql/termstructures/volatility/equityfx/fixedlocalvolsurface.hpp>
26#include <ql/models/equity/hestonslvmcmodel.hpp>
27#include <ql/processes/hestonslvprocess.hpp>
28
29#pragma push_macro("BOOST_DISABLE_ASSERTS")
30#ifndef BOOST_DISABLE_ASSERTS
31#define BOOST_DISABLE_ASSERTS
32#endif
33#include <boost/multi_array.hpp>
34#pragma pop_macro("BOOST_DISABLE_ASSERTS")
35
36#include <utility>
37
38namespace QuantLib {
41 Handle<HestonModel> hestonModel,
42 ext::shared_ptr<BrownianGeneratorFactory> brownianGeneratorFactory,
43 const Date& endDate,
44 Size timeStepsPerYear,
45 Size nBins,
46 Size calibrationPaths,
47 const std::vector<Date>& mandatoryDates,
48 const Real mixingFactor)
49 : localVol_(std::move(localVol)), hestonModel_(std::move(hestonModel)),
50 brownianGeneratorFactory_(std::move(brownianGeneratorFactory)), endDate_(endDate),
51 nBins_(nBins), calibrationPaths_(calibrationPaths), mixingFactor_(mixingFactor) {
52
55
56 const DayCounter dc = hestonModel_->process()->riskFreeRate()->dayCounter();
57 const Date refDate = hestonModel_->process()->riskFreeRate()->referenceDate();
58
59 std::vector<Time> gridTimes;
60 gridTimes.reserve(mandatoryDates.size()+1);
61 for (auto mandatoryDate : mandatoryDates) {
62 gridTimes.push_back(dc.yearFraction(refDate, mandatoryDate));
63 }
64 gridTimes.push_back(dc.yearFraction(refDate, endDate));
65
66 timeGrid_ = ext::make_shared<TimeGrid>(gridTimes.begin(), gridTimes.end(),
67 std::max(Size(2), Size(gridTimes.back()*timeStepsPerYear)));
68 }
69
70 ext::shared_ptr<HestonProcess> HestonSLVMCModel::hestonProcess() const {
71 return hestonModel_->process();
72 }
73
74 ext::shared_ptr<LocalVolTermStructure> HestonSLVMCModel::localVol() const {
75 return localVol_.currentLink();
76 }
77
78 ext::shared_ptr<LocalVolTermStructure>
80 calculate();
81
82 return leverageFunction_;
83 }
84
86 const ext::shared_ptr<HestonProcess> hestonProcess
87 = hestonModel_->process();
88 const ext::shared_ptr<Quote> spot
89 = hestonProcess->s0().currentLink();
90
91 const Real v0 = hestonProcess->v0();
92 const DayCounter dc = hestonProcess->riskFreeRate()->dayCounter();
93 const Date referenceDate = hestonProcess->riskFreeRate()->referenceDate();
94
95 const Volatility lv0
96 = localVol_->localVol(0.0, spot->value())/std::sqrt(v0);
97
98 const ext::shared_ptr<Matrix> L(new Matrix(nBins_, timeGrid_->size()));
99
100 std::vector<ext::shared_ptr<std::vector<Real> > >
101 vStrikes(timeGrid_->size());
102 for (Size i=0; i < timeGrid_->size(); ++i) {
103 const Integer u = nBins_/2;
104 const Real dx = spot->value()*std::sqrt(QL_EPSILON);
105
106 vStrikes[i] = ext::make_shared<std::vector<Real> >(nBins_);
107
108 for (Integer j=0; j < Integer(nBins_); ++j)
109 vStrikes[i]->at(j) = spot->value() + (j - u)*dx;
110 }
111
112 std::fill(L->column_begin(0),L->column_end(0), lv0);
113
114 leverageFunction_ = ext::make_shared<FixedLocalVolSurface>(
115 referenceDate,
116 std::vector<Time>(timeGrid_->begin(), timeGrid_->end()),
117 vStrikes, L, dc);
118
119 const ext::shared_ptr<HestonSLVProcess> slvProcess
120 = ext::make_shared<HestonSLVProcess>(hestonProcess, leverageFunction_, mixingFactor_);
121
122 std::vector<std::pair<Real, Real> > pairs(
123 calibrationPaths_, std::make_pair(spot->value(), v0));
124
125 const Size k = calibrationPaths_ / nBins_;
126 const Size m = calibrationPaths_ % nBins_;
127
128 const Size timeSteps = timeGrid_->size()-1;
129
130 typedef boost::multi_array<Real, 3> path_type;
131 path_type paths(boost::extents[calibrationPaths_][timeSteps][2]);
132
133 const ext::shared_ptr<BrownianGenerator> brownianGenerator =
134 brownianGeneratorFactory_->create(2, timeSteps);
135
136 for (Size i=0; i < calibrationPaths_; ++i) {
137 brownianGenerator->nextPath();
138 std::vector<Real> tmp(2);
139 for (Size j=0; j < timeSteps; ++j) {
140 brownianGenerator->nextStep(tmp);
141 paths[i][j][0] = tmp[0];
142 paths[i][j][1] = tmp[1];
143 }
144 }
145
146 for (Size n=1; n < timeGrid_->size(); ++n) {
147 const Time t = timeGrid_->at(n-1);
148 const Time dt = timeGrid_->dt(n-1);
149
150 Array x0(2), dw(2);
151
152 for (Size i=0; i < calibrationPaths_; ++i) {
153 x0[0] = pairs[i].first;
154 x0[1] = pairs[i].second;
155
156 dw[0] = paths[i][n-1][0];
157 dw[1] = paths[i][n-1][1];
158
159 x0 = slvProcess->evolve(t, x0, dt, dw);
160
161 pairs[i].first = x0[0];
162 pairs[i].second = x0[1];
163 }
164
165 std::sort(pairs.begin(), pairs.end());
166
167 Size s = 0U, e = 0U;
168 for (Size i=0; i < nBins_; ++i) {
169 const Size inc = k + static_cast<unsigned long>(i < m);
170 e = s + inc;
171
172 Real sum=0.0;
173 for (Size j=s; j < e; ++j) {
174 sum+=pairs[j].second;
175 }
176 sum/=inc;
177
178 vStrikes[n]->at(i) = 0.5*(pairs[e-1].first + pairs[s].first);
179 (*L)[i][n] = std::sqrt(squared(localVol_->localVol(t, vStrikes[n]->at(i), true))/sum);
180
181 s = e;
182 }
183
184 leverageFunction_->setInterpolation<Linear>();
185 }
186 }
187}
1-D array used in linear algebra.
Definition: array.hpp:52
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
Shared handle to an observable.
Definition: handle.hpp:41
ext::shared_ptr< LocalVolTermStructure > leverageFunction() const
ext::shared_ptr< TimeGrid > timeGrid_
void performCalculations() const override
const ext::shared_ptr< BrownianGeneratorFactory > brownianGeneratorFactory_
const Handle< LocalVolTermStructure > localVol_
const Handle< HestonModel > hestonModel_
HestonSLVMCModel(Handle< LocalVolTermStructure > localVol, Handle< HestonModel > hestonModel, ext::shared_ptr< BrownianGeneratorFactory > brownianGeneratorFactory, const Date &endDate, Size timeStepsPerYear=365, Size nBins=201, Size calibrationPaths=(1<< 15), const std::vector< Date > &mandatoryDates=std::vector< Date >(), Real mixingFactor=1.0)
ext::shared_ptr< HestonProcess > hestonProcess() const
ext::shared_ptr< FixedLocalVolSurface > leverageFunction_
ext::shared_ptr< LocalVolTermStructure > localVol() const
virtual void calculate() const
Definition: lazyobject.hpp:253
Linear-interpolation factory and traits
Matrix used in linear algebra.
Definition: matrix.hpp:41
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
#define QL_EPSILON
Definition: qldefines.hpp:178
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Volatility
volatility
Definition: types.hpp:78
QL_INTEGER Integer
integer number
Definition: types.hpp:35
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
T squared(T x)
Definition: functional.hpp:37
STL namespace.