swapvaluation.cpp
This is an example of using the QuantLib Term Structure for pricing a simple swap.
00001 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 00002 00021 /* This example shows how to set up a Term Structure and then price a simple 00022 swap. 00023 */ 00024 00025 // the only header you need to use QuantLib 00026 #include <ql/quantlib.hpp> 00027 #include <boost/timer.hpp> 00028 #include <iostream> 00029 #include <iomanip> 00030 00031 using namespace QuantLib; 00032 00033 #if defined(QL_ENABLE_SESSIONS) 00034 namespace QuantLib { 00035 00036 Integer sessionId() { return 0; } 00037 00038 } 00039 #endif 00040 00041 00042 int main(int, char* []) 00043 { 00044 try { 00045 QL_IO_INIT 00046 00047 boost::timer timer; 00048 std::cout << std::endl; 00049 00050 /********************* 00051 *** MARKET DATA *** 00052 *********************/ 00053 00054 Calendar calendar = TARGET(); 00055 // uncommenting the following line generates an error 00056 // calendar = Tokyo(); 00057 Date settlementDate(22, September, 2004); 00058 // must be a business day 00059 settlementDate = calendar.adjust(settlementDate); 00060 00061 Integer fixingDays = 2; 00062 Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days); 00063 // nothing to do with Date::todaysDate 00064 Settings::instance().evaluationDate() = todaysDate; 00065 00066 00067 todaysDate = Settings::instance().evaluationDate(); 00068 std::cout << "Today: " << todaysDate.weekday() 00069 << ", " << todaysDate << std::endl; 00070 00071 std::cout << "Settlement date: " << settlementDate.weekday() 00072 << ", " << settlementDate << std::endl; 00073 00074 // deposits 00075 Rate d1wQuote=0.0382; 00076 Rate d1mQuote=0.0372; 00077 Rate d3mQuote=0.0363; 00078 Rate d6mQuote=0.0353; 00079 Rate d9mQuote=0.0348; 00080 Rate d1yQuote=0.0345; 00081 // FRAs 00082 Rate fra3x6Quote=0.037125; 00083 Rate fra6x9Quote=0.037125; 00084 Rate fra6x12Quote=0.037125; 00085 // futures 00086 Real fut1Quote=96.2875; 00087 Real fut2Quote=96.7875; 00088 Real fut3Quote=96.9875; 00089 Real fut4Quote=96.6875; 00090 Real fut5Quote=96.4875; 00091 Real fut6Quote=96.3875; 00092 Real fut7Quote=96.2875; 00093 Real fut8Quote=96.0875; 00094 // swaps 00095 Rate s2yQuote=0.037125; 00096 Rate s3yQuote=0.0398; 00097 Rate s5yQuote=0.0443; 00098 Rate s10yQuote=0.05165; 00099 Rate s15yQuote=0.055175; 00100 00101 00102 /******************** 00103 *** QUOTES *** 00104 ********************/ 00105 00106 // SimpleQuote stores a value which can be manually changed; 00107 // other Quote subclasses could read the value from a database 00108 // or some kind of data feed. 00109 00110 // deposits 00111 boost::shared_ptr<Quote> d1wRate(new SimpleQuote(d1wQuote)); 00112 boost::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote)); 00113 boost::shared_ptr<Quote> d3mRate(new SimpleQuote(d3mQuote)); 00114 boost::shared_ptr<Quote> d6mRate(new SimpleQuote(d6mQuote)); 00115 boost::shared_ptr<Quote> d9mRate(new SimpleQuote(d9mQuote)); 00116 boost::shared_ptr<Quote> d1yRate(new SimpleQuote(d1yQuote)); 00117 // FRAs 00118 boost::shared_ptr<Quote> fra3x6Rate(new SimpleQuote(fra3x6Quote)); 00119 boost::shared_ptr<Quote> fra6x9Rate(new SimpleQuote(fra6x9Quote)); 00120 boost::shared_ptr<Quote> fra6x12Rate(new SimpleQuote(fra6x12Quote)); 00121 // futures 00122 boost::shared_ptr<Quote> fut1Price(new SimpleQuote(fut1Quote)); 00123 boost::shared_ptr<Quote> fut2Price(new SimpleQuote(fut2Quote)); 00124 boost::shared_ptr<Quote> fut3Price(new SimpleQuote(fut3Quote)); 00125 boost::shared_ptr<Quote> fut4Price(new SimpleQuote(fut4Quote)); 00126 boost::shared_ptr<Quote> fut5Price(new SimpleQuote(fut5Quote)); 00127 boost::shared_ptr<Quote> fut6Price(new SimpleQuote(fut6Quote)); 00128 boost::shared_ptr<Quote> fut7Price(new SimpleQuote(fut7Quote)); 00129 boost::shared_ptr<Quote> fut8Price(new SimpleQuote(fut8Quote)); 00130 // swaps 00131 boost::shared_ptr<Quote> s2yRate(new SimpleQuote(s2yQuote)); 00132 boost::shared_ptr<Quote> s3yRate(new SimpleQuote(s3yQuote)); 00133 boost::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote)); 00134 boost::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote)); 00135 boost::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote)); 00136 00137 00138 /********************* 00139 *** RATE HELPERS *** 00140 *********************/ 00141 00142 // RateHelpers are built from the above quotes together with 00143 // other instrument dependant infos. Quotes are passed in 00144 // relinkable handles which could be relinked to some other 00145 // data source later. 00146 00147 // deposits 00148 DayCounter depositDayCounter = Actual360(); 00149 00150 boost::shared_ptr<RateHelper> d1w(new DepositRateHelper( 00151 Handle<Quote>(d1wRate), 00152 1, Weeks, fixingDays, 00153 calendar, ModifiedFollowing, depositDayCounter)); 00154 boost::shared_ptr<RateHelper> d1m(new DepositRateHelper( 00155 Handle<Quote>(d1mRate), 00156 1, Months, fixingDays, 00157 calendar, ModifiedFollowing, depositDayCounter)); 00158 boost::shared_ptr<RateHelper> d3m(new DepositRateHelper( 00159 Handle<Quote>(d3mRate), 00160 3, Months, fixingDays, 00161 calendar, ModifiedFollowing, depositDayCounter)); 00162 boost::shared_ptr<RateHelper> d6m(new DepositRateHelper( 00163 Handle<Quote>(d6mRate), 00164 6, Months, fixingDays, 00165 calendar, ModifiedFollowing, depositDayCounter)); 00166 boost::shared_ptr<RateHelper> d9m(new DepositRateHelper( 00167 Handle<Quote>(d9mRate), 00168 9, Months, fixingDays, 00169 calendar, ModifiedFollowing, depositDayCounter)); 00170 boost::shared_ptr<RateHelper> d1y(new DepositRateHelper( 00171 Handle<Quote>(d1yRate), 00172 1, Years, fixingDays, 00173 calendar, ModifiedFollowing, depositDayCounter)); 00174 00175 00176 // setup FRAs 00177 boost::shared_ptr<RateHelper> fra3x6(new FraRateHelper( 00178 Handle<Quote>(fra3x6Rate), 00179 3, 6, fixingDays, calendar, ModifiedFollowing, 00180 depositDayCounter)); 00181 boost::shared_ptr<RateHelper> fra6x9(new FraRateHelper( 00182 Handle<Quote>(fra6x9Rate), 00183 6, 9, fixingDays, calendar, ModifiedFollowing, 00184 depositDayCounter)); 00185 boost::shared_ptr<RateHelper> fra6x12(new FraRateHelper( 00186 Handle<Quote>(fra6x12Rate), 00187 6, 12, fixingDays, calendar, ModifiedFollowing, 00188 depositDayCounter)); 00189 00190 00191 // setup futures 00192 Integer futMonths = 3; 00193 Date imm = Date::nextIMMdate(settlementDate); 00194 boost::shared_ptr<RateHelper> fut1(new FuturesRateHelper( 00195 Handle<Quote>(fut1Price), 00196 imm, 00197 futMonths, calendar, ModifiedFollowing, 00198 depositDayCounter)); 00199 imm = Date::nextIMMdate(imm+1); 00200 boost::shared_ptr<RateHelper> fut2(new FuturesRateHelper( 00201 Handle<Quote>(fut1Price), 00202 imm, 00203 futMonths, calendar, ModifiedFollowing, 00204 depositDayCounter)); 00205 imm = Date::nextIMMdate(imm+1); 00206 boost::shared_ptr<RateHelper> fut3(new FuturesRateHelper( 00207 Handle<Quote>(fut1Price), 00208 imm, 00209 futMonths, calendar, ModifiedFollowing, 00210 depositDayCounter)); 00211 imm = Date::nextIMMdate(imm+1); 00212 boost::shared_ptr<RateHelper> fut4(new FuturesRateHelper( 00213 Handle<Quote>(fut1Price), 00214 imm, 00215 futMonths, calendar, ModifiedFollowing, 00216 depositDayCounter)); 00217 imm = Date::nextIMMdate(imm+1); 00218 boost::shared_ptr<RateHelper> fut5(new FuturesRateHelper( 00219 Handle<Quote>(fut1Price), 00220 imm, 00221 futMonths, calendar, ModifiedFollowing, 00222 depositDayCounter)); 00223 imm = Date::nextIMMdate(imm+1); 00224 boost::shared_ptr<RateHelper> fut6(new FuturesRateHelper( 00225 Handle<Quote>(fut1Price), 00226 imm, 00227 futMonths, calendar, ModifiedFollowing, 00228 depositDayCounter)); 00229 imm = Date::nextIMMdate(imm+1); 00230 boost::shared_ptr<RateHelper> fut7(new FuturesRateHelper( 00231 Handle<Quote>(fut1Price), 00232 imm, 00233 futMonths, calendar, ModifiedFollowing, 00234 depositDayCounter)); 00235 imm = Date::nextIMMdate(imm+1); 00236 boost::shared_ptr<RateHelper> fut8(new FuturesRateHelper( 00237 Handle<Quote>(fut1Price), 00238 imm, 00239 futMonths, calendar, ModifiedFollowing, 00240 depositDayCounter)); 00241 00242 00243 // setup swaps 00244 Frequency swFixedLegFrequency = Annual; 00245 BusinessDayConvention swFixedLegConvention = Unadjusted; 00246 DayCounter swFixedLegDayCounter = Thirty360(Thirty360::European); 00247 Frequency swFloatingLegFrequency = Semiannual; 00248 DayCounter swFloatingLegDayCounter = Actual360(); 00249 00250 boost::shared_ptr<RateHelper> s2y(new SwapRateHelper( 00251 Handle<Quote>(s2yRate), 00252 2, Years, fixingDays, 00253 calendar, swFixedLegFrequency, 00254 swFixedLegConvention, swFixedLegDayCounter, 00255 swFloatingLegFrequency, ModifiedFollowing, 00256 swFloatingLegDayCounter)); 00257 boost::shared_ptr<RateHelper> s3y(new SwapRateHelper( 00258 Handle<Quote>(s3yRate), 00259 3, Years, fixingDays, 00260 calendar, swFixedLegFrequency, 00261 swFixedLegConvention, swFixedLegDayCounter, 00262 swFloatingLegFrequency, ModifiedFollowing, 00263 swFloatingLegDayCounter)); 00264 boost::shared_ptr<RateHelper> s5y(new SwapRateHelper( 00265 Handle<Quote>(s5yRate), 00266 5, Years, fixingDays, 00267 calendar, swFixedLegFrequency, 00268 swFixedLegConvention, swFixedLegDayCounter, 00269 swFloatingLegFrequency, ModifiedFollowing, 00270 swFloatingLegDayCounter)); 00271 boost::shared_ptr<RateHelper> s10y(new SwapRateHelper( 00272 Handle<Quote>(s10yRate), 00273 10, Years, fixingDays, 00274 calendar, swFixedLegFrequency, 00275 swFixedLegConvention, swFixedLegDayCounter, 00276 swFloatingLegFrequency, ModifiedFollowing, 00277 swFloatingLegDayCounter)); 00278 boost::shared_ptr<RateHelper> s15y(new SwapRateHelper( 00279 Handle<Quote>(s15yRate), 00280 15, Years, fixingDays, 00281 calendar, swFixedLegFrequency, 00282 swFixedLegConvention, swFixedLegDayCounter, 00283 swFloatingLegFrequency, ModifiedFollowing, 00284 swFloatingLegDayCounter)); 00285 00286 00287 /********************* 00288 ** CURVE BUILDING ** 00289 *********************/ 00290 00291 // Any DayCounter would be fine. 00292 // ActualActual::ISDA ensures that 30 years is 30.0 00293 DayCounter termStructureDayCounter = 00294 ActualActual(ActualActual::ISDA); 00295 00296 00297 double tolerance = 1.0e-15; 00298 00299 // A depo-swap curve 00300 std::vector<boost::shared_ptr<RateHelper> > depoSwapInstruments; 00301 depoSwapInstruments.push_back(d1w); 00302 depoSwapInstruments.push_back(d1m); 00303 depoSwapInstruments.push_back(d3m); 00304 depoSwapInstruments.push_back(d6m); 00305 depoSwapInstruments.push_back(d9m); 00306 depoSwapInstruments.push_back(d1y); 00307 depoSwapInstruments.push_back(s2y); 00308 depoSwapInstruments.push_back(s3y); 00309 depoSwapInstruments.push_back(s5y); 00310 depoSwapInstruments.push_back(s10y); 00311 depoSwapInstruments.push_back(s15y); 00312 boost::shared_ptr<YieldTermStructure> depoSwapTermStructure(new 00313 PiecewiseFlatForward(settlementDate, depoSwapInstruments, 00314 termStructureDayCounter, tolerance)); 00315 00316 00317 // A depo-futures-swap curve 00318 std::vector<boost::shared_ptr<RateHelper> > depoFutSwapInstruments; 00319 depoFutSwapInstruments.push_back(d1w); 00320 depoFutSwapInstruments.push_back(d1m); 00321 depoFutSwapInstruments.push_back(fut1); 00322 depoFutSwapInstruments.push_back(fut2); 00323 depoFutSwapInstruments.push_back(fut3); 00324 depoFutSwapInstruments.push_back(fut4); 00325 depoFutSwapInstruments.push_back(fut5); 00326 depoFutSwapInstruments.push_back(fut6); 00327 depoFutSwapInstruments.push_back(fut7); 00328 depoFutSwapInstruments.push_back(fut8); 00329 depoFutSwapInstruments.push_back(s3y); 00330 depoFutSwapInstruments.push_back(s5y); 00331 depoFutSwapInstruments.push_back(s10y); 00332 depoFutSwapInstruments.push_back(s15y); 00333 boost::shared_ptr<YieldTermStructure> depoFutSwapTermStructure(new 00334 PiecewiseFlatForward(settlementDate, depoFutSwapInstruments, 00335 termStructureDayCounter, tolerance)); 00336 00337 00338 // A depo-FRA-swap curve 00339 std::vector<boost::shared_ptr<RateHelper> > depoFRASwapInstruments; 00340 depoFRASwapInstruments.push_back(d1w); 00341 depoFRASwapInstruments.push_back(d1m); 00342 depoFRASwapInstruments.push_back(d3m); 00343 depoFRASwapInstruments.push_back(fra3x6); 00344 depoFRASwapInstruments.push_back(fra6x9); 00345 depoFRASwapInstruments.push_back(fra6x12); 00346 depoFRASwapInstruments.push_back(s2y); 00347 depoFRASwapInstruments.push_back(s3y); 00348 depoFRASwapInstruments.push_back(s5y); 00349 depoFRASwapInstruments.push_back(s10y); 00350 depoFRASwapInstruments.push_back(s15y); 00351 boost::shared_ptr<YieldTermStructure> depoFRASwapTermStructure(new 00352 PiecewiseFlatForward(settlementDate, depoFRASwapInstruments, 00353 termStructureDayCounter, tolerance)); 00354 00355 00356 // Term structures that will be used for pricing: 00357 // the one used for discounting cash flows 00358 Handle<YieldTermStructure> discountingTermStructure; 00359 // the one used for forward rate forecasting 00360 Handle<YieldTermStructure> forecastingTermStructure; 00361 00362 00363 /********************* 00364 * SWAPS TO BE PRICED * 00365 **********************/ 00366 00367 // constant nominal 1,000,000 Euro 00368 Real nominal = 1000000.0; 00369 // fixed leg 00370 Frequency fixedLegFrequency = Annual; 00371 BusinessDayConvention fixedLegConvention = Unadjusted; 00372 BusinessDayConvention floatingLegConvention = ModifiedFollowing; 00373 DayCounter fixedLegDayCounter = Thirty360(Thirty360::European); 00374 Rate fixedRate = 0.04; 00375 DayCounter floatingLegDayCounter = Actual360(); 00376 00377 // floating leg 00378 Frequency floatingLegFrequency = Semiannual; 00379 boost::shared_ptr<Xibor> euriborIndex(new Euribor(6, Months, 00380 forecastingTermStructure)); // using the forecasting curve 00381 Spread spread = 0.0; 00382 00383 Integer lenghtInYears = 5; 00384 bool payFixedRate = true; 00385 00386 Date maturity = calendar.advance(settlementDate, lenghtInYears, Years, 00387 floatingLegConvention); 00388 Schedule fixedSchedule(calendar, settlementDate, maturity, 00389 fixedLegFrequency, fixedLegConvention); 00390 Schedule floatSchedule(calendar, settlementDate, maturity, 00391 floatingLegFrequency, floatingLegConvention); 00392 VanillaSwap spot5YearSwap( 00393 payFixedRate, nominal, 00394 fixedSchedule, fixedRate, fixedLegDayCounter, 00395 floatSchedule, euriborIndex, fixingDays, spread, 00396 floatingLegDayCounter, discountingTermStructure); 00397 00398 Date fwdStart = calendar.advance(settlementDate, 1, Years); 00399 Date fwdMaturity = calendar.advance(fwdStart, lenghtInYears, Years, 00400 floatingLegConvention); 00401 Schedule fwdFixedSchedule(calendar, fwdStart, fwdMaturity, 00402 fixedLegFrequency, fixedLegConvention); 00403 Schedule fwdFloatSchedule(calendar, fwdStart, fwdMaturity, 00404 floatingLegFrequency, floatingLegConvention); 00405 VanillaSwap oneYearForward5YearSwap( 00406 payFixedRate, nominal, 00407 fwdFixedSchedule, fixedRate, fixedLegDayCounter, 00408 fwdFloatSchedule, euriborIndex, fixingDays, spread, 00409 floatingLegDayCounter, discountingTermStructure); 00410 00411 00412 /*************** 00413 * SWAP PRICING * 00414 ****************/ 00415 00416 // utilities for reporting 00417 std::vector<std::string> headers(4); 00418 headers[0] = "term structure"; 00419 headers[1] = "net present value"; 00420 headers[2] = "fair spread"; 00421 headers[3] = "fair fixed rate"; 00422 std::string separator = " | "; 00423 Size width = headers[0].size() + separator.size() 00424 + headers[1].size() + separator.size() 00425 + headers[2].size() + separator.size() 00426 + headers[3].size() + separator.size() - 1; 00427 std::string rule(width, '-'), dblrule(width, '='); 00428 std::string tab(8, ' '); 00429 00430 // calculations 00431 00432 std::cout << dblrule << std::endl; 00433 std::cout << "5-year market swap-rate = " 00434 << std::setprecision(2) << io::rate(s5yRate->value()) 00435 << std::endl; 00436 std::cout << dblrule << std::endl; 00437 00438 std::cout << tab << "5-years swap paying " 00439 << io::rate(fixedRate) << std::endl; 00440 std::cout << headers[0] << separator 00441 << headers[1] << separator 00442 << headers[2] << separator 00443 << headers[3] << separator << std::endl; 00444 std::cout << rule << std::endl; 00445 00446 Real NPV; 00447 Rate fairRate; 00448 Spread fairSpread; 00449 00450 // Of course, you're not forced to really use different curves 00451 forecastingTermStructure.linkTo(depoSwapTermStructure); 00452 discountingTermStructure.linkTo(depoSwapTermStructure); 00453 00454 NPV = spot5YearSwap.NPV(); 00455 fairSpread = spot5YearSwap.fairSpread(); 00456 fairRate = spot5YearSwap.fairRate(); 00457 00458 std::cout << std::setw(headers[0].size()) 00459 << "depo-swap" << separator; 00460 std::cout << std::setw(headers[1].size()) 00461 << std::fixed << std::setprecision(2) << NPV << separator; 00462 std::cout << std::setw(headers[2].size()) 00463 << io::rate(fairSpread) << separator; 00464 std::cout << std::setw(headers[3].size()) 00465 << io::rate(fairRate) << separator; 00466 std::cout << std::endl; 00467 00468 00469 // let's check that the 5 years swap has been correctly re-priced 00470 QL_REQUIRE(std::fabs(fairRate-s5yQuote)<1e-8, 00471 "5-years swap mispriced by " 00472 << io::rate(std::fabs(fairRate-s5yQuote))); 00473 00474 00475 forecastingTermStructure.linkTo(depoFutSwapTermStructure); 00476 discountingTermStructure.linkTo(depoFutSwapTermStructure); 00477 00478 NPV = spot5YearSwap.NPV(); 00479 fairSpread = spot5YearSwap.fairSpread(); 00480 fairRate = spot5YearSwap.fairRate(); 00481 00482 std::cout << std::setw(headers[0].size()) 00483 << "depo-fut-swap" << separator; 00484 std::cout << std::setw(headers[1].size()) 00485 << std::fixed << std::setprecision(2) << NPV << separator; 00486 std::cout << std::setw(headers[2].size()) 00487 << io::rate(fairSpread) << separator; 00488 std::cout << std::setw(headers[3].size()) 00489 << io::rate(fairRate) << separator; 00490 std::cout << std::endl; 00491 00492 QL_REQUIRE(std::fabs(fairRate-s5yQuote)<1e-8, 00493 "5-years swap mispriced!"); 00494 00495 00496 forecastingTermStructure.linkTo(depoFRASwapTermStructure); 00497 discountingTermStructure.linkTo(depoFRASwapTermStructure); 00498 00499 NPV = spot5YearSwap.NPV(); 00500 fairSpread = spot5YearSwap.fairSpread(); 00501 fairRate = spot5YearSwap.fairRate(); 00502 00503 std::cout << std::setw(headers[0].size()) 00504 << "depo-FRA-swap" << separator; 00505 std::cout << std::setw(headers[1].size()) 00506 << std::fixed << std::setprecision(2) << NPV << separator; 00507 std::cout << std::setw(headers[2].size()) 00508 << io::rate(fairSpread) << separator; 00509 std::cout << std::setw(headers[3].size()) 00510 << io::rate(fairRate) << separator; 00511 std::cout << std::endl; 00512 00513 QL_REQUIRE(std::fabs(fairRate-s5yQuote)<1e-8, 00514 "5-years swap mispriced!"); 00515 00516 00517 std::cout << rule << std::endl; 00518 00519 // now let's price the 1Y forward 5Y swap 00520 00521 std::cout << tab << "5-years, 1-year forward swap paying " 00522 << io::rate(fixedRate) << std::endl; 00523 std::cout << headers[0] << separator 00524 << headers[1] << separator 00525 << headers[2] << separator 00526 << headers[3] << separator << std::endl; 00527 std::cout << rule << std::endl; 00528 00529 00530 forecastingTermStructure.linkTo(depoSwapTermStructure); 00531 discountingTermStructure.linkTo(depoSwapTermStructure); 00532 00533 NPV = oneYearForward5YearSwap.NPV(); 00534 fairSpread = oneYearForward5YearSwap.fairSpread(); 00535 fairRate = oneYearForward5YearSwap.fairRate(); 00536 00537 std::cout << std::setw(headers[0].size()) 00538 << "depo-swap" << separator; 00539 std::cout << std::setw(headers[1].size()) 00540 << std::fixed << std::setprecision(2) << NPV << separator; 00541 std::cout << std::setw(headers[2].size()) 00542 << io::rate(fairSpread) << separator; 00543 std::cout << std::setw(headers[3].size()) 00544 << io::rate(fairRate) << separator; 00545 std::cout << std::endl; 00546 00547 00548 forecastingTermStructure.linkTo(depoFutSwapTermStructure); 00549 discountingTermStructure.linkTo(depoFutSwapTermStructure); 00550 00551 NPV = oneYearForward5YearSwap.NPV(); 00552 fairSpread = oneYearForward5YearSwap.fairSpread(); 00553 fairRate = oneYearForward5YearSwap.fairRate(); 00554 00555 std::cout << std::setw(headers[0].size()) 00556 << "depo-fut-swap" << separator; 00557 std::cout << std::setw(headers[1].size()) 00558 << std::fixed << std::setprecision(2) << NPV << separator; 00559 std::cout << std::setw(headers[2].size()) 00560 << io::rate(fairSpread) << separator; 00561 std::cout << std::setw(headers[3].size()) 00562 << io::rate(fairRate) << separator; 00563 std::cout << std::endl; 00564 00565 00566 forecastingTermStructure.linkTo(depoFRASwapTermStructure); 00567 discountingTermStructure.linkTo(depoFRASwapTermStructure); 00568 00569 NPV = oneYearForward5YearSwap.NPV(); 00570 fairSpread = oneYearForward5YearSwap.fairSpread(); 00571 fairRate = oneYearForward5YearSwap.fairRate(); 00572 00573 std::cout << std::setw(headers[0].size()) 00574 << "depo-FRA-swap" << separator; 00575 std::cout << std::setw(headers[1].size()) 00576 << std::fixed << std::setprecision(2) << NPV << separator; 00577 std::cout << std::setw(headers[2].size()) 00578 << io::rate(fairSpread) << separator; 00579 std::cout << std::setw(headers[3].size()) 00580 << io::rate(fairRate) << separator; 00581 std::cout << std::endl; 00582 00583 00584 // now let's say that the 5-years swap rate goes up to 4.60%. 00585 // A smarter market element--say, connected to a data source-- would 00586 // notice the change itself. Since we're using SimpleQuotes, 00587 // we'll have to change the value manually--which forces us to 00588 // downcast the handle and use the SimpleQuote 00589 // interface. In any case, the point here is that a change in the 00590 // value contained in the Quote triggers a new bootstrapping 00591 // of the curve and a repricing of the swap. 00592 00593 boost::shared_ptr<SimpleQuote> fiveYearsRate = 00594 boost::dynamic_pointer_cast<SimpleQuote>(s5yRate); 00595 fiveYearsRate->setValue(0.0460); 00596 00597 std::cout << dblrule << std::endl; 00598 std::cout << "5-year market swap-rate = " 00599 << io::rate(s5yRate->value()) << std::endl; 00600 std::cout << dblrule << std::endl; 00601 00602 std::cout << tab << "5-years swap paying " 00603 << io::rate(fixedRate) << std::endl; 00604 std::cout << headers[0] << separator 00605 << headers[1] << separator 00606 << headers[2] << separator 00607 << headers[3] << separator << std::endl; 00608 std::cout << rule << std::endl; 00609 00610 // now get the updated results 00611 forecastingTermStructure.linkTo(depoSwapTermStructure); 00612 discountingTermStructure.linkTo(depoSwapTermStructure); 00613 00614 NPV = spot5YearSwap.NPV(); 00615 fairSpread = spot5YearSwap.fairSpread(); 00616 fairRate = spot5YearSwap.fairRate(); 00617 00618 std::cout << std::setw(headers[0].size()) 00619 << "depo-swap" << separator; 00620 std::cout << std::setw(headers[1].size()) 00621 << std::fixed << std::setprecision(2) << NPV << separator; 00622 std::cout << std::setw(headers[2].size()) 00623 << io::rate(fairSpread) << separator; 00624 std::cout << std::setw(headers[3].size()) 00625 << io::rate(fairRate) << separator; 00626 std::cout << std::endl; 00627 00628 QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8, 00629 "5-years swap mispriced!"); 00630 00631 00632 forecastingTermStructure.linkTo(depoFutSwapTermStructure); 00633 discountingTermStructure.linkTo(depoFutSwapTermStructure); 00634 00635 NPV = spot5YearSwap.NPV(); 00636 fairSpread = spot5YearSwap.fairSpread(); 00637 fairRate = spot5YearSwap.fairRate(); 00638 00639 std::cout << std::setw(headers[0].size()) 00640 << "depo-fut-swap" << separator; 00641 std::cout << std::setw(headers[1].size()) 00642 << std::fixed << std::setprecision(2) << NPV << separator; 00643 std::cout << std::setw(headers[2].size()) 00644 << io::rate(fairSpread) << separator; 00645 std::cout << std::setw(headers[3].size()) 00646 << io::rate(fairRate) << separator; 00647 std::cout << std::endl; 00648 00649 QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8, 00650 "5-years swap mispriced!"); 00651 00652 00653 forecastingTermStructure.linkTo(depoFRASwapTermStructure); 00654 discountingTermStructure.linkTo(depoFRASwapTermStructure); 00655 00656 NPV = spot5YearSwap.NPV(); 00657 fairSpread = spot5YearSwap.fairSpread(); 00658 fairRate = spot5YearSwap.fairRate(); 00659 00660 std::cout << std::setw(headers[0].size()) 00661 << "depo-FRA-swap" << separator; 00662 std::cout << std::setw(headers[1].size()) 00663 << std::fixed << std::setprecision(2) << NPV << separator; 00664 std::cout << std::setw(headers[2].size()) 00665 << io::rate(fairSpread) << separator; 00666 std::cout << std::setw(headers[3].size()) 00667 << io::rate(fairRate) << separator; 00668 std::cout << std::endl; 00669 00670 QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8, 00671 "5-years swap mispriced!"); 00672 00673 std::cout << rule << std::endl; 00674 00675 // the 1Y forward 5Y swap changes as well 00676 00677 std::cout << tab << "5-years, 1-year forward swap paying " 00678 << io::rate(fixedRate) << std::endl; 00679 std::cout << headers[0] << separator 00680 << headers[1] << separator 00681 << headers[2] << separator 00682 << headers[3] << separator << std::endl; 00683 std::cout << rule << std::endl; 00684 00685 00686 forecastingTermStructure.linkTo(depoSwapTermStructure); 00687 discountingTermStructure.linkTo(depoSwapTermStructure); 00688 00689 NPV = oneYearForward5YearSwap.NPV(); 00690 fairSpread = oneYearForward5YearSwap.fairSpread(); 00691 fairRate = oneYearForward5YearSwap.fairRate(); 00692 00693 std::cout << std::setw(headers[0].size()) 00694 << "depo-swap" << separator; 00695 std::cout << std::setw(headers[1].size()) 00696 << std::fixed << std::setprecision(2) << NPV << separator; 00697 std::cout << std::setw(headers[2].size()) 00698 << io::rate(fairSpread) << separator; 00699 std::cout << std::setw(headers[3].size()) 00700 << io::rate(fairRate) << separator; 00701 std::cout << std::endl; 00702 00703 00704 forecastingTermStructure.linkTo(depoFutSwapTermStructure); 00705 discountingTermStructure.linkTo(depoFutSwapTermStructure); 00706 00707 NPV = oneYearForward5YearSwap.NPV(); 00708 fairSpread = oneYearForward5YearSwap.fairSpread(); 00709 fairRate = oneYearForward5YearSwap.fairRate(); 00710 00711 std::cout << std::setw(headers[0].size()) 00712 << "depo-fut-swap" << separator; 00713 std::cout << std::setw(headers[1].size()) 00714 << std::fixed << std::setprecision(2) << NPV << separator; 00715 std::cout << std::setw(headers[2].size()) 00716 << io::rate(fairSpread) << separator; 00717 std::cout << std::setw(headers[3].size()) 00718 << io::rate(fairRate) << separator; 00719 std::cout << std::endl; 00720 00721 00722 forecastingTermStructure.linkTo(depoFRASwapTermStructure); 00723 discountingTermStructure.linkTo(depoFRASwapTermStructure); 00724 00725 NPV = oneYearForward5YearSwap.NPV(); 00726 fairSpread = oneYearForward5YearSwap.fairSpread(); 00727 fairRate = oneYearForward5YearSwap.fairRate(); 00728 00729 std::cout << std::setw(headers[0].size()) 00730 << "depo-FRA-swap" << separator; 00731 std::cout << std::setw(headers[1].size()) 00732 << std::fixed << std::setprecision(2) << NPV << separator; 00733 std::cout << std::setw(headers[2].size()) 00734 << io::rate(fairSpread) << separator; 00735 std::cout << std::setw(headers[3].size()) 00736 << io::rate(fairRate) << separator; 00737 std::cout << std::endl; 00738 00739 Real seconds = timer.elapsed(); 00740 Integer hours = int(seconds/3600); 00741 seconds -= hours * 3600; 00742 Integer minutes = int(seconds/60); 00743 seconds -= minutes * 60; 00744 std::cout << " \nRun completed in "; 00745 if (hours > 0) 00746 std::cout << hours << " h "; 00747 if (hours > 0 || minutes > 0) 00748 std::cout << minutes << " m "; 00749 std::cout << std::fixed << std::setprecision(0) 00750 << seconds << " s\n" << std::endl; 00751 00752 return 0; 00753 00754 } catch (std::exception& e) { 00755 std::cout << e.what() << std::endl; 00756 return 1; 00757 } catch (...) { 00758 std::cout << "unknown error" << std::endl; 00759 return 1; 00760 } 00761 } 00762