Login  Register

Floating rate bond. How to find fixing?

Posted by Peter Toke Heden Ahlgren on Nov 24, 2009; 8:09pm
URL: http://quantlib.414.s1.nabble.com/Floating-rate-bond-How-to-find-fixing-tp8387.html

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