I'm a newbie to quantlib. Trying to build a 1-mo USD Libor forward curve from a swap curve. Here is a skeletal code. Can an expert in the list take a quick look and comment if I am doing things correctly. Without documentation, its been a little bit of trial and error to getting started with quantlib. Some of the code is boilerplate from some of the examples.
I'm trying to build a cublic spline interpolated forward curve and I want to output forwardrates for 1-mo Libor.
Any guidance would be greatly appreicated.
thanks
Kumar
/*********************
*** MARKET DATA ***
*********************/
Calendar calendar = QuantLib::TARGET();
// must be a business day
settlementDate = calendar.adjust(settlementDate);
// assume fixings for same date
Integer fixingDays = 0;
Natural curveSettlementDays = 0;
Date currentDate = calendar.advance(settlementDate, -fixingDays, Days);
// nothing to do with Date::todaysDate
Settings::instance().evaluationDate() = currentDate;
Period OneMonth(1, TimeUnit::Months);
std::cout << "Today: " << currentDate.weekday()
<< ", " << currentDate << std::endl;
std::cout << "Settlement date: " << settlementDate.weekday()
<< ", " << settlementDate << std::endl;
// deposit
rates
Rate d1mQuote = yc.month1.get()/100.0;
Rate d3mQuote = yc.month3.get()/100.0;
Rate d6mQuote = yc.month6.get()/100.0;
Rate d1yQuote = yc.year1.get()/100.0;
// swaps
Rate s2yQuote = yc.year2.get()/100.0;
Rate s3yQuote = yc.year3.get()/100.0;
Rate s4yQuote =yc.year4.get()/100.0;
Rate s5yQuote = yc.year5.get()/100.0;
Rate s7yrQuote = yc.year7.get()/100.0;
Rate s10yQuote = yc.year10.get()/100.0;
Rate s15yQuote = yc.year15.get()/100.0;
Rate s20yQuote = yc.year20.get()/100.0;
Rate s30yQuote = yc.year30.get()/100.0;
/********************
*** QUOTES
***
********************/
// SimpleQuote stores a value which can be manually changed;
// other Quote subclasses could read the value from a database
// or some kind of data feed.
// deposits
boost::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote));
boost::shared_ptr<Quote> d3mRate(new SimpleQuote(d3mQuote));
boost::shared_ptr<Quote> d6mRate(new SimpleQuote(d6mQuote));
boost::shared_ptr<Quote> d1yRate(new SimpleQuote(d1yQuote));
// swaps
boost::shared_ptr<Quote> s2yRate(new SimpleQuote(s2yQuote));
boost::shared_ptr<Quote> s3yRate(new SimpleQuote(s3yQuote));
boost::shared_ptr<Quote> s4yRate(new
SimpleQuote(s4yQuote));
boost::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote));
boost::shared_ptr<Quote> s7yRate(new SimpleQuote(s5yQuote));
boost::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote));
boost::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote));
boost::shared_ptr<Quote> s20yRate(new SimpleQuote(s20yQuote));
boost::shared_ptr<Quote> s30yRate(new SimpleQuote(s30yQuote));
/*********************
*** RATE HELPERS ***
*********************/
// RateHelpers are built from the above quotes together with
// other instrument dependant infos. Quotes are passed in
// relinkable handles which could be relinked to some
other
// data source later.
// deposits
DayCounter depositDayCounter = QuantLib::Actual360();
boost::shared_ptr<RateHelper> d1m(new DepositRateHelper(
Handle<Quote>(d1mRate),
1*Months, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter));
boost::shared_ptr<RateHelper> d3m(new DepositRateHelper(
Handle<Quote>(d3mRate),
3*Months, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter));
boost::shared_ptr<RateHelper> d6m(new
DepositRateHelper(
Handle<Quote>(d6mRate),
6*Months, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter));
boost::shared_ptr<RateHelper> d1y(new DepositRateHelper(
Handle<Quote>(d1yRate),
1*Years, fixingDays,
calendar, ModifiedFollowing,
true, depositDayCounter));
// setup swaps
Frequency swFixedLegFrequency = Annual;
BusinessDayConvention swFixedLegConvention = Unadjusted;
DayCounter swFixedLegDayCounter = Thirty360(Thirty360::European);
boost::shared_ptr<IborIndex> swFloatingLegIndex(new USDLibor(OneMonth));
boost::shared_ptr<RateHelper> s2y(new SwapRateHelper(
Handle<Quote>(s2yRate), 2*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s3y(new SwapRateHelper(
Handle<Quote>(s3yRate), 3*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s4y(new SwapRateHelper(
Handle<Quote>(s4yRate), 4*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s5y(new SwapRateHelper(
Handle<Quote>(s5yRate), 5*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s7y(new SwapRateHelper(
Handle<Quote>(s7yRate), 7*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention,
swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s10y(new SwapRateHelper(
Handle<Quote>(s10yRate), 10*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s15y(new SwapRateHelper(
Handle<Quote>(s15yRate), 15*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s20y(new SwapRateHelper(
Handle<Quote>(s20yRate), 20*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
boost::shared_ptr<RateHelper> s30y(new SwapRateHelper(
Handle<Quote>(s30yRate), 30*Years,
calendar, swFixedLegFrequency,
swFixedLegConvention, swFixedLegDayCounter,
swFloatingLegIndex));
/*********************
** CURVE BUILDING **
*********************/
// Any DayCounter would be fine.
// ActualActual::ISDA ensures that 30 years is 30.0
DayCounter termStructureDayCounter =
Actual360();
Real tolerance = 1.0e-10;
Size max = 5000;
// A depo-swap curve
std::vector<boost::shared_ptr<RateHelper> > depoSwapInstruments;
depoSwapInstruments.push_back(d1m);
depoSwapInstruments.push_back(d3m);
depoSwapInstruments.push_back(d6m);
depoSwapInstruments.push_back(d1y);
depoSwapInstruments.push_back(s2y);
depoSwapInstruments.push_back(s3y);
depoSwapInstruments.push_back(s4y);
depoSwapInstruments.push_back(s5y);
depoSwapInstruments.push_back(s7y);
depoSwapInstruments.push_back(s10y);
depoSwapInstruments.push_back(s15y);
depoSwapInstruments.push_back(s20y);
depoSwapInstruments.push_back(s30y);
Cubic interpolator(CubicInterpolation::Spline, true,
CubicInterpolation::SecondDerivative, 0.0,
CubicInterpolation::SecondDerivative, 0.0);
boost::shared_ptr<YieldTermStructure> depoSwapTermStructure (
new PiecewiseYieldCurve<ForwardRate,Cubic,IterativeBootStrap>(
settlementDate, depoSwapInstruments,
termStructureDayCounter,
std::vector<Handle<Quote> >(),
std::vector<Date>(),
tolerance, interpolator));
RelinkableHandle<YieldTermStructure> forecastingTermStructure;
forecastingTermStructure.linkTo(depoSwapTermStructure);
// Loop over period of term structure.
// do it for 360 months
int i;
int mos = 360;
std::vector<Rate> fwdRates(mos);
USDLibor libor1M(OneMonth);
Period indexTenor = libor1M.tenor();
DayCounter indexDayCounter = libor1M.dayCounter();
for (i=0; i<mos; i++) {
currentDate = calendar.advance(currentDate, OneMonth, Following);
// move the evaluationDate to currentDate
// and update ratehelpers dates...
//Settings::instance().evaluationDate() = currentDate;
fwdRates[i] = forecastingTermStructure->forwardRate(currentDate,indexTenor,indexDayCounter,Simple);
cout << "date: " << currentDate << ", fwdRate[" << i << "]: " << fwdRates[i] << endl;
}
the opportunity to enter the BlackBerry Developer Challenge. See full prize