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