Posted by
Ferdinando M. Ametrano-2 on
Oct 02, 2001; 4:45am
URL: http://quantlib.414.s1.nabble.com/Interest-Rate-Swap-tp1766p1767.html
Hi all
>I'm trying to price an Interest Rate Swap with QuantLib but I didn't
>understand how to set up the termstructure in C++.
Yeah, it needs better documentation/example. Also the swap needs an
extended interface to be priced as floating leg spread: on the to-do list.
I will remember to improve the documentation before the next release. In
the meantime I've added a term structure setup + swap pricing example to
the CVS.
I attach here the zipped folder: the example works under Win32 with Borland
and MS VC++, it should also work under Linux with gcc.
Here's the code:
#include "ql/quantlib.hpp"
using namespace QuantLib;
using Calendars::TARGET;
using DayCounters::ActualActual;
using DayCounters::Actual360;
using DayCounters::Thirty360;
using Indexes::Euribor;
using Instruments::SimpleSwap;
using TermStructures::PiecewiseFlatForward;
using TermStructures::FlatForward;
using TermStructures::RateHelper;
using TermStructures::DepositRateHelper;
using TermStructures::SwapRateHelper;
int main(int argc, char* argv[])
{
try {
Handle<Calendar> calendar(new TARGET);
int settlementDays = 2;
Handle<DayCounter> depositDayCounter(new Actual360);
// Handles are the QuantLib way to ensure that the RateHelper pointers
// always point to a valid DepositRateHelper
// without having to worry about deallocation
Handle<RateHelper> d1w(new DepositRateHelper(0.0382, settlementDays,
1, Days, calendar, ModifiedFollowing, depositDayCounter));
Handle<RateHelper> d1m(new DepositRateHelper(0.0372, settlementDays,
1, Months, calendar, ModifiedFollowing, depositDayCounter));
Handle<RateHelper> d3m(new DepositRateHelper(0.0363, settlementDays,
3, Months, calendar, ModifiedFollowing, depositDayCounter));
Handle<RateHelper> d6m(new DepositRateHelper(0.0353, settlementDays,
6, Months, calendar, ModifiedFollowing, depositDayCounter));
Handle<RateHelper> d9m(new DepositRateHelper(0.0348, settlementDays,
9, Months, calendar, ModifiedFollowing, depositDayCounter));
Handle<RateHelper> d1y(new DepositRateHelper(0.0345, settlementDays,
1, Years, calendar, ModifiedFollowing, depositDayCounter));
int swFixedLegFrequency = 1;
bool swFixedLegIsAdjusted = false;
Handle<DayCounter> swFixedLegDayCounter(new
Thirty360(Thirty360::European));
int swFloatingLegFrequency = 2;
Handle<RateHelper> s2y(new SwapRateHelper(0.037125, settlementDays,
2, calendar, ModifiedFollowing, swFixedLegFrequency,
swFixedLegIsAdjusted, swFixedLegDayCounter,
swFloatingLegFrequency));
Handle<RateHelper> s3y(new SwapRateHelper(0.0398, settlementDays,
3, calendar, ModifiedFollowing, swFixedLegFrequency,
swFixedLegIsAdjusted, swFixedLegDayCounter,
swFloatingLegFrequency));
Handle<RateHelper> s5y(new SwapRateHelper(0.0443, settlementDays,
5, calendar, ModifiedFollowing, swFixedLegFrequency,
swFixedLegIsAdjusted, swFixedLegDayCounter,
swFloatingLegFrequency));
Handle<RateHelper> s10y(new SwapRateHelper(0.05165, settlementDays,
10, calendar, ModifiedFollowing, swFixedLegFrequency,
swFixedLegIsAdjusted, swFixedLegDayCounter,
swFloatingLegFrequency));
Handle<RateHelper> s15y(new SwapRateHelper(0.055175, settlementDays,
15, calendar, ModifiedFollowing, swFixedLegFrequency,
swFixedLegIsAdjusted, swFixedLegDayCounter,
swFloatingLegFrequency));
std::vector<Handle<RateHelper> > instruments;
instruments.push_back(d1w);
instruments.push_back(d1m);
instruments.push_back(d3m);
instruments.push_back(d6m);
instruments.push_back(d9m);
instruments.push_back(d1y);
instruments.push_back(s2y);
instruments.push_back(s3y);
instruments.push_back(s5y);
instruments.push_back(s10y);
instruments.push_back(s15y);
Currency currency = EUR;
// Any DayCounter would be fine.
// ActualActual::ISDA ensures that 30 years is 30.0
Handle<DayCounter> termStructureDayCounter(
new ActualActual(ActualActual::ISDA));
Date todaysDate(1, October, 2001);
// bootstrap the curve
Handle<TermStructure> myTermStructure(new
PiecewiseFlatForward(currency, termStructureDayCounter,
todaysDate, calendar, settlementDays, instruments));
// let's start with the swap pricing
// this will be use for discounting and for
// forward rate forecasting
// Of course, you're not forced to use the same curve
RelinkableHandle<TermStructure > rhTermStructure;
// spot start
Date startDate = myTermStructure->settlementDate();
int lenghtInYears = 5;
std::vector<double> nominals;
nominals.push_back(100000);
// fixed leg
int fixedLegFrequency = 1;
bool fixedLegIsAdjusted = false;
RollingConvention roll = ModifiedFollowing;
Handle<DayCounter> fixedLegDayCounter(new
Thirty360(Thirty360::European));
Rate fixedRate = 0.04; // dummy value
std::vector<double> couponRates;
couponRates.push_back(fixedRate);
// floating leg
int floatingLegFrequency = 2;
Handle<Index> euriborIndex(new Euribor(6, Months,
rhTermStructure));
std::vector<double> spreads;
spreads.push_back(0.0);
bool payFixedRate = true;
SimpleSwap mySwap(payFixedRate, startDate, lenghtInYears, Years,
calendar, roll, nominals, fixedLegFrequency, couponRates,
fixedLegIsAdjusted, fixedLegDayCounter, floatingLegFrequency,
euriborIndex, spreads, rhTermStructure);
rhTermStructure.linkTo(myTermStructure);
Rate fairFixedRate = fixedRate-mySwap.NPV()/mySwap.BPS();
std::cout << DoubleFormatter::toString(fairFixedRate*100,4) <<
std::endl;
// let's price the same swap on a different term structure
// e.g. Flat Forward at 5.0%
Handle<TermStructure> newTermStructure(new
FlatForward(currency, termStructureDayCounter, todaysDate,
calendar, settlementDays, 0.05));
rhTermStructure.linkTo(newTermStructure);
fairFixedRate = fixedRate-mySwap.NPV()/mySwap.BPS();
std::cout << DoubleFormatter::toString(fairFixedRate*100,4) <<
std::endl;
return 0;
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
return 1;
} catch (...) {
std::cout << "unknown error" << std::endl;
return 1;
}
}
Feel free to suggest improvements and/or to comments about the design and
this example.
ciao -- Nando