/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2007 Marco Bianchetti Copyright (C) 2006, 2007 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 . The license is also available online at . 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. */ /*! \file cmsmarket.hpp \brief set of CMS quotes */ #ifndef quantlib_cms_market_h #define quantlib_cms_market_h #include #include #include #include #include #include namespace QuantLib { typedef Leg Leg; class CmsCouponPricer; //! set of CMS quotes class CmsMarket: public LazyObject{ public: CmsMarket( const std::vector& expiries, const std::vector< boost::shared_ptr >& swapIndices, const std::vector > >& bidAskSpreads, const std::vector< boost::shared_ptr >& pricers, const Handle& yieldTermStructure); //! \name LazyObject interface //@{ void update() { LazyObject::update();} //@} // call during calibration procedure void reprice(const Handle& volStructure, Real meanReversion); //inspectors ... const std::vector& swapTenors() const {return swapTenors_;} Matrix meanReversions(){return meanReversions_;}; Matrix impliedCmsSpreads(){return modelCmsSpreads_;}; Matrix spreadErrors(){return spreadErrors_;}; Matrix browse() const; //cms market calibration methods (they haven't Lazyness behaviour) Real weightedError(const Matrix& weights); Real weightedPriceError(const Matrix& weights); Real weightedForwardPriceError(const Matrix& weights); Disposable weightedErrors(const Matrix& weights); Disposable weightedPriceErrors(const Matrix& weights); Disposable weightedForwardPriceErrors(const Matrix& weights); private: void performCalculations() const; void registerWithMarketData(); void createForwardStartingCms(); void priceForwardStartingCms() const; void priceSpotFromForwardStartingCms() const; Real weightedMean(const Matrix& var, const Matrix& weights); Disposable weightedMeans(const Matrix& var, const Matrix& weights); std::vector expiries_; std::vector swapTenors_; Size nExercise_; Size nSwapTenors_; // market bid spreads mutable Matrix bids_; // market ask spreads mutable Matrix asks_; // market mid spreads mutable Matrix mids_; // Implied spreads to model prices mutable Matrix modelCmsSpreads_; // Differences between implied and mid spreads mutable Matrix spreadErrors_; // prices of constant maturity swaps with spread = 0 mutable Matrix prices_; // market prices of Cms Leg corrisponding to bid spreads mutable Matrix marketBidCmsLegValues_; // market prices of Cms Leg corrisponding to ask spreads mutable Matrix marketAskCmsLegValues_; // market prices of Cms Leg corrisponding to mid spreads mutable Matrix marketMidCmsLegValues_; // model prices of Cms Leg corrisponding to mid spreads mutable Matrix modelCmsLegValues_; // Differences between modelCmsLegValue and marketMidCmsLegValue_ mutable Matrix priceErrors_; mutable Matrix swapFloatingLegsPrices_,swapFloatingLegsBps_; // market prices of Forward Cms Leg corrisponding to bid spreads mutable Matrix marketBidForwardCmsLegValues_; // market prices of Forward Cms Leg corrisponding to ask spreads mutable Matrix marketAskForwardCmsLegValues_; // market prices of Forward Cms Leg corrisponding to mid spreads mutable Matrix marketMidForwardCmsLegValues_; // model prices of Forward Cms Leg corrisponding to mid spreads mutable Matrix modelForwardCmsLegValues_; // Differences between modelForwardCmsLegValues and marketMidCmsLegValues mutable Matrix forwardPriceErrors_; mutable Matrix meanReversions_; std::vector< boost::shared_ptr > pricers_; std::vector< boost::shared_ptr > swapIndices_; const std::vector > > bidAskSpreads_; std::vector< std::vector< boost::shared_ptr > > swaps_; std::vector< std::vector< boost::shared_ptr > > forwardSwaps_; Handle yieldTermStructure_; }; class CmsMarketCalibration{ public: enum CalibrationType {OnSpread, OnPrice, OnForwardCmsPrice }; CmsMarketCalibration( Handle& volCube, boost::shared_ptr& cmsMarket, const Matrix& weights, CalibrationType calibrationType); Handle volCube_; boost::shared_ptr cmsMarket_; Matrix weights_; CalibrationType calibrationType_; Matrix sparseSabrParameters_, denseSabrParameters_, browseCmsMarket_; Array compute(const boost::shared_ptr& endCriteria, const boost::shared_ptr& method, const Array& guess, bool isMeanReversionFixed); Real error(){return error_;} EndCriteria::Type endCriteria() { return endCriteria_; }; private: class ParametersConstraint : public Constraint { private: class Impl : public Constraint::Impl { Size nBeta_; public: Impl(Size nBeta) : Constraint::Impl(),nBeta_(nBeta){} bool test(const Array& params) const { QL_REQUIRE(params.size()==nBeta_+1,"params.size()!=nBeta_+1"); bool areBetasInConstraints = true; for(Size i=0;i=0.0 && params[i]<=1.0); return areBetasInConstraints // betas && params[nBeta_]>0.0 && params[nBeta_]<2.0; // mean reversion } }; public: ParametersConstraint(Size nBeta) : Constraint(boost::shared_ptr(new Impl(nBeta))) {} }; class ObjectiveFunction : public CostFunction { public: ObjectiveFunction(CmsMarketCalibration* smileAndCms) :smileAndCms_(smileAndCms), volCube_(smileAndCms->volCube_), cmsMarket_(smileAndCms->cmsMarket_), weights_(smileAndCms->weights_), calibrationType_(smileAndCms->calibrationType_){}; Real value(const Array& x) const; Disposable values(const Array& x) const; protected: Real switchErrorFunctionOnCalibrationType() const; Disposable switchErrorsFunctionOnCalibrationType() const; CmsMarketCalibration* smileAndCms_; Handle volCube_; boost::shared_ptr cmsMarket_; Matrix weights_; CalibrationType calibrationType_; private: virtual void updateVolatilityCubeAndCmsMarket(const Array& x) const; }; class ParametersConstraintWithFixedMeanReversion : public Constraint { private: class Impl : public Constraint::Impl { Size nBeta_; public: Impl(Size nBeta) : Constraint::Impl(),nBeta_(nBeta){} bool test(const Array& params) const { QL_REQUIRE(params.size()==nBeta_,"params.size()!=nBeta_"); bool areBetasInConstraints = true; for(Size i=0;i=0.0 && params[i]<=1.0); return areBetasInConstraints; } }; public: ParametersConstraintWithFixedMeanReversion(Size nBeta) : Constraint(boost::shared_ptr(new Impl(nBeta))) {} }; class ObjectiveFunctionWithFixedMeanReversion : public ObjectiveFunction { public: ObjectiveFunctionWithFixedMeanReversion(CmsMarketCalibration* smileAndCms, Real fixedMeanReversion) :ObjectiveFunction(smileAndCms), fixedMeanReversion_(fixedMeanReversion){}; private: virtual void updateVolatilityCubeAndCmsMarket(const Array& x) const; Real fixedMeanReversion_; }; Real error_; EndCriteria::Type endCriteria_; }; } #endif