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(); } } ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Peter,
as for the approach, I'll let the real quants answer :) Regarding the code: On Tue, 2009-11-24 at 21:09 +0100, Peter Toke Heden Ahlgren wrote: > 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? Yes, that's the fixing of last coupon. As you figured out, you'll have to use the addFixing method. The date you'll have to pass is the one in the error message (October 16th, 2009.) The index is the 1-year Euribor, and the value is its fixing at that date. You can do this manually after you see the error, or you can do this beforehand by writing something like the following (uncommented for lack of time, post back to the list if you can't figure out something): const Leg& l = floatingRateBond.cashflows(); Leg::const_iterator i = CashFlows::nextCashFlow(l); if (i != l.end()) { boost::shared_ptr<FloatingRateCoupon> coupon = boost::dynamic_pointer_cast<FloatingRateCoupon>(*i); Date fixingDate = coupon->fixingDate(); Rate r = ... (you'll have to retrieve the rate for fixingDate someway) coupon->index()->addFixing(fixingDate, r); } Luigi P.S. I haven't looked hard at your code, so I won't comment on it now. The one thing that jumped at me was the switch on freq. You can replace the whole thing with: Frequency freq = Frequency((int) mxGetScalar(prhs[4])); Period iPer = Period(freq); Period iPerLibor = iPer; -- Do the right thing. It will gratify some people and astonish the rest. -- Mark Twain ------------------------------------------------------------------------------ Join us December 9, 2009 for the Red Hat Virtual Experience, a free event focused on virtualization and cloud computing. Attend in-depth sessions from your desk. Your couch. Anywhere. http://p.sf.net/sfu/redhat-sfdev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |