I am trying to value a plain old vanilla swap (pay fixed - receive usd libor) and have based my code on swapvaluation.cpp example. My swap settled on 3-may-2011, today is 19-may-2011 and it is a 7 year swap and fixed rate is 2.83. I am getting an error at line NPV = spot5YearSwap.NPV() which I can not figure out why. The code follows. Any help is greatly appreciated. Thank you.
------------------- Error message : 1st iteration: failed at 3rd alive instrument, maturity August 23rd, 2011, refer ence date May 3rd, 2011: root not bracketed: f[2.22045e-016,0.999738] -> [-1.762 113e+016,-2.035924e-004] --------------------- // the only header you need to use QuantLib #include <ql/quantlib.hpp> #ifdef BOOST_MSVC /* Uncomment the following lines to unmask floating-point exceptions. Warning: unpredictable results can arise... See http://www.wilmott.com/messageview.cfm?catid=10&threadid=9481 Is there anyone with a definitive word about this? */ // #include <float.h> // namespace { unsigned int u = _controlfp(_EM_INEXACT, _MCW_EM); } #endif #include <boost/timer.hpp> #include <iostream> #include <iomanip> using namespace QuantLib; #if defined(QL_ENABLE_SESSIONS) namespace QuantLib { Integer sessionId() { return 0; } } #endif int main(int, char* []) { try { boost::timer timer; std::cout << std::endl; /********************* *** MARKET DATA *** *********************/ Calendar calendar = TARGET(); Date settlementDate(3, May, 2011); // must be a business day settlementDate = calendar.adjust(settlementDate); Integer fixingDays = 2; Date todaysDate(19,May,2011); // nothing to do with Date::todaysDate Settings::instance().evaluationDate() = todaysDate; todaysDate = Settings::instance().evaluationDate(); std::cout << "Today: " << todaysDate.weekday() << ", " << todaysDate << std::endl; std::cout << "Settlement date: " << settlementDate.weekday() << ", " << settlementDate << std::endl; // deposits Rate d1wQuote=0.0016835; Rate d1mQuote=0.0019575; Rate d3mQuote=0.000456; Rate d6mQuote=0.000862; Rate d9mQuote=0.00571; Rate d1yQuote=0.0073475; // swaps Rate s2yQuote=0.0075; Rate s3yQuote=0.0122; Rate s5yQuote=0.02071; Rate s10yQuote=0.03254; Rate s15yQuote=0.03722; /******************** *** 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)); // 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(); boost::shared_ptr<RateHelper> d1w(new DepositRateHelper( Handle<Quote>(d1wRate), 1*Weeks, fixingDays, calendar, ModifiedFollowing, true, depositDayCounter)); boost::shared_ptr<RateHelper> d1m(new DepositRateHelper( Handle<Quote>(d1mRate), 1*Months, fixingDays, calendar, ModifiedFollowing, true, depositDayCounter)); boost::shared_ptr<RateHelper> d3m(new DepositRateHelper( Handle<Quote>(d3mRate), 3*Months, fixingDays, calendar, ModifiedFollowing, true, depositDayCounter)); boost::shared_ptr<RateHelper> d6m(new DepositRateHelper( Handle<Quote>(d6mRate), 6*Months, fixingDays, calendar, ModifiedFollowing, true, depositDayCounter)); boost::shared_ptr<RateHelper> d9m(new DepositRateHelper( Handle<Quote>(d9mRate), 9*Months, fixingDays, calendar, ModifiedFollowing, true, depositDayCounter)); boost::shared_ptr<RateHelper> d1y(new DepositRateHelper( Handle<Quote>(d1yRate), 1*Years, fixingDays, calendar, ModifiedFollowing, true, depositDayCounter)); // setup swaps Frequency swFixedLegFrequency = Semiannual; BusinessDayConvention swFixedLegConvention = ModifiedFollowing; DayCounter swFixedLegDayCounter = Thirty360(Thirty360::USA); boost::shared_ptr<IborIndex> swFloatingLegIndex(new USDLibor(Period(3,Months))); boost::shared_ptr<RateHelper> s2y(new SwapRateHelper( Handle<Quote>(s2yRate), 2*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s3y(new SwapRateHelper( Handle<Quote>(s3yRate), 3*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s5y(new SwapRateHelper( Handle<Quote>(s5yRate), 5*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s10y(new SwapRateHelper( Handle<Quote>(s10yRate), 10*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s15y(new SwapRateHelper( Handle<Quote>(s15yRate), 15*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 DayCounter termStructureDayCounter = ActualActual(ActualActual::ISDA); double tolerance = 1.0e-15; // 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<YieldTermStructure> depoSwapTermStructure( new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, depoSwapInstruments, termStructureDayCounter, tolerance)); // Term structures that will be used for pricing: // the one used for discounting cash flows RelinkableHandle<YieldTermStructure> discountingTermStructure; // the one used for forward rate forecasting RelinkableHandle<YieldTermStructure> forecastingTermStructure; /********************* * SWAPS TO BE PRICED * **********************/ // constant nominal 1,000,000 Euro Real nominal = 1350000.0; // fixed leg Frequency fixedLegFrequency = Semiannual; BusinessDayConvention fixedLegConvention = ModifiedFollowing; BusinessDayConvention floatingLegConvention = ModifiedFollowing; DayCounter fixedLegDayCounter = Thirty360(Thirty360::USA); Rate fixedRate = .02883; DayCounter floatingLegDayCounter = Actual360(); // floating leg Frequency floatingLegFrequency = Quarterly; boost::shared_ptr<IborIndex> euriborIndex( new USDLibor(Period(6,Months),discountingTermStructure)); Spread spread = 0.0; Integer lenghtInYears = 7; VanillaSwap::Type swapType = VanillaSwap::Payer; Date maturity = settlementDate + lenghtInYears*Years; Schedule fixedSchedule(settlementDate, maturity, Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration::Forward, false); Schedule floatSchedule(settlementDate, maturity, Period(floatingLegFrequency), calendar, floatingLegConvention, floatingLegConvention, DateGeneration::Forward, false); VanillaSwap spot5YearSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatSchedule, euriborIndex, spread, floatingLegDayCounter); Date fwdStart = calendar.advance(settlementDate, 1, Years); Date fwdMaturity = fwdStart + lenghtInYears*Years; Schedule fwdFixedSchedule(fwdStart, fwdMaturity, Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration::Forward, false); Schedule fwdFloatSchedule(fwdStart, fwdMaturity, Period(floatingLegFrequency), calendar, floatingLegConvention, floatingLegConvention, DateGeneration::Forward, false); VanillaSwap oneYearForward5YearSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter, fwdFloatSchedule, euriborIndex, spread, floatingLegDayCounter); /*************** * 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 = " << std::setprecision(2) << io::rate(s5yRate->value()) << std::endl; std::cout << dblrule << std::endl; std::cout << tab << "5-years swap paying " << io::rate(fixedRate) << 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; boost::shared_ptr<PricingEngine> swapEngine( new DiscountingSwapEngine(discountingTermStructure)); spot5YearSwap.setPricingEngine(swapEngine); oneYearForward5YearSwap.setPricingEngine(swapEngine); // 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()) << std::fixed << std::setprecision(2) << NPV << separator; std::cout << std::setw(headers[2].size()) << io::rate(fairSpread) << separator; std::cout << std::setw(headers[3].size()) << io::rate(fairRate) << separator; std::cout << std::endl; std::cout << rule << std::endl; // now let's price the 1Y forward 5Y swap std::cout << tab << "5-years, 1-year forward swap paying " << io::rate(fixedRate) << 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()) << std::fixed << std::setprecision(2) << NPV << separator; std::cout << std::setw(headers[2].size()) << io::rate(fairSpread) << separator; std::cout << std::setw(headers[3].size()) << io::rate(fairRate) << 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 = " << io::rate(s5yRate->value()) << std::endl; std::cout << dblrule << std::endl; std::cout << tab << "5-years swap paying " << io::rate(fixedRate) << 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()) << std::fixed << std::setprecision(2) << NPV << separator; std::cout << std::setw(headers[2].size()) << io::rate(fairSpread) << separator; std::cout << std::setw(headers[3].size()) << io::rate(fairRate) << separator; std::cout << std::endl; QL_REQUIRE(std::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 " << io::rate(fixedRate) << 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()) << std::fixed << std::setprecision(2) << NPV << separator; std::cout << std::setw(headers[2].size()) << io::rate(fairSpread) << separator; std::cout << std::setw(headers[3].size()) << io::rate(fairRate) << separator; std::cout << std::endl; Real seconds = timer.elapsed(); Integer hours = int(seconds/3600); seconds -= hours * 3600; Integer minutes = int(seconds/60); seconds -= minutes * 60; std::cout << " \nRun completed in "; if (hours > 0) std::cout << hours << " h "; if (hours > 0 || minutes > 0) std::cout << minutes << " m "; std::cout << std::fixed << std::setprecision(0) << seconds << " s\n" << std::endl; return 0; } catch (std::exception& e) { std::cerr << e.what() << std::endl; return 1; } catch (...) { std::cerr << "unknown error" << std::endl; return 1; } } |
On Thu, 2011-05-19 at 09:30 -0700, Pointman wrote:
> I am trying to value a plain old vanilla swap (pay fixed - receive usd libor) > and have based my code on swapvaluation.cpp example. My swap settled on > 3-may-2011, today is 19-may-2011 and it is a 7 year swap and fixed rate is > 2.83. I am getting an error at line NPV = spot5YearSwap.NPV() which I can > not figure out why. The code follows. Any help is greatly appreciated. Thank > you. The settlementDate is not meant to be the past date at which the swap settled, it's the date at which you'd settle if you were to unwind the swap today. Basically it is the date at which you discount the cash flows, which probably makes settlementDate a bit of a misnomer. Anyway, you can just set settlementDate = todaysDate, or todaysDate plus two settlement days if you want to discount to spot. After that, it should work. Luigi > ------------------- > Error message : 1st iteration: failed at 3rd alive instrument, maturity > August 23rd, 2011, refer > ence date May 3rd, 2011: root not bracketed: f[2.22045e-016,0.999738] -> > [-1.762 > 113e+016,-2.035924e-004] > --------------------- > // the only header you need to use QuantLib > #include <ql/quantlib.hpp> > > #ifdef BOOST_MSVC > /* Uncomment the following lines to unmask floating-point > exceptions. Warning: unpredictable results can arise... > > See http://www.wilmott.com/messageview.cfm?catid=10&threadid=9481 > Is there anyone with a definitive word about this? > */ > // #include <float.h> > // namespace { unsigned int u = _controlfp(_EM_INEXACT, _MCW_EM); } > #endif > > #include <boost/timer.hpp> > #include <iostream> > #include <iomanip> > > using namespace QuantLib; > > #if defined(QL_ENABLE_SESSIONS) > namespace QuantLib { > > Integer sessionId() { return 0; } > > } > #endif > > > int main(int, char* []) { > > try { > > boost::timer timer; > std::cout << std::endl; > > /********************* > *** MARKET DATA *** > *********************/ > > Calendar calendar = TARGET(); > Date settlementDate(3, May, 2011); > // must be a business day > settlementDate = calendar.adjust(settlementDate); > > Integer fixingDays = 2; > Date todaysDate(19,May,2011); > // nothing to do with Date::todaysDate > Settings::instance().evaluationDate() = todaysDate; > > > todaysDate = Settings::instance().evaluationDate(); > std::cout << "Today: " << todaysDate.weekday() > << ", " << todaysDate << std::endl; > > std::cout << "Settlement date: " << settlementDate.weekday() > << ", " << settlementDate << std::endl; > > // deposits > Rate d1wQuote=0.0016835; > Rate d1mQuote=0.0019575; > Rate d3mQuote=0.000456; > Rate d6mQuote=0.000862; > Rate d9mQuote=0.00571; > Rate d1yQuote=0.0073475; > > // swaps > Rate s2yQuote=0.0075; > Rate s3yQuote=0.0122; > Rate s5yQuote=0.02071; > Rate s10yQuote=0.03254; > Rate s15yQuote=0.03722; > > > /******************** > *** 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 d1wRate(new SimpleQuote(d1wQuote)); > boost::shared_ptr d1mRate(new SimpleQuote(d1mQuote)); > boost::shared_ptr d3mRate(new SimpleQuote(d3mQuote)); > boost::shared_ptr d6mRate(new SimpleQuote(d6mQuote)); > boost::shared_ptr d9mRate(new SimpleQuote(d9mQuote)); > boost::shared_ptr d1yRate(new SimpleQuote(d1yQuote)); > > // swaps > boost::shared_ptr s2yRate(new SimpleQuote(s2yQuote)); > boost::shared_ptr s3yRate(new SimpleQuote(s3yQuote)); > boost::shared_ptr s5yRate(new SimpleQuote(s5yQuote)); > boost::shared_ptr s10yRate(new SimpleQuote(s10yQuote)); > boost::shared_ptr 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(); > > boost::shared_ptr<RateHelper> d1w(new DepositRateHelper( > Handle(d1wRate), > 1*Weeks, fixingDays, > calendar, ModifiedFollowing, > true, depositDayCounter)); > boost::shared_ptr<RateHelper> d1m(new DepositRateHelper( > Handle(d1mRate), > 1*Months, fixingDays, > calendar, ModifiedFollowing, > true, depositDayCounter)); > boost::shared_ptr<RateHelper> d3m(new DepositRateHelper( > Handle(d3mRate), > 3*Months, fixingDays, > calendar, ModifiedFollowing, > true, depositDayCounter)); > boost::shared_ptr<RateHelper> d6m(new DepositRateHelper( > Handle(d6mRate), > 6*Months, fixingDays, > calendar, ModifiedFollowing, > true, depositDayCounter)); > boost::shared_ptr<RateHelper> d9m(new DepositRateHelper( > Handle(d9mRate), > 9*Months, fixingDays, > calendar, ModifiedFollowing, > true, depositDayCounter)); > boost::shared_ptr<RateHelper> d1y(new DepositRateHelper( > Handle(d1yRate), > 1*Years, fixingDays, > calendar, ModifiedFollowing, > true, depositDayCounter)); > > > > > > > // setup swaps > Frequency swFixedLegFrequency = Semiannual; > BusinessDayConvention swFixedLegConvention = ModifiedFollowing; > DayCounter swFixedLegDayCounter = Thirty360(Thirty360::USA); > boost::shared_ptr<IborIndex> swFloatingLegIndex(new > USDLibor(Period(3,Months))); > > boost::shared_ptr<RateHelper> s2y(new SwapRateHelper( > Handle(s2yRate), 2*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s3y(new SwapRateHelper( > Handle(s3yRate), 3*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s5y(new SwapRateHelper( > Handle(s5yRate), 5*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s10y(new SwapRateHelper( > Handle(s10yRate), 10*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s15y(new SwapRateHelper( > Handle(s15yRate), 15*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > > > /********************* > ** CURVE BUILDING ** > *********************/ > > // Any DayCounter would be fine. > // ActualActual::ISDA ensures that 30 years is 30.0 > DayCounter termStructureDayCounter = > ActualActual(ActualActual::ISDA); > > > double tolerance = 1.0e-15; > > // 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<YieldTermStructure> depoSwapTermStructure( > new PiecewiseYieldCurve<Discount,LogLinear>( > settlementDate, > depoSwapInstruments, > termStructureDayCounter, > tolerance)); > > > > // Term structures that will be used for pricing: > // the one used for discounting cash flows > RelinkableHandle<YieldTermStructure> discountingTermStructure; > // the one used for forward rate forecasting > RelinkableHandle<YieldTermStructure> forecastingTermStructure; > > > /********************* > * SWAPS TO BE PRICED * > **********************/ > > // constant nominal 1,000,000 Euro > Real nominal = 1350000.0; > // fixed leg > Frequency fixedLegFrequency = Semiannual; > BusinessDayConvention fixedLegConvention = ModifiedFollowing; > BusinessDayConvention floatingLegConvention = ModifiedFollowing; > DayCounter fixedLegDayCounter = Thirty360(Thirty360::USA); > Rate fixedRate = .02883; > DayCounter floatingLegDayCounter = Actual360(); > > // floating leg > Frequency floatingLegFrequency = Quarterly; > boost::shared_ptr<IborIndex> euriborIndex( > new > USDLibor(Period(6,Months),discountingTermStructure)); > Spread spread = 0.0; > > Integer lenghtInYears = 7; > VanillaSwap::Type swapType = VanillaSwap::Payer; > > Date maturity = settlementDate + lenghtInYears*Years; > Schedule fixedSchedule(settlementDate, maturity, > Period(fixedLegFrequency), > calendar, fixedLegConvention, > fixedLegConvention, > DateGeneration::Forward, false); > Schedule floatSchedule(settlementDate, maturity, > Period(floatingLegFrequency), > calendar, floatingLegConvention, > floatingLegConvention, > DateGeneration::Forward, false); > VanillaSwap spot5YearSwap(swapType, nominal, > fixedSchedule, fixedRate, fixedLegDayCounter, > floatSchedule, euriborIndex, spread, > floatingLegDayCounter); > > Date fwdStart = calendar.advance(settlementDate, 1, Years); > Date fwdMaturity = fwdStart + lenghtInYears*Years; > Schedule fwdFixedSchedule(fwdStart, fwdMaturity, > Period(fixedLegFrequency), > calendar, fixedLegConvention, > fixedLegConvention, > DateGeneration::Forward, false); > Schedule fwdFloatSchedule(fwdStart, fwdMaturity, > Period(floatingLegFrequency), > calendar, floatingLegConvention, > floatingLegConvention, > DateGeneration::Forward, false); > VanillaSwap oneYearForward5YearSwap(swapType, nominal, > fwdFixedSchedule, fixedRate, fixedLegDayCounter, > fwdFloatSchedule, euriborIndex, spread, > floatingLegDayCounter); > > > /*************** > * 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 = " > << std::setprecision(2) << io::rate(s5yRate->value()) > << std::endl; > std::cout << dblrule << std::endl; > > std::cout << tab << "5-years swap paying " > << io::rate(fixedRate) << 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; > > boost::shared_ptr<PricingEngine> swapEngine( > new > DiscountingSwapEngine(discountingTermStructure)); > > spot5YearSwap.setPricingEngine(swapEngine); > oneYearForward5YearSwap.setPricingEngine(swapEngine); > > // 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()) > << std::fixed << std::setprecision(2) << NPV << separator; > std::cout << std::setw(headers[2].size()) > << io::rate(fairSpread) << separator; > std::cout << std::setw(headers[3].size()) > << io::rate(fairRate) << separator; > std::cout << std::endl; > > > > std::cout << rule << std::endl; > > // now let's price the 1Y forward 5Y swap > > std::cout << tab << "5-years, 1-year forward swap paying " > << io::rate(fixedRate) << 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()) > << std::fixed << std::setprecision(2) << NPV << separator; > std::cout << std::setw(headers[2].size()) > << io::rate(fairSpread) << separator; > std::cout << std::setw(headers[3].size()) > << io::rate(fairRate) << 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 = " > << io::rate(s5yRate->value()) << std::endl; > std::cout << dblrule << std::endl; > > std::cout << tab << "5-years swap paying " > << io::rate(fixedRate) << 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()) > << std::fixed << std::setprecision(2) << NPV << separator; > std::cout << std::setw(headers[2].size()) > << io::rate(fairSpread) << separator; > std::cout << std::setw(headers[3].size()) > << io::rate(fairRate) << separator; > std::cout << std::endl; > > QL_REQUIRE(std::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 " > << io::rate(fixedRate) << 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()) > << std::fixed << std::setprecision(2) << NPV << separator; > std::cout << std::setw(headers[2].size()) > << io::rate(fairSpread) << separator; > std::cout << std::setw(headers[3].size()) > << io::rate(fairRate) << separator; > std::cout << std::endl; > > > > Real seconds = timer.elapsed(); > Integer hours = int(seconds/3600); > seconds -= hours * 3600; > Integer minutes = int(seconds/60); > seconds -= minutes * 60; > std::cout << " \nRun completed in "; > if (hours > 0) > std::cout << hours << " h "; > if (hours > 0 || minutes > 0) > std::cout << minutes << " m "; > std::cout << std::fixed << std::setprecision(0) > << seconds << " s\n" << std::endl; > > return 0; > > } catch (std::exception& e) { > std::cerr << e.what() << std::endl; > return 1; > } catch (...) { > std::cerr << "unknown error" << std::endl; > return 1; > } > } > > -- This gubblick contains many nonsklarkish English flutzpahs, but the overall pluggandisp can be glorked from context. -- David Moser ------------------------------------------------------------------------------ What Every C/C++ and Fortran developer Should Know! Read this article and learn how Intel has extended the reach of its next-generation tools to help Windows* and Linux* C/C++ and Fortran developers boost performance applications - including clusters. http://p.sf.net/sfu/intel-dev2devmay _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |