Dear QuantLib users
I am sorry for this
financial newbie question but I hope you can help me out! Inspired by the Bonds
example and the bonds file in the test suite, I am trying to price a plain
floating rate bond. I have a euro swap zero coup curve that I use as argument along
with the specs for the bond. From the bonds test suite file I call this “plain”
since I use the same curve for forecasting and discounting.
First of all I am uncertain
about the validity of this approach, especially the step below where I use the
euro swap zero coupon curve to construct a euribor index. It seems to me that
one can only get around constructing a floating rate bond with some Ibor Index…
Second, I get with the
present code an error saying: What() is:Missing Euribor1Y Actual/360 fixing for
October 16th, 2009. I guess some how this is related to the present coupon, but
being a bond newbie I am not sure. Now, should I expect this error and how do I
come around. I have found the ->addFixing, but how can I know what date QL
will be missing? And what rate should I use? The 1 Year Euro Swap Zero Coup at
that date?
I have pasted the code
below; since I am compiling this for Matlab, some of the code below is not
purely intended for QL. In comments I have written the value of the different
variables after the have been constructed. The function is intended for pricing
a scenario of spreads and zero coupons I get from Matlab, that is the reason
for the loop in the end.
I would of course also be
grateful for any comments on my QL coding, since I am very new to this incredible
library and its “coding principles”.
Thank you all very much in
advance.
Best regards, Peter
#include <mex.h>
#include <ql/quantlib.hpp>
#include <iostream>
#include <iomanip>
#include <asu_matlab_functions.h>
#include <sstream>
using namespace QuantLib;
void mexFunction( int nlhs, mxArray *plhs[], int
nrhs, const mxArray *prhs[])
{
Calendar
calendar = TARGET();
Date
today((long int)mxGetScalar(prhs[0])-693960);
today
= calendar.adjust(today); // 40142
Settings::instance().evaluationDate()
= today;
Natural
settlementDays = (Natural)mxGetScalar(prhs[1]); // 3
Date
settlementDate = calendar.advance(today,settlementDays,Days); // 40147
Natural
fixingDays = 3;
Date
issueDate((long int)mxGetScalar(prhs[2])-693960);
issueDate
= calendar.adjust(issueDate); // 39742
Date
maturityDate((long int)mxGetScalar(prhs[3])-693960);
maturityDate
= calendar.adjust(maturityDate); // 41933
int freq = (int)
mxGetScalar(prhs[4]);
Period
iPer;
Period
iPerLibor;
switch (freq)
{
case 1 :
iPer
= Period(Annual);
iPerLibor
= Period(1,Years);
break;
case 2 :
iPer
= Period(Semiannual);
iPerLibor
= Period(6,Months);
break;
case 3 :
iPer
= Period(EveryFourthMonth);
iPerLibor
= Period(4,Months);
break;
case 4 :
iPer
= Period(Quarterly);
iPerLibor
= Period(3,Months);
break;
case 6 :
iPer
= Period(Bimonthly);
iPerLibor
= Period(2,Months);
break;
case 12 :
iPer
= Period(Monthly);
iPerLibor
= Period(1,Months);
break;
default :
mexErrMsgIdAndTxt("ASUToolbox:floatingbond","Frequency should be either 1 (annual), 2
(semi-annual), 3 (every fourth month), 4 (quarterly), 6 (bimonthly) or 12
(monthly).");
}
//
iPer 1 Years
//
iPerLibor 1 Years
mwSize
numberOfCurvePoints = mxGetNumberOfElements(prhs[5]);
mwSize
curve_rows = mxGetM(prhs[6]);
mwSize
curve_cols = mxGetN(prhs[6]);
if (numberOfCurvePoints!=curve_cols)
mexErrMsgIdAndTxt("ASUToolbox:floatingbond","Number of curvepoints and values must be the
same.");
mwSize
numberOfSpreads = mxGetNumberOfElements(prhs[7]);
double *iSpreads = mxGetPr(prhs[6]);
if (numberOfSpreads!=curve_rows)
mexErrMsgIdAndTxt("ASUToolbox:floatingbond","Number of curvevalues and spreads must be the
same.");
double *CurvePoints = mxGetPr(prhs[5]);
std::vector<Period>
iPeriods;
for (mwSize i=0; i<numberOfCurvePoints; i++)
{
if (CurvePoints[i]<1) iPeriods.push_back(((int) (CurvePoints[i]*12))*Months);
else iPeriods.push_back(((int)
CurvePoints[i])*Years);
}
//
iPeriods 3 Months, 6 Months, 1 Years, 2 Years, 3 Years, 5 Years, 7 Years, 10
Years, 20 Years, 30 // Years
double tolerance = 1.0e-15;
DayCounter
zcBondsDayCounter = Actual365Fixed();
std::vector<boost::shared_ptr<SimpleQuote>
> iTheQuotes;
std::vector<boost::shared_ptr<RateHelper>
> iTheCurve;
for (mwSize j=0; j<numberOfCurvePoints; j++)
{
boost::shared_ptr<SimpleQuote>
iRate(new SimpleQuote((Rate) 0.0));
iTheQuotes.push_back(iRate);
boost::shared_ptr<RateHelper>
iPoint(
new DepositRateHelper(
Handle<Quote>(iRate),
iPeriods[j],
fixingDays,
calendar,
ModifiedFollowing,
true,
zcBondsDayCounter));
iTheCurve.push_back(iPoint);
}
DayCounter
termStructureDayCounter = ActualActual(ActualActual::ISDA);
boost::shared_ptr<YieldTermStructure>
swapTermStructure(
new PiecewiseYieldCurve<Discount,LogLinear>(
settlementDate,
iTheCurve,
termStructureDayCounter,
tolerance));
RelinkableHandle<YieldTermStructure>
discountingTermStructure;
RelinkableHandle<YieldTermStructure>
forecastingTermStructure;
discountingTermStructure.linkTo(swapTermStructure);
forecastingTermStructure.linkTo(swapTermStructure);
boost::shared_ptr<IborIndex>
index(new Euribor(iPerLibor,
forecastingTermStructure));
//index->addFixing(Date(16, October, 2009),0.02);
Schedule
floatingBondSchedule(issueDate,
maturityDate,
iPer,
Germany(Germany::Settlement),
Unadjusted,
Unadjusted, DateGeneration::Backward, false);
FloatingRateBond
floatingRateBond(
settlementDays,
Real(100.0),
floatingBondSchedule,
index,
Actual360(),
ModifiedFollowing,
fixingDays,
// Gearings
std::vector<Real>(1, 1.0),
// Spreads
std::vector<Rate>(1, 0.0),
// Caps
std::vector<Rate>(),
// Floors
std::vector<Rate>(),
// Fixing in arrears
false,
Real(100.0),
Date());
boost::shared_ptr<PricingEngine>
bondEngine(
new DiscountingBondEngine(discountingTermStructure));
floatingRateBond.setPricingEngine(bondEngine);
boost::shared_ptr<IborCouponPricer>
pricer(
new
BlackIborCouponPricer(Handle<OptionletVolatilityStructure>()));
setCouponPricer(floatingRateBond.cashflows(),pricer);
plhs[0]
= mxCreateDoubleMatrix(curve_rows,1,mxREAL);
double *dirtyMatrix =
mxGetPr(plhs[0]);
for (mwSize i=0; i<curve_rows; i++)
{
for (mwSize j=0; j<numberOfCurvePoints; j++)
{
iTheQuotes[j]->setValue((Rate)CurveValues[i+j*curve_rows]);
}
//
The curve now has the following values:
//
0.00726362845472265
// 0.0100644668047577
// 0.0120480471730201
// 0.0171903849135268
// 0.0215856363845785
// 0.0278534962670635
// 0.0320699648771060
// 0.0361526048810217
// 0.0419715341115639
// 0.0394774761552008
dirtyMatrix[i]
= floatingRateBond.dirtyPrice();
}
}
Free forum by Nabble | Disable Popup Ads | Edit this page |