Posted by
MonkeyMan-3 on
URL: http://quantlib.414.s1.nabble.com/Missing-USDLibor6M-Actual-360-fixing-tp7050p7052.html
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