This examples prices a number of callable bonds and compares the results to known good data. It uses the experimental CallableBond class.
#ifdef BOOST_MSVC
#endif
#include <ql/quantlib.hpp>
#include <vector>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <boost/timer.hpp>
#if defined(QL_ENABLE_SESSIONS)
}
#endif
boost::shared_ptr<YieldTermStructure>
flatRate(
const Date& today,
const boost::shared_ptr<Quote>& forward,
return boost::shared_ptr<YieldTermStructure>(
dc,
compounding,
frequency));
}
boost::shared_ptr<YieldTermStructure>
flatRate(
const Date& today,
return flatRate(today,
dc,
compounding,
frequency);
}
int main(int, char* [])
{
try {
boost::timer timer;
Settings::instance().evaluationDate() = today;
cout << endl;
cout << "Pricing a callable fixed rate bond using" << endl;
cout << "Hull White model w/ reversion parameter = 0.03" << endl;
cout << "BAC4.65 09/15/12 ISIN: US06060WBJ36" << endl;
cout << "roughly five year tenor, ";
cout << "quarterly coupon and call dates" << endl;
cout << "reference date is : " << today << endl << endl;
Rate bbCurveRate = 0.055;
bbIR.rate(),
bbIR.dayCounter(),
bbIR.compounding(),
bbIR.frequency()));
CallabilitySchedule callSchedule;
Size numberOfCallDates = 24;
Date callDate =
Date(15,September,2006);
for (
Size i=0; i< numberOfCallDates; i++) {
Callability::Price::Clean);
callSchedule.push_back(
boost::shared_ptr<Callability>(
Callability::Call,
callDate )));
callDate = nullCalendar.
advance(callDate, 3, Months);
}
Date maturity =
Date(15,September,2012);
accrualConvention, accrualConvention,
DateGeneration::Backward, false);
Size maxIterations = 1000;
Real reversionParameter = .03;
boost::shared_ptr<ShortRateModel> hw0(
new HullWhite(termStructure,reversionParameter,sigma));
boost::shared_ptr<PricingEngine> engine0(
vector<Rate>(1, coupon),
bondDayCounter, paymentConvention,
redemption, issue, callSchedule);
callableBond.setPricingEngine(engine0);
cout << setprecision(2)
<< showpoint
<< fixed
<< "sigma/vol (%) = "
<< 100.*sigma
<< endl;
cout << "QuantLib price/yld (%) ";
cout << callableBond.cleanPrice() << " / "
<< 100. * callableBond.yield(bondDayCounter,
Compounded,
frequency,
accuracy,
maxIterations)
<< endl;
cout << "Bloomberg price/yld (%) ";
cout << "96.50 / 5.47"
<< endl
<< endl;
sigma = .01;
cout << "sigma/vol (%) = " << 100.*sigma << endl;
boost::shared_ptr<ShortRateModel> hw1(
new HullWhite(termStructure,reversionParameter,sigma));
boost::shared_ptr<PricingEngine> engine1(
callableBond.setPricingEngine(engine1);
cout << "QuantLib price/yld (%) ";
cout << callableBond.cleanPrice() << " / "
<< 100.* callableBond.yield(bondDayCounter,
Compounded,
frequency,
accuracy,
maxIterations)
<< endl;
cout << "Bloomberg price/yld (%) ";
cout << "95.68 / 5.66"
<< endl
<< endl;
sigma = .03;
boost::shared_ptr<ShortRateModel> hw2(
new HullWhite(termStructure, reversionParameter, sigma));
boost::shared_ptr<PricingEngine> engine2(
callableBond.setPricingEngine(engine2);
cout << "sigma/vol (%) = "
<< 100.*sigma
<< endl;
cout << "QuantLib price/yld (%) ";
cout << callableBond.cleanPrice() << " / "
<< 100. * callableBond.yield(bondDayCounter,
Compounded,
frequency,
accuracy,
maxIterations)
<< endl;
cout << "Bloomberg price/yld (%) ";
cout << "92.34 / 6.49"
<< endl
<< endl;
sigma = .06;
boost::shared_ptr<ShortRateModel> hw3(
new HullWhite(termStructure, reversionParameter, sigma));
boost::shared_ptr<PricingEngine> engine3(
callableBond.setPricingEngine(engine3);
cout << "sigma/vol (%) = "
<< 100.*sigma
<< endl;
cout << "QuantLib price/yld (%) ";
cout << callableBond.cleanPrice() << " / "
<< 100. * callableBond.yield(bondDayCounter,
Compounded,
frequency,
accuracy,
maxIterations)
<< endl;
cout << "Bloomberg price/yld (%) ";
cout << "87.16 / 7.83"
<< endl
<< endl;
sigma = .12;
boost::shared_ptr<ShortRateModel> hw4(
new HullWhite(termStructure, reversionParameter, sigma));
boost::shared_ptr<PricingEngine> engine4(
callableBond.setPricingEngine(engine4);
cout << "sigma/vol (%) = "
<< 100.*sigma
<< endl;
cout << "QuantLib price/yld (%) ";
cout << callableBond.cleanPrice() << " / "
<< 100.* callableBond.yield(bondDayCounter,
Compounded,
frequency,
accuracy,
maxIterations)
<< endl;
cout << "Bloomberg price/yld (%) ";
cout << "77.31 / 10.65"
<< endl
<< endl;
Real seconds = timer.elapsed();
seconds -= hours * 3600;
seconds -= minutes * 60;
cout << " \nRun completed in ";
if (hours > 0)
cout << hours << " h ";
if (hours > 0 || minutes > 0)
cout << minutes << " m ";
cout << fixed << setprecision(0)
<< seconds << " s\n" << endl;
return 0;
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
} catch (...) {
std::cerr << "unknown error" << std::endl;
return 1;
}
}