swaptionvolcube1.cpp

来自「有很多的函数库」· C++ 代码 · 共 783 行 · 第 1/3 页

CPP
783
字号
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2006 Giorgio Facchinetti

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

#include <ql/termstructures/volatilities/swaptionvolcube1.hpp>
#include <ql/math/interpolations/sabrinterpolation.hpp>
#include <ql/termstructures/volatilities/swaptionvolmatrix.hpp>
#include <ql/math/interpolations/flatextrapolation2d.hpp>

#ifndef SWAPTIONVOLCUBE_VEGAWEIGHTED_TOL
	#define SWAPTIONVOLCUBE_VEGAWEIGHTED_TOL 15.0e-4
#endif
#ifndef SWAPTIONVOLCUBE_TOL
	#define SWAPTIONVOLCUBE_TOL 100.0e-4
#endif

namespace QuantLib {

    //=======================================================================//
    //                        SwaptionVolCube1                   //
    //=======================================================================//

    SwaptionVolCube1::SwaptionVolCube1(
                const Handle<SwaptionVolatilityStructure>& atmVolStructure,
                const std::vector<Period>& optionTenors,
                const std::vector<Period>& swapTenors,
                const std::vector<Spread>& strikeSpreads,
                const std::vector<std::vector<Handle<Quote> > >& volSpreads,
                const boost::shared_ptr<SwapIndex>& swapIndexBase,
                bool vegaWeightedSmileFit,
                const std::vector<std::vector<Handle<Quote> > >& parametersGuess,
                const std::vector<bool>& isParameterFixed,
                bool isAtmCalibrated,
                const boost::shared_ptr<EndCriteria>& endCriteria,
                Real maxErrorTolerance)
    : SwaptionVolatilityCube(atmVolStructure, optionTenors, swapTenors,
                             strikeSpreads, volSpreads, swapIndexBase,
                             vegaWeightedSmileFit),
      parametersGuessQuotes_(parametersGuess),
      isParameterFixed_(isParameterFixed), isAtmCalibrated_(isAtmCalibrated),
      endCriteria_(endCriteria)
    {
        if(maxErrorTolerance != Null<Rate>()){
            maxErrorTolerance_ = maxErrorTolerance;
        } else{
        	maxErrorTolerance_ = SWAPTIONVOLCUBE_VEGAWEIGHTED_TOL;
			if (vegaWeightedSmileFit_) maxErrorTolerance_ = SWAPTIONVOLCUBE_TOL;
        }
       registerWithParametersGuess();
    }

    void SwaptionVolCube1::registerWithParametersGuess()
    {
        for (Size i=0; i<4; i++)
            for (Size j=0; j<nOptionTenors_; j++)
                for (Size k=0; k<nSwapTenors_; k++)
                    registerWith(parametersGuessQuotes_[j+k*nOptionTenors_][i]);
    }

    void SwaptionVolCube1::performCalculations() const{
        //! set parametersGuess_ by parametersGuessQuotes_
        parametersGuess_ = Cube(optionDates_, swapTenors_,
                                optionTimes_, swapLengths_, 4);
        Size i;
        for (i=0; i<4; i++)
            for (Size j=0; j<nOptionTenors_ ; j++)
                for (Size k=0; k<nSwapTenors_; k++) {
                    parametersGuess_.setElement(i, j, k, 
                        parametersGuessQuotes_[j+k*nOptionTenors_][i]->value());
                }
        parametersGuess_.updateInterpolators();

        //! set marketVolCube_ by volSpreads_ quotes
        marketVolCube_ = Cube(optionDates_, swapTenors_,
                              optionTimes_, swapLengths_, nStrikes_);
        Rate atmForward;
        Volatility vol;
        for (Size i=0; i<nStrikes_; i++)
            for (Size j=0; j<nOptionTenors_; j++)
                for (Size k=0; k<nSwapTenors_; k++) {
                    atmForward = atmStrike(optionDates_[j], swapTenors_[k]);
                    vol = volSpreads_[j*nSwapTenors_+k][i]->value() +
                        atmVol_->volatility(optionDates_[j], swapTenors_[k],
                                                               atmForward);
                    marketVolCube_.setElement(i, j, k, vol);
                }
        marketVolCube_.updateInterpolators();

        sparseParameters_ = sabrCalibration(marketVolCube_);
        //parametersGuess_ = sparseParameters_;
        sparseParameters_.updateInterpolators();
        //parametersGuess_.updateInterpolators();
        volCubeAtmCalibrated_= marketVolCube_;

        if(isAtmCalibrated_){
            fillVolatilityCube();
            denseParameters_ = sabrCalibration(volCubeAtmCalibrated_);
            denseParameters_.updateInterpolators();
        }
    }

    SwaptionVolCube1::Cube
    SwaptionVolCube1::sabrCalibration(const Cube& marketVolCube) const {

        const std::vector<Time>& optionTimes = marketVolCube.optionTimes();
        const std::vector<Time>& swapLengths = marketVolCube.swapLengths();
        const std::vector<Date>& optionDates = marketVolCube.optionDates();
        const std::vector<Period>& swapTenors = marketVolCube.swapTenors();
        Matrix alphas(optionTimes.size(), swapLengths.size(),0.);
        Matrix betas(alphas);
        Matrix nus(alphas);
        Matrix rhos(alphas);
        Matrix forwards(alphas);
        Matrix errors(alphas);
        Matrix maxErrors(alphas);
        Matrix endCriteria(alphas);

        const std::vector<Matrix>& tmpMarketVolCube = marketVolCube.points();

        std::vector<Real> strikes(strikeSpreads_.size());
        std::vector<Real> volatilities(strikeSpreads_.size());

        for (Size j=0; j<optionTimes.size(); j++) {
            for (Size k=0; k<swapLengths.size(); k++) {
                Rate atmForward = atmStrike(optionDates[j], swapTenors[k]);
                for (Size i=0; i<nStrikes_; i++){
                    strikes[i] = atmForward+strikeSpreads_[i];
                    volatilities[i] = tmpMarketVolCube[i][j][k];
                }

                const std::vector<Real>& guess = parametersGuess_.operator()(
                    optionTimes[j], swapLengths[k]);
                
                const boost::shared_ptr<SABRInterpolation> sabrInterpolation =
                    boost::shared_ptr<SABRInterpolation>(new
                        SABRInterpolation(strikes.begin(), strikes.end(),
                                          volatilities.begin(),
                                          optionTimes[j], atmForward,
                                          guess[0], guess[1],
                                          guess[2], guess[3],
                                          isParameterFixed_[0],
                                          isParameterFixed_[1],
                                          isParameterFixed_[2],
                                          isParameterFixed_[3],
                                          vegaWeightedSmileFit_,
                                          endCriteria_,
                                          boost::shared_ptr<OptimizationMethod>()));
                sabrInterpolation->update();

                Real interpolationError =
                    sabrInterpolation->interpolationError();
                alphas     [j][k]=sabrInterpolation->alpha();
                betas      [j][k]=sabrInterpolation->beta();
                nus        [j][k]=sabrInterpolation->nu();
                rhos       [j][k]=sabrInterpolation->rho();
                forwards   [j][k]=atmForward;
                errors     [j][k]=interpolationError;
                maxErrors  [j][k]=sabrInterpolation->interpolationMaxError();
                endCriteria[j][k]=sabrInterpolation->endCriteria();
				
                QL_ENSURE(endCriteria[j][k]!=EndCriteria::MaxIterations,
                          "global swaptions calibration failed: "
                          "MaxIterations reached: " << "\n" <<
                          "option maturity = " << optionDates[j] << ", \n" <<
                          "swap tenor = " << swapTenors[k] << ", \n" <<
					      "alpha = " <<  alphas[j][k]<< ", \n" <<
					      "beta = " <<  betas[j][k] << ", \n" <<
					      "nu = " <<  nus[j][k]   << ", \n" <<
					      "rho = " <<  rhos[j][k]  << ", \n" <<
					      "error = " <<  io::rate(errors[j][k])
                          );

                QL_ENSURE(maxErrors[j][k]<maxErrorTolerance_,
                          "global swaptions calibration failed: "
                          "maxErrorTolerance not reached: " << "\n" <<
                          "option maturity = " << optionDates[j] << ", \n" <<
                          "swap tenor = " << swapTenors[k] << "\n" <<
                          "max error = " << io::rate(maxErrors[j][k]) << "\n" <<
						  "error = " << io::rate(errors[j][k])  << "\n" <<
						  "alpha = " << alphas[j][k]<< "\n" <<
						  "beta = " << betas[j][k] << "\n" <<
						  "nu = " << nus[j][k]   << "\n" <<
						  "rho = " << rhos[j][k]
                          );
            }
        }
        Cube sabrParametersCube(optionDates, swapTenors,
                                optionTimes, swapLengths, 8);
        sabrParametersCube.setLayer(0, alphas);
        sabrParametersCube.setLayer(1, betas);
        sabrParametersCube.setLayer(2, nus);
        sabrParametersCube.setLayer(3, rhos);
        sabrParametersCube.setLayer(4, forwards);
        sabrParametersCube.setLayer(5, errors);
        sabrParametersCube.setLayer(6, maxErrors);
        sabrParametersCube.setLayer(7, endCriteria);

        return sabrParametersCube;

    }
    void SwaptionVolCube1::sabrCalibrationSection(
                                            const Cube& marketVolCube,
                                            Cube& parametersCube,
                                            const Period& swapTenor) const {

        const std::vector<Time>& optionTimes = marketVolCube.optionTimes();
        const std::vector<Time>& swapLengths = marketVolCube.swapLengths();
        const std::vector<Date>& optionDates = marketVolCube.optionDates();
        const std::vector<Period>& swapTenors = marketVolCube.swapTenors();

        Size k = std::find(swapTenors.begin(), swapTenors.end(),
                           swapTenor) - swapTenors.begin();
        QL_REQUIRE(k != swapTenors.size(), "swap tenor not found");

        std::vector<Real> calibrationResult(8,0.);
        const std::vector<Matrix>& tmpMarketVolCube = marketVolCube.points();

        std::vector<Real> strikes(strikeSpreads_.size());
        std::vector<Real> volatilities(strikeSpreads_.size());

        for (Size j=0; j<optionTimes.size(); j++) {
            Rate atmForward = atmStrike(optionDates[j], swapTenors[k]);
            for (Size i=0; i<nStrikes_; i++){
                strikes[i] = atmForward+strikeSpreads_[i];
                volatilities[i] = tmpMarketVolCube[i][j][k];
            }

            const std::vector<Real>& guess = parametersGuess_.operator()(
                optionTimes[j], swapLengths[k]);

            const boost::shared_ptr<SABRInterpolation> sabrInterpolation =
                boost::shared_ptr<SABRInterpolation>(new
                    SABRInterpolation(strikes.begin(), strikes.end(),
                                      volatilities.begin(),
                                      optionTimes[j], atmForward,
                                      guess[0], guess[1],
                                      guess[2], guess[3],
                                      isParameterFixed_[0],
                                      isParameterFixed_[1],
                                      isParameterFixed_[2],
                                      isParameterFixed_[3],
                                      vegaWeightedSmileFit_,
                                      endCriteria_,
                                      boost::shared_ptr<OptimizationMethod>()));

            sabrInterpolation->update();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?