This example prices a bermudan swaption using different models calibrated to market swaptions. The calibration examples include Hull and White's using both an analytic formula as well as numerically, and Black and Karasinski's model. Using these three calibrations, Bermudan swaptions are priced for at-the-money, out-of-the-money and in-the-money volatilities.
#include <ql/qldefines.hpp>
#ifdef BOOST_MSVC
# include <ql/auto_link.hpp>
#endif
#include <ql/instruments/swaption.hpp>
#include <ql/pricingengines/swap/discountingswapengine.hpp>
#include <ql/pricingengines/swaption/treeswaptionengine.hpp>
#include <ql/pricingengines/swaption/jamshidianswaptionengine.hpp>
#include <ql/pricingengines/swaption/g2swaptionengine.hpp>
#include <ql/pricingengines/swaption/fdhullwhiteswaptionengine.hpp>
#include <ql/pricingengines/swaption/fdg2swaptionengine.hpp>
#include <ql/models/shortrate/calibrationhelpers/swaptionhelper.hpp>
#include <ql/models/shortrate/onefactormodels/blackkarasinski.hpp>
#include <ql/math/optimization/levenbergmarquardt.hpp>
#include <ql/indexes/ibor/euribor.hpp>
#include <ql/cashflows/coupon.hpp>
#include <ql/quotes/simplequote.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/time/calendars/target.hpp>
#include <ql/time/daycounters/thirty360.hpp>
#include <ql/utilities/dataformatters.hpp>
#include <iostream>
#include <iomanip>
#if defined(QL_ENABLE_SESSIONS)
ThreadKey sessionId() { return 0; }
}
#endif
1, 2, 3, 4, 5};
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 ext::shared_ptr<ShortRateModel>& model,
const std::vector<ext::shared_ptr<BlackCalibrationHelper> >& swaptions) {
std::vector<ext::shared_ptr<CalibrationHelper> > helpers(swaptions.begin(), swaptions.end());
model->calibrate(helpers, om,
for (
Size i=0; i<numRows; i++) {
Real npv = swaptions[i]->modelValue();
Volatility implied = swaptions[i]->impliedVolatility(npv, 1e-4,
1000, 0.05, 0.50);
std::cout << i+1 << "x" << swapLengths[j]
<< std::setprecision(5) << std::noshowpos
<< ", market " << std::setw(7)
<< " (" << std::setw(7) << std::showpos
}
}
int main(int, char* []) {
try {
std::cout << std::endl;
Date todaysDate(15, February, 2002);
Date settlementDate(19, February, 2002);
ext::shared_ptr<Quote> flatRate(
new SimpleQuote(0.04875825));
ext::make_shared<FlatForward>(
VanillaSwap::Type type = VanillaSwap::Payer;
Rate dummyFixedRate = 0.03;
ext::shared_ptr<IborIndex> indexSixMonths(new
Date startDate = calendar.
advance(settlementDate,1,Years,
floatingLegConvention);
floatingLegConvention);
calendar,fixedLegConvention,fixedLegConvention,
Schedule floatSchedule(startDate,maturity,
Period(floatingLegFrequency),
calendar,floatingLegConvention,floatingLegConvention,
type, 1000.0,
fixedSchedule, dummyFixedRate, fixedLegDayCounter,
floatSchedule, indexSixMonths, 0.0,
indexSixMonths->dayCounter()));
swap->setPricingEngine(ext::shared_ptr<PricingEngine>(
new DiscountingSwapEngine(rhTermStructure)));
Rate fixedATMRate = swap->fairRate();
Rate fixedOTMRate = fixedATMRate * 1.2;
Rate fixedITMRate = fixedATMRate * 0.8;
type, 1000.0,
fixedSchedule, fixedATMRate, fixedLegDayCounter,
floatSchedule, indexSixMonths, 0.0,
indexSixMonths->dayCounter()));
type, 1000.0,
fixedSchedule, fixedOTMRate, fixedLegDayCounter,
floatSchedule, indexSixMonths, 0.0,
indexSixMonths->dayCounter()));
type, 1000.0,
fixedSchedule, fixedITMRate, fixedLegDayCounter,
floatSchedule, indexSixMonths, 0.0,
indexSixMonths->dayCounter()));
std::vector<Period> 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<ext::shared_ptr<BlackCalibrationHelper> > swaptions;
std::list<Time> times;
for (i=0; i<numRows; i++) {
ext::shared_ptr<Quote> vol(
new SimpleQuote(swaptionVols[k]));
swaptions.push_back(ext::shared_ptr<BlackCalibrationHelper>(new
Period(swapLengths[j], Years),
indexSixMonths,
indexSixMonths->tenor(),
indexSixMonths->dayCounter(),
indexSixMonths->dayCounter(),
rhTermStructure)));
swaptions.back()->addTimesTo(times);
}
TimeGrid grid(times.begin(), times.end(), 30);
ext::shared_ptr<G2> modelG2(
new G2(rhTermStructure));
ext::shared_ptr<HullWhite> modelHW(
new HullWhite(rhTermStructure));
ext::shared_ptr<HullWhite> modelHW2(
new HullWhite(rhTermStructure));
ext::shared_ptr<BlackKarasinski> modelBK(
std::cout << "G2 (analytic formulae) calibration" << std::endl;
for (i=0; i<swaptions.size(); i++)
swaptions[i]->setPricingEngine(ext::shared_ptr<PricingEngine>(
calibrateModel(modelG2, swaptions);
std::cout << "calibrated to:\n"
<< "a = " << modelG2->params()[0] << ", "
<< "sigma = " << modelG2->params()[1] << "\n"
<< "b = " << modelG2->params()[2] << ", "
<< "eta = " << modelG2->params()[3] << "\n"
<< "rho = " << modelG2->params()[4]
<< std::endl << std::endl;
std::cout << "Hull-White (analytic formulae) calibration" << std::endl;
for (i=0; i<swaptions.size(); i++)
swaptions[i]->setPricingEngine(ext::shared_ptr<PricingEngine>(
calibrateModel(modelHW, swaptions);
std::cout << "calibrated to:\n"
<< "a = " << modelHW->params()[0] << ", "
<< "sigma = " << modelHW->params()[1]
<< std::endl << std::endl;
std::cout << "Hull-White (numerical) calibration" << std::endl;
for (i=0; i<swaptions.size(); i++)
swaptions[i]->setPricingEngine(ext::shared_ptr<PricingEngine>(
calibrateModel(modelHW2, swaptions);
std::cout << "calibrated to:\n"
<< "a = " << modelHW2->params()[0] << ", "
<< "sigma = " << modelHW2->params()[1]
<< std::endl << std::endl;
std::cout << "Black-Karasinski (numerical) calibration" << std::endl;
for (i=0; i<swaptions.size(); i++)
swaptions[i]->setPricingEngine(ext::shared_ptr<PricingEngine>(
calibrateModel(modelBK, swaptions);
std::cout << "calibrated to:\n"
<< "a = " << modelBK->params()[0] << ", "
<< "sigma = " << modelBK->params()[1]
<< std::endl << std::endl;
std::cout << "Payer bermudan swaption "
<<
"struck at " <<
io::rate(fixedATMRate)
<< " (ATM)" << std::endl;
std::vector<Date> bermudanDates;
const std::vector<ext::shared_ptr<CashFlow> >& leg =
swap->fixedLeg();
for (i=0; i<leg.size(); i++) {
ext::shared_ptr<Coupon> coupon =
ext::dynamic_pointer_cast<Coupon>(leg[i]);
bermudanDates.push_back(coupon->accrualStartDate());
}
ext::shared_ptr<Exercise> bermudanExercise(
Swaption bermudanSwaption(atmSwap, bermudanExercise);
bermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "G2 (tree): " << bermudanSwaption.NPV() << std::endl;
bermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdG2SwaptionEngine(modelG2)));
std::cout << "G2 (fdm) : " << bermudanSwaption.NPV() << std::endl;
bermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "HW (tree): " << bermudanSwaption.NPV() << std::endl;
bermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdHullWhiteSwaptionEngine(modelHW)));
std::cout << "HW (fdm) : " << bermudanSwaption.NPV() << std::endl;
bermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "HW (num, tree): " << bermudanSwaption.NPV() << std::endl;
bermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdHullWhiteSwaptionEngine(modelHW2)));
std::cout << "HW (num, fdm) : " << bermudanSwaption.NPV() << std::endl;
bermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "BK: " << bermudanSwaption.NPV() << std::endl;
std::cout << "Payer bermudan swaption "
<<
"struck at " <<
io::rate(fixedOTMRate)
<< " (OTM)" << std::endl;
Swaption otmBermudanSwaption(otmSwap,bermudanExercise);
otmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "G2 (tree): " << otmBermudanSwaption.NPV()
<< std::endl;
otmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdG2SwaptionEngine(modelG2)));
std::cout << "G2 (fdm) : " << otmBermudanSwaption.NPV()
<< std::endl;
otmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "HW (tree): " << otmBermudanSwaption.NPV()
<< std::endl;
otmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdHullWhiteSwaptionEngine(modelHW)));
std::cout << "HW (fdm) : " << otmBermudanSwaption.NPV()
<< std::endl;
otmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "HW (num, tree): " << otmBermudanSwaption.NPV()
<< std::endl;
otmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdHullWhiteSwaptionEngine(modelHW2)));
std::cout << "HW (num, fdm): " << otmBermudanSwaption.NPV()
<< std::endl;
otmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "BK: " << otmBermudanSwaption.NPV()
<< std::endl;
std::cout << "Payer bermudan swaption "
<<
"struck at " <<
io::rate(fixedITMRate)
<< " (ITM)" << std::endl;
Swaption itmBermudanSwaption(itmSwap,bermudanExercise);
itmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "G2 (tree): " << itmBermudanSwaption.NPV()
<< std::endl;
itmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdG2SwaptionEngine(modelG2)));
std::cout << "G2 (fdm) : " << itmBermudanSwaption.NPV()
<< std::endl;
itmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "HW (tree): " << itmBermudanSwaption.NPV()
<< std::endl;
itmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdHullWhiteSwaptionEngine(modelHW)));
std::cout << "HW (fdm) : " << itmBermudanSwaption.NPV()
<< std::endl;
itmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "HW (num, tree): " << itmBermudanSwaption.NPV()
<< std::endl;
itmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
new FdHullWhiteSwaptionEngine(modelHW2)));
std::cout << "HW (num, fdm) : " << itmBermudanSwaption.NPV()
<< std::endl;
itmBermudanSwaption.setPricingEngine(ext::shared_ptr<PricingEngine>(
std::cout << "BK: " << itmBermudanSwaption.NPV()
<< std::endl;
return 0;
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
} catch (...) {
std::cerr << "unknown error" << std::endl;
return 1;
}
}