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