Anyone know what is happening here? I get this error message while I'm trying to
price a vanilla IRS. Here is some log output: 2010-08-05 06:19:06,757 INFO bootstrap - Today: Friday, May 27th, 2005 2010-08-05 06:19:06,757 INFO bootstrap - Settlement date: Tuesday, May 31st, 2005 2010-08-05 06:19:06,757 INFO bootstrap - Currency: usd 2010-08-05 06:19:06,773 INFO bootstrap - Libor date: Friday, May 27th, 2005 2010-08-05 06:19:07,136 DEBUG bootstrap - Using ibor: USDLibor, 6m 2010-08-05 06:19:07,138 INFO bootstrap - Creating swap: 2yf2y 2010-08-05 06:19:07,138 INFO bootstrap - Swap start: May 31st, 2007 2010-08-05 06:19:07,138 INFO bootstrap - Swap maturity: May 31st, 2009 2010-08-05 06:19:07,138 INFO bootstrap - Pricing swap: 2yf2y 1st iteration: failed at 16th instrument, maturity May 31st, 2007, reference date May 31st, 2005: 2nd leg: Missing USDLibor6M Actual/360 fixing for May 26th, 2005 Note that the error is for the 26th even though I'm processing data for the 27th. Neither May 26, 2005 nor May 27, 2005 is a holiday in the US. Somewhere my setup is backing up to what it thinks was the processing date, but it got it wrong. What's especially odd is I successfully process swaps for the preceding two months before I get to this date and blow up. Any ideas? Thanks ------------------------------------------------------------------------------ The Palm PDK Hot Apps Program offers developers who use the Plug-In Development Kit to bring their C/C++ apps to Palm for a share of $1 Million in cash or HP Products. Visit us here for more details: http://p.sf.net/sfu/dev2dev-palm _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Thu, 2010-08-05 at 10:45 +0000, MonkeyMan wrote:
> Anyone know what is happening here? I get this error message while I'm trying to > price a vanilla IRS. [...] Somewhere my > setup is backing up to what it thinks was the processing date, but it got it > wrong. Can you post some self-contained code that reproduces the error? Luigi -- Hofstadter's Law: It always takes longer than you expect, even when you take Hofstadter's Law into account. ------------------------------------------------------------------------------ The Palm PDK Hot Apps Program offers developers who use the Plug-In Development Kit to bring their C/C++ apps to Palm for a share of $1 Million in cash or HP Products. Visit us here for more details: http://p.sf.net/sfu/dev2dev-palm _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Hi all, Luigi Ballabio schrieb: > On Thu, 2010-08-05 at 10:45 +0000, MonkeyMan wrote: > > Can you post some self-contained code that reproduces the error? > wirting a self-contained and complete code (code snippet is not enough) to reproduce the bug is very important. It is even suggested by the boost web site: http://www.boost.org/support/bugs.html To quote: Attach a /minimal/ and /complete/ program that reproduces the problem. Aside from helping the library maintainer fix the problem, you may find the bug in your own code, which can avoid a costly delay waiting for a response. Kim > Luigi > > > ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by Luigi Ballabio
Here is a complete program that reproduces the anomaly (not calling it a bug). I
suspect instead that it is something I am doing incorrectly. This code should look familiar. It is the swapvaluation example with a couple of changes. Most importantly for this post, instead of starting with the settlement date and backing up 2 days to get today's date, I start with today's date and go forward 2 days. That is how this would be run in the RW. Thanks in advance for any help! BEGIN CODE: /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include <ql/quantlib.hpp> #ifdef BOOST_MSVC // #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 *** *********************/ //May 29, 2005 is a holiday Calendar calendar = UnitedStates(); Date todaysDate(29, April, 2005); // must be a business day Integer fixingDays = 2; Date settlementDate = calendar.advance(todaysDate, fixingDays, Days); settlementDate = calendar.adjust(settlementDate); // 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.0306625; Rate d2wQuote=0.0307563; Rate d1mQuote=0.0307563; Rate d2mQuote=0.0323000; Rate d3mQuote=0.0311125; Rate d6mQuote=0.0353000; Rate d9mQuote=0.0367375; Rate d1yQuote=0.0378000; ; // futures Real fut1Quote=96.5775; Real fut2Quote=96.235; Real fut3Quote=96.07; Real fut4Quote=95.995; Real fut5Quote=95.93; Real fut6Quote=95.87; Real fut7Quote=95.815; Real fut8Quote=95.795; // swaps Rate s2yQuote=0.037975; Rate s3yQuote=0.040650; Rate s4yQuote=0.041350; Rate s5yQuote=0.042000; Rate s6yQuote=0.042600; Rate s7yQuote=0.043100; Rate s8yQuote=0.043650; Rate s9yQuote=0.044200; Rate s10yQuote=0.044650; Rate s12yQuote=0.045500; Rate s15yQuote=0.046550; Rate s20yQuote=0.047600; Rate s30yQuote=0.048250; /******************** *** 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> d2wRate(new SimpleQuote(d2wQuote)); boost::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote)); boost::shared_ptr<Quote> d2mRate(new SimpleQuote(d2mQuote)); 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)); // 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> s4yRate(new SimpleQuote(s4yQuote)); boost::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote)); boost::shared_ptr<Quote> s6yRate(new SimpleQuote(s6yQuote)); boost::shared_ptr<Quote> s7yRate(new SimpleQuote(s7yQuote)); boost::shared_ptr<Quote> s8yRate(new SimpleQuote(s8yQuote)); boost::shared_ptr<Quote> s9yRate(new SimpleQuote(s9yQuote)); boost::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote)); boost::shared_ptr<Quote> s12yRate(new SimpleQuote(s12yQuote)); boost::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote)); boost::shared_ptr<Quote> s20yRate(new SimpleQuote(s20yQuote)); boost::shared_ptr<Quote> s30yRate(new SimpleQuote(s30yQuote)); /********************* *** RATE HELPERS *** *********************/ // 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> d2w(new DepositRateHelper( Handle<Quote>(d2wRate), 2*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> d2m(new DepositRateHelper( Handle<Quote>(d2mRate), 2*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 futures // Rate convexityAdjustment = 0.0; Integer futMonths = 3; Date imm = IMM::nextDate(settlementDate); boost::shared_ptr<RateHelper> fut1(new FuturesRateHelper( Handle<Quote>(fut1Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); imm = IMM::nextDate(imm+1); boost::shared_ptr<RateHelper> fut2(new FuturesRateHelper( Handle<Quote>(fut2Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); imm = IMM::nextDate(imm+1); boost::shared_ptr<RateHelper> fut3(new FuturesRateHelper( Handle<Quote>(fut3Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); imm = IMM::nextDate(imm+1); boost::shared_ptr<RateHelper> fut4(new FuturesRateHelper( Handle<Quote>(fut4Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); imm = IMM::nextDate(imm+1); boost::shared_ptr<RateHelper> fut5(new FuturesRateHelper( Handle<Quote>(fut5Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); imm = IMM::nextDate(imm+1); boost::shared_ptr<RateHelper> fut6(new FuturesRateHelper( Handle<Quote>(fut6Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); imm = IMM::nextDate(imm+1); boost::shared_ptr<RateHelper> fut7(new FuturesRateHelper( Handle<Quote>(fut7Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); imm = IMM::nextDate(imm+1); boost::shared_ptr<RateHelper> fut8(new FuturesRateHelper( Handle<Quote>(fut8Price), imm, futMonths, calendar, ModifiedFollowing, true, depositDayCounter)); // setup swaps Frequency swFixedLegFrequency = Annual; BusinessDayConvention swFixedLegConvention = Unadjusted; DayCounter swFixedLegDayCounter = Thirty360(Thirty360::USA); boost::shared_ptr<IborIndex> swFloatingLegIndex(new USDLibor(Period(6,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> s4y(new SwapRateHelper( Handle<Quote>(s4yRate), 4*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> s6y(new SwapRateHelper( Handle<Quote>(s6yRate), 6*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s7y(new SwapRateHelper( Handle<Quote>(s7yRate), 7*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s8y(new SwapRateHelper( Handle<Quote>(s8yRate), 8*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s9y(new SwapRateHelper( Handle<Quote>(s9yRate), 9*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> s12y(new SwapRateHelper( Handle<Quote>(s12yRate), 12*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s15y(new SwapRateHelper( Handle<Quote>(s15yRate), 15*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s20y(new SwapRateHelper( Handle<Quote>(s20yRate), 20*Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); boost::shared_ptr<RateHelper> s30y(new SwapRateHelper( Handle<Quote>(s30yRate), 30*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-futures-swap curve std::vector<boost::shared_ptr<RateHelper> > depoFutSwapInstruments; depoFutSwapInstruments.push_back(d1w); depoFutSwapInstruments.push_back(d2w); depoFutSwapInstruments.push_back(d1m); depoFutSwapInstruments.push_back(d2m); depoFutSwapInstruments.push_back(d3m); depoFutSwapInstruments.push_back(d6m); depoFutSwapInstruments.push_back(d9m); depoFutSwapInstruments.push_back(d1y); 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(s2y); depoFutSwapInstruments.push_back(s3y); depoFutSwapInstruments.push_back(s4y); depoFutSwapInstruments.push_back(s5y); depoFutSwapInstruments.push_back(s6y); depoFutSwapInstruments.push_back(s7y); depoFutSwapInstruments.push_back(s8y); depoFutSwapInstruments.push_back(s9y); depoFutSwapInstruments.push_back(s10y); depoFutSwapInstruments.push_back(s12y); depoFutSwapInstruments.push_back(s15y); depoFutSwapInstruments.push_back(s20y); depoFutSwapInstruments.push_back(s30y); LogCubic mlcns = LogCubic( CubicInterpolation::Spline, true, CubicInterpolation::SecondDerivative, 0, CubicInterpolation::SecondDerivative, 0); boost::shared_ptr<YieldTermStructure> depoFutSwapTermStructure( new PiecewiseYieldCurve<Discount,LogCubic>( settlementDate, depoFutSwapInstruments, termStructureDayCounter, tolerance, mlcns)); depoFutSwapTermStructure->enableExtrapolation(); // Term structures that will be used for pricing: // the one used for discounting cash flows RelinkableHandle<YieldTermStructure> discountingTermStructure; /********************* * 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::USA); Rate fixedRate = 0.04; DayCounter floatingLegDayCounter = Actual360(); // floating leg Frequency floatingLegFrequency = Semiannual; boost::shared_ptr<IborIndex> iborIndex(new USDLibor(Period(6,Months),discountingTermStructure)); Spread spread = 0.0; Integer lenghtInYears = 2; 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); Date fwdStart = calendar.advance(settlementDate, 2, 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 twoYearForward2YearSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter, fwdFloatSchedule, iborIndex, 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 Real NPV; Rate fairRate; Spread fairSpread; boost::shared_ptr<PricingEngine> swapEngine( new DiscountingSwapEngine(discountingTermStructure)); twoYearForward2YearSwap.setPricingEngine(swapEngine); discountingTermStructure.linkTo(depoFutSwapTermStructure); // now let's price the 2Y forward 2Y swap std::cout << tab << "2-years, 2-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; NPV = twoYearForward2YearSwap.NPV(); fairSpread = twoYearForward2YearSwap.fairSpread(); fairRate = twoYearForward2YearSwap.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 SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
I am not sure if this is correct, but might as well say it.
Suppose you have a 1 year "vanilla" interest rate swap with quarter floating rate payment. i.e., the floating rate index is a 3 months libor. However, I have seen two ways of computing the forward libor. I am not sure which one is correct. Say the 1 year floating leg start on on Feb 17 2009 and end on Feb 17 2010. The accrual periods, only adjusted to weekends, are Feb 17 2009, May 18 2009 May 18 2009, Aug 17 2009 Aug 17 2009, Nov 17 2009 Nov 17 2009, Feb 17 2010 Note that the May 17 2009 is Sunday, so it is adjusted to May 18 2009. There are two ways to compute the forward rate for period May 18 to Aug 17 2009. (1) ForwardRate(May 18 2009, Aug 17 2009), which is "naturally" the same as the accrual period. (2) ForwardRate(May 18 2009, May 18 2009 + 3 months), which is using the 3 months libor definition. Note that the dates I am using is the effective dates (not the observation). Because of the holiday adjustment, (1) and (2) are slightly different. As far as the "vanilla" IR Swap, is the floating rate payment using (1) or (2)? If you change the date to 29th April 2006 code works, also for 29th April 2009, and for 29th April 2010. For 29th April 2005, it doesn't work, but it does for 29th April 2004. Also fixing date and settlement dates are different. For example.... "Taking the period "May 18 2009 to Aug 17 2009" for example, assume fixing days is 5 (bds) and settle days is 2 (bds), then fixing date is May 11 2009 and 3m libor start at May 13 2009 and end at Aug 13 2009...but accrual period is "May 18 2009 to Aug 17 2009". " Anyway this is just the financial part, i guess only a developer can figure out the intricacies. Coz the date mismatch is a genuine problem in swaps, and depends on how you choose to solve it. Either way is correct. On 8/6/10 4:45 PM, MonkeyMan wrote: > Here is a complete program that reproduces the anomaly (not calling it a bug). I > suspect instead that it is something I am doing incorrectly. This code should > look familiar. It is the swapvaluation example with a couple of changes. Most > importantly for this post, instead of starting with the settlement date and > backing up 2 days to get today's date, I start with today's date and go forward > 2 days. That is how this would be run in the RW. Thanks in advance for any help! > > BEGIN CODE: > > /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ > > #include<ql/quantlib.hpp> > > #ifdef BOOST_MSVC > // #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 *** > *********************/ > //May 29, 2005 is a holiday > Calendar calendar = UnitedStates(); > > > Date todaysDate(29, April, 2005); > // must be a business day > > > Integer fixingDays = 2; > Date settlementDate = calendar.advance(todaysDate, fixingDays, Days); > settlementDate = calendar.adjust(settlementDate); > // 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.0306625; > Rate d2wQuote=0.0307563; > Rate d1mQuote=0.0307563; > Rate d2mQuote=0.0323000; > Rate d3mQuote=0.0311125; > Rate d6mQuote=0.0353000; > Rate d9mQuote=0.0367375; > Rate d1yQuote=0.0378000; > ; > // futures > Real fut1Quote=96.5775; > Real fut2Quote=96.235; > Real fut3Quote=96.07; > Real fut4Quote=95.995; > Real fut5Quote=95.93; > Real fut6Quote=95.87; > Real fut7Quote=95.815; > Real fut8Quote=95.795; > // swaps > Rate s2yQuote=0.037975; > Rate s3yQuote=0.040650; > Rate s4yQuote=0.041350; > Rate s5yQuote=0.042000; > Rate s6yQuote=0.042600; > Rate s7yQuote=0.043100; > Rate s8yQuote=0.043650; > Rate s9yQuote=0.044200; > Rate s10yQuote=0.044650; > Rate s12yQuote=0.045500; > Rate s15yQuote=0.046550; > Rate s20yQuote=0.047600; > Rate s30yQuote=0.048250; > > > /******************** > *** 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> d2wRate(new SimpleQuote(d2wQuote)); > boost::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote)); > boost::shared_ptr<Quote> d2mRate(new SimpleQuote(d2mQuote)); > 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)); > > // 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> s4yRate(new SimpleQuote(s4yQuote)); > boost::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote)); > boost::shared_ptr<Quote> s6yRate(new SimpleQuote(s6yQuote)); > boost::shared_ptr<Quote> s7yRate(new SimpleQuote(s7yQuote)); > boost::shared_ptr<Quote> s8yRate(new SimpleQuote(s8yQuote)); > boost::shared_ptr<Quote> s9yRate(new SimpleQuote(s9yQuote)); > boost::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote)); > boost::shared_ptr<Quote> s12yRate(new SimpleQuote(s12yQuote)); > boost::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote)); > boost::shared_ptr<Quote> s20yRate(new SimpleQuote(s20yQuote)); > boost::shared_ptr<Quote> s30yRate(new SimpleQuote(s30yQuote)); > > > > > > /********************* > *** RATE HELPERS *** > *********************/ > // 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> d2w(new DepositRateHelper( > Handle<Quote>(d2wRate), > 2*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> d2m(new DepositRateHelper( > Handle<Quote>(d2mRate), > 2*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 futures > // Rate convexityAdjustment = 0.0; > Integer futMonths = 3; > Date imm = IMM::nextDate(settlementDate); > boost::shared_ptr<RateHelper> fut1(new FuturesRateHelper( > Handle<Quote>(fut1Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > imm = IMM::nextDate(imm+1); > boost::shared_ptr<RateHelper> fut2(new FuturesRateHelper( > Handle<Quote>(fut2Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > imm = IMM::nextDate(imm+1); > boost::shared_ptr<RateHelper> fut3(new FuturesRateHelper( > Handle<Quote>(fut3Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > imm = IMM::nextDate(imm+1); > boost::shared_ptr<RateHelper> fut4(new FuturesRateHelper( > Handle<Quote>(fut4Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > imm = IMM::nextDate(imm+1); > boost::shared_ptr<RateHelper> fut5(new FuturesRateHelper( > Handle<Quote>(fut5Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > imm = IMM::nextDate(imm+1); > boost::shared_ptr<RateHelper> fut6(new FuturesRateHelper( > Handle<Quote>(fut6Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > imm = IMM::nextDate(imm+1); > boost::shared_ptr<RateHelper> fut7(new FuturesRateHelper( > Handle<Quote>(fut7Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > imm = IMM::nextDate(imm+1); > boost::shared_ptr<RateHelper> fut8(new FuturesRateHelper( > Handle<Quote>(fut8Price), > imm, > futMonths, calendar, ModifiedFollowing, > true, depositDayCounter)); > > > // setup swaps > Frequency swFixedLegFrequency = Annual; > BusinessDayConvention swFixedLegConvention = Unadjusted; > DayCounter swFixedLegDayCounter = Thirty360(Thirty360::USA); > boost::shared_ptr<IborIndex> swFloatingLegIndex(new > USDLibor(Period(6,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> s4y(new SwapRateHelper( > Handle<Quote>(s4yRate), 4*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> s6y(new SwapRateHelper( > Handle<Quote>(s6yRate), 6*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s7y(new SwapRateHelper( > Handle<Quote>(s7yRate), 7*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s8y(new SwapRateHelper( > Handle<Quote>(s8yRate), 8*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s9y(new SwapRateHelper( > Handle<Quote>(s9yRate), 9*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> s12y(new SwapRateHelper( > Handle<Quote>(s12yRate), 12*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s15y(new SwapRateHelper( > Handle<Quote>(s15yRate), 15*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s20y(new SwapRateHelper( > Handle<Quote>(s20yRate), 20*Years, > calendar, swFixedLegFrequency, > swFixedLegConvention, swFixedLegDayCounter, > swFloatingLegIndex)); > boost::shared_ptr<RateHelper> s30y(new SwapRateHelper( > Handle<Quote>(s30yRate), 30*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-futures-swap curve > std::vector<boost::shared_ptr<RateHelper> > depoFutSwapInstruments; > depoFutSwapInstruments.push_back(d1w); > depoFutSwapInstruments.push_back(d2w); > depoFutSwapInstruments.push_back(d1m); > depoFutSwapInstruments.push_back(d2m); > depoFutSwapInstruments.push_back(d3m); > depoFutSwapInstruments.push_back(d6m); > depoFutSwapInstruments.push_back(d9m); > depoFutSwapInstruments.push_back(d1y); > 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(s2y); > depoFutSwapInstruments.push_back(s3y); > depoFutSwapInstruments.push_back(s4y); > depoFutSwapInstruments.push_back(s5y); > depoFutSwapInstruments.push_back(s6y); > depoFutSwapInstruments.push_back(s7y); > depoFutSwapInstruments.push_back(s8y); > depoFutSwapInstruments.push_back(s9y); > depoFutSwapInstruments.push_back(s10y); > depoFutSwapInstruments.push_back(s12y); > depoFutSwapInstruments.push_back(s15y); > depoFutSwapInstruments.push_back(s20y); > depoFutSwapInstruments.push_back(s30y); > > LogCubic mlcns = LogCubic( > CubicInterpolation::Spline, > true, > CubicInterpolation::SecondDerivative, > 0, > CubicInterpolation::SecondDerivative, > 0); > > boost::shared_ptr<YieldTermStructure> depoFutSwapTermStructure( > new PiecewiseYieldCurve<Discount,LogCubic>( > settlementDate, depoFutSwapInstruments, > termStructureDayCounter, > tolerance, > mlcns)); > depoFutSwapTermStructure->enableExtrapolation(); > > > // Term structures that will be used for pricing: > // the one used for discounting cash flows > RelinkableHandle<YieldTermStructure> discountingTermStructure; > > > /********************* > * 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::USA); > Rate fixedRate = 0.04; > DayCounter floatingLegDayCounter = Actual360(); > > // floating leg > Frequency floatingLegFrequency = Semiannual; > boost::shared_ptr<IborIndex> iborIndex(new > USDLibor(Period(6,Months),discountingTermStructure)); > Spread spread = 0.0; > > Integer lenghtInYears = 2; > 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); > > Date fwdStart = calendar.advance(settlementDate, 2, 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 twoYearForward2YearSwap(swapType, nominal, > fwdFixedSchedule, fixedRate, fixedLegDayCounter, > fwdFloatSchedule, iborIndex, 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 > Real NPV; > Rate fairRate; > Spread fairSpread; > > boost::shared_ptr<PricingEngine> swapEngine( > new DiscountingSwapEngine(discountingTermStructure)); > > twoYearForward2YearSwap.setPricingEngine(swapEngine); > discountingTermStructure.linkTo(depoFutSwapTermStructure); > > // now let's price the 2Y forward 2Y swap > > std::cout<< tab<< "2-years, 2-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; > > NPV = twoYearForward2YearSwap.NPV(); > fairSpread = twoYearForward2YearSwap.fairSpread(); > fairRate = twoYearForward2YearSwap.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 SF.net email is sponsored by > > Make an app they can't live without > Enter the BlackBerry Developer Challenge > http://p.sf.net/sfu/RIM-dev2dev > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users > -- Regards, Animesh Saxena (http://quantanalysis.wordpress.com) Ph: (+91)9920098221 ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
animesh saxena <animesh.saxena <at> gmail.com> writes:
> ... (gmane made me prune the rest of this post) > Say the 1 year floating leg start on on Feb 17 2009 and end on Feb 17 > 2010. The accrual periods, only adjusted to weekends, are > Feb 17 2009, May 18 2009 > May 18 2009, Aug 17 2009 > Aug 17 2009, Nov 17 2009 > Nov 17 2009, Feb 17 2010 > > Note that the May 17 2009 is Sunday, so it is adjusted to May 18 2009. > There are two ways to compute the forward rate for period May 18 to Aug > 17 2009. > (1) ForwardRate(May 18 2009, Aug 17 2009), which is "naturally" the same > as the accrual period. > (2) ForwardRate(May 18 2009, May 18 2009 + 3 months), which is using the > 3 months libor definition. > ... (gmane made me prune the rest of this post) Seems like you'd want to go with your first option. You'd need to interpolate the rates in the shorter period rather than extend past the end date. This should be priced into the instrument, right? ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Yes, that's right. But again the question is -> Is this what Quantlib
is doing? Or is it extending past the start or end dates and hence error in finding the libor rate On 8/9/10 7:11 PM, MonkeyMan wrote: > animesh saxena<animesh.saxena<at> gmail.com> writes: > >> ... (gmane made me prune the rest of this post) >> Say the 1 year floating leg start on on Feb 17 2009 and end on Feb 17 >> 2010. The accrual periods, only adjusted to weekends, are >> Feb 17 2009, May 18 2009 >> May 18 2009, Aug 17 2009 >> Aug 17 2009, Nov 17 2009 >> Nov 17 2009, Feb 17 2010 >> >> Note that the May 17 2009 is Sunday, so it is adjusted to May 18 2009. >> There are two ways to compute the forward rate for period May 18 to Aug >> 17 2009. >> (1) ForwardRate(May 18 2009, Aug 17 2009), which is "naturally" the same >> as the accrual period. >> (2) ForwardRate(May 18 2009, May 18 2009 + 3 months), which is using the >> 3 months libor definition. >> ... (gmane made me prune the rest of this post) > Seems like you'd want to go with your first option. You'd need to interpolate > the rates in the shorter period rather than extend past the end date. This > should be priced into the instrument, right? > > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by > > Make an app they can't live without > Enter the BlackBerry Developer Challenge > http://p.sf.net/sfu/RIM-dev2dev > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users > -- Regards, Animesh Saxena (http://quantanalysis.wordpress.com) Ph: (+91)9920098221 ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
I'm almost 100% sure QL is doing #1 (May 18 2009 - Aug 17 2009), since
that would be the rate that matches the true accrual period. Just because we call it the 'libor curve' doesn't necessarily mean that we only can pull out 3M forward rates. A good way to think about it is simply a 'libor-denominated curve' in which case you are simply saying that you constructed your curve from libor-based instruments. I guess someone who knows how to read C++ would be able to give a definitive answer on what QL is doing in the code. Remember that you need to pass old libor fixings (3M) to the curve in order to generate swaps that have already become effective (i.e. their cashflows have started to transfer between parties). Use the function =qlIndexAddFixings. On Mon, Aug 9, 2010 at 8:55 AM, animesh saxena <[hidden email]> wrote: > Yes, that's right. But again the question is -> Is this what Quantlib > is doing? > Or is it extending past the start or end dates and hence error in > finding the libor rate > > > On 8/9/10 7:11 PM, MonkeyMan wrote: >> animesh saxena<animesh.saxena<at> gmail.com> writes: >> >>> ... (gmane made me prune the rest of this post) >>> Say the 1 year floating leg start on on Feb 17 2009 and end on Feb 17 >>> 2010. The accrual periods, only adjusted to weekends, are >>> Feb 17 2009, May 18 2009 >>> May 18 2009, Aug 17 2009 >>> Aug 17 2009, Nov 17 2009 >>> Nov 17 2009, Feb 17 2010 >>> >>> Note that the May 17 2009 is Sunday, so it is adjusted to May 18 2009. >>> There are two ways to compute the forward rate for period May 18 to Aug >>> 17 2009. >>> (1) ForwardRate(May 18 2009, Aug 17 2009), which is "naturally" the same >>> as the accrual period. >>> (2) ForwardRate(May 18 2009, May 18 2009 + 3 months), which is using the >>> 3 months libor definition. >>> ... (gmane made me prune the rest of this post) >> Seems like you'd want to go with your first option. You'd need to interpolate >> the rates in the shorter period rather than extend past the end date. This >> should be priced into the instrument, right? >> >> >> >> ------------------------------------------------------------------------------ >> This SF.net email is sponsored by >> >> Make an app they can't live without >> Enter the BlackBerry Developer Challenge >> http://p.sf.net/sfu/RIM-dev2dev >> _______________________________________________ >> QuantLib-users mailing list >> [hidden email] >> https://lists.sourceforge.net/lists/listinfo/quantlib-users >> > > -- > Regards, > Animesh Saxena > > (http://quantanalysis.wordpress.com) > Ph: (+91)9920098221 > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by > > Make an app they can't live without > Enter the BlackBerry Developer Challenge > http://p.sf.net/sfu/RIM-dev2dev > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users > ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Mike DelMedico <mike.delmedico <at> gmail.com> writes:
> > I'm almost 100% sure QL is doing #1 (May 18 2009 - Aug 17 2009), since > that would be the rate that matches the true accrual period. I agree. > Remember that you need to pass old libor fixings (3M) to the curve in > order to generate swaps that have already become effective (i.e. their > cashflows have started to transfer between parties). Use the function > =qlIndexAddFixings. > Thanks. I didn't know about this function. In my example I take the deposit, futures, and spot swap rates observed at time 0 and simply want to calculate a forward rate as of time 0. I don't have any swaps that started in the past. I really don't know why Quantlib is backup up past my eval date to start the swap. ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by MonkeyMan-3
On Fri, 2010-08-06 at 11:15 +0000, MonkeyMan wrote:
> Here is a complete program that reproduces the anomaly (not calling it a bug). I > suspect instead that it is something I am doing incorrectly. This code should > look familiar. It is the swapvaluation example with a couple of changes. Most > importantly for this post, instead of starting with the settlement date and > backing up 2 days to get today's date, I start with today's date and go forward > 2 days. That is how this would be run in the RW. Thanks in advance for any help! It's a calendar mismatch. USD libor is fixed in London and uses a calendar which joins US and UK holidays. Since May 2nd 2005 was a holiday in the UK, the USD-Libor settlement for April 29th is May 4th, not May 3rd as you get by advancing 2 days on the US calendar. Conversely, the USD-libor fixing date for May 3rd is April 28th, not 29th. When you try to price a swap with that settlement date, the libor instance tries to retrieve the April 28th fixing (which is in the past, so it can't get it off the curve) and gives you the error. Luigi -- Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Luigi Ballabio <luigi.ballabio <at> gmail.com> writes:
> It's a calendar mismatch. USD libor is fixed in London and uses a > calendar which joins US and UK holidays. Makes sense. So I changed my date calculation to this: Calendar calendar = UnitedStates(); Date todaysDate(29, April, 2005); Integer fixingDays = 2; JointCalendar usdgbpCalendar = JointCalendar(UnitedStates(), UnitedKingdom()); Date settlementDate = usdgbpCalendar.advance(todaysDate, fixingDays, Days); settlementDate = usdgbpCalendar.adjust(settlementDate); Then I also changed my rate helpers for deposits and swaps to have the joined calendar: boost::shared_ptr<RateHelper> d1w(new DepositRateHelper( Handle<Quote>(d1wRate), 1*Weeks, fixingDays, usdgbpCalendar, Following, true, depositDayCounter)); and boost::shared_ptr<RateHelper> s2y(new SwapRateHelper( Handle<Quote>(s2yRate), 2*Years, usdgbpCalendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex)); And my code doesn't blow up. One last question, though. When I'm building a new swap to price do I need to change both the fixed and floating calendars or only the floating calendar. Like this: Schedule fwdFixedSchedule(fwdStart, fwdMaturity, Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration::Forward, false); Schedule fwdFloatSchedule(fwdStart, fwdMaturity, Period(floatingLegFrequency), usdgbpCalendar, floatingLegConvention, floatingLegConvention, DateGeneration::Forward, false); It seems that since the standard is for the fixed leg to be unadjusted, I would just use the joined calendar for the floating leg, but I may be confusing conventions. Thanks for your help. I have been flailing around looking at day count conventions and in all the wrong places. Monkey ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Tue, 2010-08-10 at 11:22 +0000, MonkeyMan wrote:
> Luigi Ballabio <luigi.ballabio <at> gmail.com> writes: > And my code doesn't blow up. One last question, though. When I'm building a new > swap to price do I need to change both the fixed and floating calendars or only > the floating calendar. I'd guess only the floating, but as it's conventions I think some swap expert should step in and give us an opinion... Luigi -- When I was a boy of fourteen, my father was so ignorant I could hardly stand to have the old man around. But when I got to be twenty-one, I was astonished at how much the old man had learned in seven years. -- Mark Twain ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Luigi Ballabio <luigi.ballabio <at> gmail.com> writes:
> I think some swap expert should step in and give us an opinion... That would help. I found several confirms floating around the webs and have seen an example of New York for both fixed and floating here: http://www.budget.state.ny.us/investor/bond/esdcConfirms/UBSPersonalIncomeTaxBonds2December222004.pdf and here: http://contracts.onecle.com/mercury-interactive/goldman.swap.2002.11.05.shtml but this one has New York and London for both legs: http://agreements.realdealdocs.com/Swap-Agreement/RE-Interest-Rate-Swap-Confirmation-REVIS-1211548/ ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Both calendars need to be adjusted... I'll give you an example:
For USD swap trades executed on 1/15/10, spot (effective) date is 1/15/10 +2 LDN BD (and the 2nd LDN BD needs to be a NY Federal Reserve business day as well) which turns out to be 1/19/10. For USD swap trades executed 1/14/10, spot date is ALSO 1/19/10, using the same logic. On 1/18/10 (yes you can trade USD swaps in London even if NY is closed) spot date is 1/20/10. On 1/19/10 spot date is 1/21/10. As a rule, the first business day forward needs to be a valid London business day, while the second business day forward needs to be BOTH a London business days AS WELL as a New York Federal Reserve business day. Hope this helps. By the way, since you are trying to build a historical swap curve database, do you mind if I ask where you are getting your input data (for swaps) for the curve? If you use Bloomberg, be very careful, since I have found a lot of problems with their historical swap data. - Mike On Tue, Aug 10, 2010 at 8:07 AM, MonkeyMan <[hidden email]> wrote: > Luigi Ballabio <luigi.ballabio <at> gmail.com> writes: > >> I think some swap expert should step in and give us an opinion... > > That would help. I found several confirms floating around the webs and have seen > an example of New York for both fixed and floating here: > > http://www.budget.state.ny.us/investor/bond/esdcConfirms/UBSPersonalIncomeTaxBonds2December222004.pdf > > and here: > > http://contracts.onecle.com/mercury-interactive/goldman.swap.2002.11.05.shtml > > but this one has New York and London for both legs: > > http://agreements.realdealdocs.com/Swap-Agreement/RE-Interest-Rate-Swap-Confirmation-REVIS-1211548/ > > > > > > > > > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by > > Make an app they can't live without > Enter the BlackBerry Developer Challenge > http://p.sf.net/sfu/RIM-dev2dev > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users > ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Mike DelMedico <mike.delmedico <at> gmail.com> writes:
Thanks for the info. > do you mind if I ask where you are getting your input data (for swaps) > for the curve? For the US I'm using ICAP data provided by Reuters for spot rates. Reuters provides forward rates as well, but the contributors are all mixed together and I found the quality to be kind of spotty. I get the impression that they calc the forward rates using the last update to a consolidated spot rates page. Needless to say, this can cause the forwards to blow up. I haven't tried to use bberg data. Thanks for the heads up. ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Okay, one more follow up about this. What about instances like the following.
Base currency is USD. Eval Date: May 2, 2005 (Good day in US, holiday in UK) Settle Date: May 4, 2005 (Good day in US & UK) Since it is a holiday in the UK, I need to use libor fixings for the previous good day, which is April 29. Luckily I have this data. Now I get this error: 1st iteration: failed at 1st instrument, maturity May 11th, 2005, reference date May 4th, 2005: Missing no-fix1W Actual/360 fixing for April 29th, 2005 I don't really understand why my DepositRateHelper didn't use the correct date in the first place since I passed in the joined calendar. So, I've tried to correct this by adding fixings for the 29th using the addFixing method in IborIndex. I figured I'd need to add a fixing for each of 1w, 2w,...,1y libor rates. Still getting errors about the 1w rate, though. ... Date fixingDate(29, April, 2005); JointCalendar usdgbpCalendar = JointCalendar(UnitedStates(), UnitedKingdom()); ... Rate d1wQuote=0.0306625; ... boost::shared_ptr<RateHelper> d1w(new DepositRateHelper( Handle<Quote>(d1wRate), 1*Weeks, fixingDays, usdgbpCalendar, Following, true, depositDayCounter)); ... boost::shared_ptr<YieldTermStructure> depoFutSwapTermStructure( new PiecewiseYieldCurve<Discount,LogCubic>( settlementDate, depoFutSwapInstruments, termStructureDayCounter, tolerance, mlcns)); depoFutSwapTermStructure->enableExtrapolation(); RelinkableHandle<YieldTermStructure> discountingTermStructure; discountingTermStructure.linkTo(depoFutSwapTermStructure); boost::shared_ptr<IborIndex> w1(new USDLibor(Period(1,Weeks), discountingTermStructure)); w1->addFixing(fixingDate,d1wQuote); I still get the error. I have tried calling w1->update() and discoutingTermStructure->update() hoping that would trigger a recalc. What am I doing wrong? Thanks again guys. ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Wed, 2010-08-11 at 04:20 +0000, MonkeyMan wrote:
> Okay, one more follow up about this. What about instances like the following. > Base currency is USD. > > Eval Date: May 2, 2005 (Good day in US, holiday in UK) > Settle Date: May 4, 2005 (Good day in US & UK) > > Since it is a holiday in the UK, I need to use libor fixings for the previous > good day, which is April 29. Luckily I have this data. Now I get this error: > > 1st iteration: failed at 1st instrument, maturity May 11th, 2005, reference date > May 4th, 2005: Missing no-fix1W Actual/360 fixing for April 29th, 2005 The bootstrap process is not using the fixings on purpose (the no-fix1W tag is a dark hint.) If it used them, the solver inside the bootstrapper couldn't run as modifying the curve node would have no effect. I'm not sure how we can get out of this without modifying some code. To make this case work, you'd have to patch DepositRateHelper::impliedQuote() and have it calculate the deposit rate off the curve instead of using iborIndex_->fixing---or maybe you can patch it so that the fixing date is moved to today. I'm not sure which is the least evil. Luigi -- No, I'm not interested in developing a powerful brain. All I'm after is just a mediocre brain, something like the president of American Telephone and Telegraph Company. -- Alan Turing on the possibilities of a thinking machine, 1943. ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
> To make this case work, you'd have to patch
> DepositRateHelper::impliedQuote() and have it calculate the deposit rate > off the curve instead of using iborIndex_->fixing---or maybe you can > patch it so that the fixing date is moved to today. Hmm. I think it is preferable to change the fixing date. I'll take a look and report back any progress. Thanks. ------------------------------------------------------------------------------ This SF.net Dev2Dev email is sponsored by: Show off your parallel programming skills. Enter the Intel(R) Threading Challenge 2010. http://p.sf.net/sfu/intel-thread-sfd _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |