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