Interest Rate Swap

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Interest Rate Swap

Marcello Gambacorta COFIRI SIM
Hi QuantLibers,
I'm trying to price an Interest Rate Swap with QuantLib but I didn't
understand how to set up the termstructure in C++.
Suppose I want to price the following Swap against Euribor 6m:
SWAP DETAILS:
today:                              1-10-2001
effective date:                  3-10-2001
fixedlegtenor:                   annual
first fixed payment:          3-10-2002
floatinglegtenor                semiannual
first floating payment:      3-4-2002
maturity date:                   3-10-2006
Notional:                          100,000

TERM STRUCTURE DETAILS:
 Deposit(Act/360)
1w  3.82%
1m 3.72%
3m 3.63%
6m 3.53%
9m 3.48%
1y  3.45%
 Swap(30/360)
 2y  3.7125%
 3y  3.98%
 5y  4.43%
 10y 5.165%
 15y 5.5175%

Any idea in C++?
Thanks in advance
Marcello







Marcello Gambacorta
Customer Desk Cofiri SIM S.p.A.
Tel: 0039-(0)64733571
Fax:0039-(0)64884322
mail: [hidden email]





Reply | Threaded
Open this post in threaded view
|

Re: Interest Rate Swap

Ferdinando M. Ametrano-2
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

Swap.zip (8K) Download Attachment