swapvaluation.cpp

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

QuantLib.org
QuantLib
Hosted by
SourceForge.net Logo
Documentation generated by
doxygen