This example evaluates a forward-rate agreement.
00001
00002
00020
00021
00022
00023
00024
00025 #define BOOST_LIB_DIAGNOSTIC
00026 # include <ql/quantlib.hpp>
00027 #undef BOOST_LIB_DIAGNOSTIC
00028
00029 #ifdef BOOST_MSVC
00030
00031
00032
00033
00034
00035
00036
00037
00038 #endif
00039
00040 #include <boost/timer.hpp>
00041 #include <iostream>
00042
00043 #define LENGTH(a) (sizeof(a)/sizeof(a[0]))
00044
00045 using namespace std;
00046 using namespace QuantLib;
00047
00048 #if defined(QL_ENABLE_SESSIONS)
00049 namespace QuantLib {
00050
00051 Integer sessionId() { return 0; }
00052
00053 }
00054 #endif
00055
00056 int main(int, char* []) {
00057
00058 try {
00059 QL_IO_INIT
00060
00061 boost::timer timer;
00062 std::cout << std::endl;
00063
00064
00065
00066
00067
00068 Handle<YieldTermStructure> euriborTermStructure;
00069 boost::shared_ptr<Xibor> euribor3m(
00070 new Euribor3M(euriborTermStructure));
00071
00072 Date todaysDate = Date(23, May, 2006);
00073 Settings::instance().evaluationDate() = todaysDate;
00074
00075 Calendar calendar = euribor3m->calendar();
00076 Integer fixingDays = euribor3m->settlementDays();
00077 Date settlementDate = calendar.advance(todaysDate, fixingDays, Days);
00078
00079 std::cout << "Today: " << todaysDate.weekday()
00080 << ", " << todaysDate << std::endl;
00081
00082 std::cout << "Settlement date: " << settlementDate.weekday()
00083 << ", " << settlementDate << std::endl;
00084
00085
00086
00087 Rate threeMonthFraQuote[10];
00088
00089 threeMonthFraQuote[1]=0.030;
00090 threeMonthFraQuote[2]=0.031;
00091 threeMonthFraQuote[3]=0.032;
00092 threeMonthFraQuote[6]=0.033;
00093 threeMonthFraQuote[9]=0.034;
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 boost::shared_ptr<SimpleQuote> fra1x4Rate(
00106 new SimpleQuote(threeMonthFraQuote[1]));
00107 boost::shared_ptr<SimpleQuote> fra2x5Rate(
00108 new SimpleQuote(threeMonthFraQuote[2]));
00109 boost::shared_ptr<SimpleQuote> fra3x6Rate(
00110 new SimpleQuote(threeMonthFraQuote[3]));
00111 boost::shared_ptr<SimpleQuote> fra6x9Rate(
00112 new SimpleQuote(threeMonthFraQuote[6]));
00113 boost::shared_ptr<SimpleQuote> fra9x12Rate(
00114 new SimpleQuote(threeMonthFraQuote[9]));
00115
00116 Handle<Quote> h1x4; h1x4.linkTo(fra1x4Rate);
00117 Handle<Quote> h2x5; h2x5.linkTo(fra2x5Rate);
00118 Handle<Quote> h3x6; h3x6.linkTo(fra3x6Rate);
00119 Handle<Quote> h6x9; h6x9.linkTo(fra6x9Rate);
00120 Handle<Quote> h9x12; h9x12.linkTo(fra9x12Rate);
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 DayCounter fraDayCounter = euribor3m->dayCounter();
00132 BusinessDayConvention convention = euribor3m->businessDayConvention();
00133
00134 boost::shared_ptr<RateHelper> fra1x4(
00135 new FraRateHelper(h1x4, 1, 4,
00136 fixingDays, calendar, convention,
00137 fraDayCounter));
00138
00139 boost::shared_ptr<RateHelper> fra2x5(
00140 new FraRateHelper(h2x5, 2, 5,
00141 fixingDays, calendar, convention,
00142 fraDayCounter));
00143
00144 boost::shared_ptr<RateHelper> fra3x6(
00145 new FraRateHelper(h3x6, 3, 6,
00146 fixingDays, calendar, convention,
00147 fraDayCounter));
00148
00149 boost::shared_ptr<RateHelper> fra6x9(
00150 new FraRateHelper(h6x9, 6, 9,
00151 fixingDays, calendar, convention,
00152 fraDayCounter));
00153
00154 boost::shared_ptr<RateHelper> fra9x12(
00155 new FraRateHelper(h9x12, 9, 12,
00156 fixingDays, calendar, convention,
00157 fraDayCounter));
00158
00159
00160
00161
00162
00163
00164
00165
00166 DayCounter termStructureDayCounter =
00167 ActualActual(ActualActual::ISDA);
00168
00169 double tolerance = 1.0e-15;
00170
00171
00172 std::vector<boost::shared_ptr<RateHelper> > fraInstruments;
00173
00174 fraInstruments.push_back(fra1x4);
00175 fraInstruments.push_back(fra2x5);
00176 fraInstruments.push_back(fra3x6);
00177 fraInstruments.push_back(fra6x9);
00178 fraInstruments.push_back(fra9x12);
00179
00180 boost::shared_ptr<YieldTermStructure> fraTermStructure(new
00181 PiecewiseFlatForward(settlementDate, fraInstruments,
00182 termStructureDayCounter, tolerance));
00183
00184
00185
00186
00187 Handle<YieldTermStructure> discountingTermStructure;
00188 discountingTermStructure.linkTo(fraTermStructure);
00189
00190
00191
00192
00193
00194
00195 Calendar fraCalendar = euribor3m->calendar();
00196 BusinessDayConvention fraBusinessDayConvention =
00197 euribor3m->businessDayConvention();
00198 Position::Type fraFwdType = Position::Long;
00199 Real fraNotional = 100.0;
00200 const Integer FraTermMonths = 3;
00201 Integer monthsToStart[] = { 1, 2, 3, 6, 9 };
00202
00203 euriborTermStructure.linkTo(fraTermStructure);
00204
00205 cout << endl;
00206 cout << "Test FRA construction, NPV calculation, and FRA purchase"
00207 << endl
00208 << endl;
00209
00210 Size i;
00211 for (i=0; i<LENGTH(monthsToStart); i++) {
00212
00213 Date fraValueDate = fraCalendar.advance(
00214 settlementDate,monthsToStart[i],Months,
00215 fraBusinessDayConvention);
00216
00217 Date fraMaturityDate = fraCalendar.advance(
00218 fraValueDate,FraTermMonths,Months,
00219 fraBusinessDayConvention);
00220
00221 Rate fraStrikeRate = threeMonthFraQuote[monthsToStart[i]];
00222
00223 ForwardRateAgreement myFRA(fraValueDate, fraMaturityDate,
00224 fraFwdType,fraStrikeRate,
00225 fraNotional, euribor3m,
00226 discountingTermStructure);
00227
00228 cout << "3m Term FRA, Months to Start: "
00229 << monthsToStart[i]
00230 << endl;
00231 cout << "strike FRA rate: "
00232 << io::rate(fraStrikeRate)
00233 << endl;
00234 cout << "FRA 3m forward rate: "
00235 << myFRA.forwardRate()
00236 << endl;
00237 cout << "FRA market quote: "
00238 << io::rate(threeMonthFraQuote[monthsToStart[i]])
00239 << endl;
00240 cout << "FRA spot value: "
00241 << myFRA.spotValue()
00242 << endl;
00243 cout << "FRA forward value: "
00244 << myFRA.forwardValue()
00245 << endl;
00246 cout << "FRA implied Yield: "
00247 << myFRA.impliedYield(myFRA.spotValue(),
00248 myFRA.forwardValue(),
00249 settlementDate,
00250 Simple,
00251 fraDayCounter)
00252 << endl;
00253 cout << "market Zero Rate: "
00254 << discountingTermStructure->zeroRate(fraMaturityDate,
00255 fraDayCounter,
00256 Simple)
00257 << endl;
00258 cout << "FRA NPV [should be zero]: "
00259 << myFRA.NPV()
00260 << endl
00261 << endl;
00262
00263 }
00264
00265
00266
00267
00268 cout << endl << endl;
00269 cout << "Now take a 100 basis-point upward shift in FRA quotes "
00270 << "and examine NPV"
00271 << endl
00272 << endl;
00273
00274 const Real BpsShift = 0.01;
00275
00276 threeMonthFraQuote[1]=0.030+BpsShift;
00277 threeMonthFraQuote[2]=0.031+BpsShift;
00278 threeMonthFraQuote[3]=0.032+BpsShift;
00279 threeMonthFraQuote[6]=0.033+BpsShift;
00280 threeMonthFraQuote[9]=0.034+BpsShift;
00281
00282 fra1x4Rate->setValue(threeMonthFraQuote[1]);
00283 fra2x5Rate->setValue(threeMonthFraQuote[2]);
00284 fra3x6Rate->setValue(threeMonthFraQuote[3]);
00285 fra6x9Rate->setValue(threeMonthFraQuote[6]);
00286 fra9x12Rate->setValue(threeMonthFraQuote[9]);
00287
00288
00289 for (i=0; i<LENGTH(monthsToStart); i++) {
00290
00291 Date fraValueDate = fraCalendar.advance(
00292 settlementDate,monthsToStart[i],Months,
00293 fraBusinessDayConvention);
00294
00295 Date fraMaturityDate = fraCalendar.advance(
00296 fraValueDate,FraTermMonths,Months,
00297 fraBusinessDayConvention);
00298
00299 Rate fraStrikeRate =
00300 threeMonthFraQuote[monthsToStart[i]] - BpsShift;
00301
00302 ForwardRateAgreement myFRA(fraValueDate, fraMaturityDate,
00303 fraFwdType, fraStrikeRate,
00304 fraNotional, euribor3m,
00305 discountingTermStructure);
00306
00307 cout << "3m Term FRA, 100 notional, Months to Start = "
00308 << monthsToStart[i]
00309 << endl;
00310 cout << "strike FRA rate: "
00311 << io::rate(fraStrikeRate)
00312 << endl;
00313 cout << "FRA 3m forward rate: "
00314 << myFRA.forwardRate()
00315 << endl;
00316 cout << "FRA market quote: "
00317 << io::rate(threeMonthFraQuote[monthsToStart[i]])
00318 << endl;
00319 cout << "FRA spot value: "
00320 << myFRA.spotValue()
00321 << endl;
00322 cout << "FRA forward value: "
00323 << myFRA.forwardValue()
00324 << endl;
00325 cout << "FRA implied Yield: "
00326 << myFRA.impliedYield(myFRA.spotValue(),
00327 myFRA.forwardValue(),
00328 settlementDate,
00329 Simple,
00330 fraDayCounter)
00331 << endl;
00332 cout << "market Zero Rate: "
00333 << discountingTermStructure->zeroRate(fraMaturityDate,
00334 fraDayCounter,
00335 Simple)
00336 << endl;
00337 cout << "FRA NPV [should be positive]: "
00338 << myFRA.NPV()
00339 << endl
00340 << endl;
00341 }
00342
00343 Real seconds = timer.elapsed();
00344 Integer hours = int(seconds/3600);
00345 seconds -= hours * 3600;
00346 Integer minutes = int(seconds/60);
00347 seconds -= minutes * 60;
00348 cout << " \nRun completed in ";
00349 if (hours > 0)
00350 cout << hours << " h ";
00351 if (hours > 0 || minutes > 0)
00352 cout << minutes << " m ";
00353 cout << fixed << setprecision(0)
00354 << seconds << " s\n" << endl;
00355
00356 return 0;
00357
00358 } catch (exception& e) {
00359 cout << e.what() << endl;
00360 return 1;
00361 } catch (...) {
00362 cout << "unknown error" << endl;
00363 return 1;
00364 }
00365 }
00366