1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3 /*
4 Copyright (C) 2014 Peter Caspers
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18 */
19
20 #include <ql/experimental/volatility/sviinterpolatedsmilesection.hpp>
21 #include <ql/settings.hpp>
22 #include <ql/quotes/simplequote.hpp>
23
24 namespace QuantLib {
25
SviInterpolatedSmileSection(const Date & optionDate,const Handle<Quote> & forward,const std::vector<Rate> & strikes,bool hasFloatingStrikes,const Handle<Quote> & atmVolatility,const std::vector<Handle<Quote>> & volHandles,Real a,Real b,Real sigma,Real rho,Real m,bool isAFixed,bool isBFixed,bool isSigmaFixed,bool isRhoFixed,bool isMFixed,bool vegaWeighted,const ext::shared_ptr<EndCriteria> & endCriteria,const ext::shared_ptr<OptimizationMethod> & method,const DayCounter & dc)26 SviInterpolatedSmileSection::SviInterpolatedSmileSection(
27 const Date &optionDate, const Handle<Quote> &forward,
28 const std::vector<Rate> &strikes, bool hasFloatingStrikes,
29 const Handle<Quote> &atmVolatility,
30 const std::vector<Handle<Quote> > &volHandles, Real a, Real b, Real sigma,
31 Real rho, Real m, bool isAFixed, bool isBFixed, bool isSigmaFixed,
32 bool isRhoFixed, bool isMFixed, bool vegaWeighted,
33 const ext::shared_ptr<EndCriteria> &endCriteria,
34 const ext::shared_ptr<OptimizationMethod> &method, const DayCounter &dc)
35 : SmileSection(optionDate, dc), forward_(forward),
36 atmVolatility_(atmVolatility), volHandles_(volHandles), strikes_(strikes),
37 actualStrikes_(strikes), hasFloatingStrikes_(hasFloatingStrikes),
38 vols_(volHandles.size()), a_(a), b_(b), sigma_(sigma), rho_(rho), m_(m),
39 isAFixed_(isAFixed), isBFixed_(isBFixed), isSigmaFixed_(isSigmaFixed),
40 isRhoFixed_(isRhoFixed), isMFixed_(isMFixed), vegaWeighted_(vegaWeighted),
41 endCriteria_(endCriteria), method_(method) {
42
43 LazyObject::registerWith(forward_);
44 LazyObject::registerWith(atmVolatility_);
45 for (Size i = 0; i < volHandles_.size(); ++i)
46 LazyObject::registerWith(volHandles_[i]);
47 }
48
SviInterpolatedSmileSection(const Date & optionDate,const Rate & forward,const std::vector<Rate> & strikes,bool hasFloatingStrikes,const Volatility & atmVolatility,const std::vector<Volatility> & volHandles,Real a,Real b,Real sigma,Real rho,Real m,bool isAFixed,bool isBFixed,bool isSigmaFixed,bool isRhoFixed,bool isMFixed,bool vegaWeighted,const ext::shared_ptr<EndCriteria> & endCriteria,const ext::shared_ptr<OptimizationMethod> & method,const DayCounter & dc)49 SviInterpolatedSmileSection::SviInterpolatedSmileSection(
50 const Date &optionDate, const Rate &forward,
51 const std::vector<Rate> &strikes, bool hasFloatingStrikes,
52 const Volatility &atmVolatility, const std::vector<Volatility> &volHandles,
53 Real a, Real b, Real sigma, Real rho, Real m, bool isAFixed, bool isBFixed,
54 bool isSigmaFixed, bool isRhoFixed, bool isMFixed, bool vegaWeighted,
55 const ext::shared_ptr<EndCriteria> &endCriteria,
56 const ext::shared_ptr<OptimizationMethod> &method, const DayCounter &dc)
57 : SmileSection(optionDate, dc),
58 forward_(
59 Handle<Quote>(ext::shared_ptr<Quote>(new SimpleQuote(forward)))),
60 atmVolatility_(Handle<Quote>(
61 ext::shared_ptr<Quote>(new SimpleQuote(atmVolatility)))),
62 volHandles_(volHandles.size()), strikes_(strikes),
63 actualStrikes_(strikes), hasFloatingStrikes_(hasFloatingStrikes),
64 vols_(volHandles.size()), a_(a), b_(b), sigma_(sigma), rho_(rho), m_(m),
65 isAFixed_(isAFixed), isBFixed_(isBFixed), isSigmaFixed_(isSigmaFixed),
66 isRhoFixed_(isRhoFixed), isMFixed_(isMFixed), vegaWeighted_(vegaWeighted),
67 endCriteria_(endCriteria), method_(method) {
68
69 for (Size i = 0; i < volHandles_.size(); ++i)
70 volHandles_[i] = Handle<Quote>(
71 ext::shared_ptr<Quote>(new SimpleQuote(volHandles[i])));
72 }
73
createInterpolation() const74 void SviInterpolatedSmileSection::createInterpolation() const {
75 ext::shared_ptr<SviInterpolation> tmp(new SviInterpolation(
76 actualStrikes_.begin(), actualStrikes_.end(), vols_.begin(),
77 exerciseTime(), forwardValue_, a_, b_, sigma_, rho_, m_, isAFixed_,
78 isBFixed_, isSigmaFixed_, isRhoFixed_, isMFixed_, vegaWeighted_,
79 endCriteria_, method_));
80 swap(tmp, sviInterpolation_);
81 }
82
performCalculations() const83 void SviInterpolatedSmileSection::performCalculations() const {
84 forwardValue_ = forward_->value();
85 vols_.clear();
86 actualStrikes_.clear();
87 // we populate the volatilities, skipping the invalid ones
88 for (Size i = 0; i < volHandles_.size(); ++i) {
89 if (volHandles_[i]->isValid()) {
90 if (hasFloatingStrikes_) {
91 actualStrikes_.push_back(forwardValue_ + strikes_[i]);
92 vols_.push_back(atmVolatility_->value() +
93 volHandles_[i]->value());
94 } else {
95 actualStrikes_.push_back(strikes_[i]);
96 vols_.push_back(volHandles_[i]->value());
97 }
98 }
99 }
100 // we are recreating the sabrinterpolation object unconditionnaly to
101 // avoid iterator invalidation
102 createInterpolation();
103 sviInterpolation_->update();
104 }
105
varianceImpl(Real strike) const106 Real SviInterpolatedSmileSection::varianceImpl(Real strike) const {
107 calculate();
108 Real v = (*sviInterpolation_)(strike, true);
109 return v * v * exerciseTime();
110 }
111 }
112