Floating rate bond. How to find fixing?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Floating rate bond. How to find fixing?

Peter Toke Heden Ahlgren

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
Reply | Threaded
Open this post in threaded view
|

Re: Floating rate bond. How to find fixing?

Luigi Ballabio
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