> 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
> 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
swap today. Basically it is the date at which you discount the cash
> -------------------
> 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;
> }
> }
>
>
overall pluggandisp can be glorked from context.
developers boost performance applications - including clusters.