/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /*! Copyright (C) 2004 Ferdinando Ametrano Copyright (C) 2002, 2003 Sadruddin Rejeb Copyright (C) 2005, 2006, 2007 StatPro Italia srl 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. */ #define BOOST_LIB_DIAGNOSTIC # include #undef BOOST_LIB_DIAGNOSTIC #ifdef BOOST_MSVC /* Uncomment the following lines to unmask floating-point exceptions. Warning: unpredictable results can arise... See http://www.wilmott.com/messageview.cfm?catid=10&threadid=9481 Is there anyone with a definitive word about this? */ // #include // namespace { unsigned int u = _controlfp(_EM_INEXACT, _MCW_EM); } #endif #include #include #include using namespace QuantLib; #if defined(QL_ENABLE_SESSIONS) namespace QuantLib { Integer sessionId() { return 0; } } #endif //Number of swaptions to be calibrated to... Size numRows = 5; Size numCols = 5; Integer swapLenghts[] = { 1, 2, 3, 4, 5}; Volatility swaptionVols[] = { 0.1490, 0.1340, 0.1228, 0.1189, 0.1148, 0.1290, 0.1201, 0.1146, 0.1108, 0.1040, 0.1149, 0.1112, 0.1070, 0.1010, 0.0957, 0.1047, 0.1021, 0.0980, 0.0951, 0.1270, 0.1000, 0.0950, 0.0900, 0.1230, 0.1160}; void calibrateModel( const boost::shared_ptr& model, const std::vector >& helpers) { LevenbergMarquardt om; model->calibrate(helpers, om, EndCriteria(400, 100, 1.0e-8, 1.0e-8, 1.0e-8)); // Output the implied Black volatilities for (Size i=0; imodelValue(); Volatility implied = helpers[i]->impliedVolatility(npv, 1e-4, 1000, 0.05, 0.50); Volatility diff = implied - swaptionVols[k]; std::cout << i+1 << "x" << swapLenghts[j] << std::setprecision(5) << std::noshowpos << ": model " << std::setw(7) << io::volatility(implied) << ", market " << std::setw(7) << io::volatility(swaptionVols[k]) << " (" << std::setw(7) << std::showpos << io::volatility(diff) << std::noshowpos << ")\n"; } } int main(int, char* []) { try { boost::timer timer; std::cout << std::endl; Date todaysDate(15, February, 2002); Calendar calendar = TARGET(); Date settlementDate(19, February, 2002); Settings::instance().evaluationDate() = todaysDate; // flat yield term structure impling 1x5 swap at 5% boost::shared_ptr flatRate(new SimpleQuote(0.04875825)); Handle rhTermStructure( boost::shared_ptr( new FlatForward(settlementDate, Handle(flatRate), Actual365Fixed()))); // Define the ATM/OTM/ITM swaps Frequency fixedLegFrequency = Annual; BusinessDayConvention fixedLegConvention = Unadjusted; BusinessDayConvention floatingLegConvention = ModifiedFollowing; DayCounter fixedLegDayCounter = Thirty360(Thirty360::European); Frequency floatingLegFrequency = Semiannual; VanillaSwap::Type type = VanillaSwap::Payer; Rate dummyFixedRate = 0.03; boost::shared_ptr indexSixMonths(new Euribor6M(rhTermStructure)); Date startDate = calendar.advance(settlementDate,1,Years, floatingLegConvention); Date maturity = calendar.advance(startDate,5,Years, floatingLegConvention); Schedule fixedSchedule(startDate,maturity,Period(fixedLegFrequency), calendar,fixedLegConvention,fixedLegConvention, false,false); Schedule floatSchedule(startDate,maturity,Period(floatingLegFrequency), calendar,floatingLegConvention,floatingLegConvention, false,false); boost::shared_ptr swap(new VanillaSwap( type, 1000.0, fixedSchedule, dummyFixedRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths->dayCounter(), rhTermStructure)); Rate fixedATMRate = swap->fairRate(); Rate fixedOTMRate = fixedATMRate * 1.2; Rate fixedITMRate = fixedATMRate * 0.8; boost::shared_ptr atmSwap(new VanillaSwap( type, 1000.0, fixedSchedule, fixedATMRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths->dayCounter(), rhTermStructure)); boost::shared_ptr otmSwap(new VanillaSwap( type, 1000.0, fixedSchedule, fixedOTMRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths->dayCounter(), rhTermStructure)); boost::shared_ptr itmSwap(new VanillaSwap( type, 1000.0, fixedSchedule, fixedITMRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths->dayCounter(), rhTermStructure)); // defining the swaptions to be used in model calibration std::vector swaptionMaturities; swaptionMaturities.push_back(Period(1, Years)); swaptionMaturities.push_back(Period(2, Years)); swaptionMaturities.push_back(Period(3, Years)); swaptionMaturities.push_back(Period(4, Years)); swaptionMaturities.push_back(Period(5, Years)); std::vector > swaptions; // List of times that have to be included in the timegrid std::list