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