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