Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

bond.cpp

Go to the documentation of this file.
00001 #include ".\bond.h"
00002 
00003 cashflow::cashflow(valarray<Date> dates, valarray<Real> cashflows)
00004 :       _dates(dates),
00005         _cashflows(cashflows)
00006 {
00007 }
00008 
00009 valarray<Date> cashflow::getDates(){
00010         return _dates;
00011 }
00012 
00013 valarray<Real>  cashflow::getCashflows(){
00014         return _cashflows;
00015 }
00016 
00017 
00018 bond::bond(Date issue, Date maturity, Date firstcoupondate, Real coupon, Frequency freq, Real faceamount,DayCountConvention daycount, yieldCurve yc)
00019 :       _issue(issue),
00020         _maturity(maturity),
00021         _firstcoupondate(firstcoupondate),
00022         _coupon(coupon),
00023         _freq(freq),
00024         _faceamount(faceamount),
00025         _daycount(daycount),
00026         _yc(yc)
00027 {
00028 }
00029 
00030 
00031 cashflow bond::getCashflow(){
00032         Real timetomaturity = _firstcoupondate.dayCount(_maturity, _daycount);
00033         Real numberofcashflow;
00034         Real coupon;
00035 
00036         Integer nbofmonth;
00037 
00038         switch (_freq) {
00039                 case NoFrequency:
00040                         numberofcashflow = 1.0;
00041                         coupon = 0;
00042                         nbofmonth = 0;
00043                         break;
00044                 case Once:
00045                         numberofcashflow = 1.0;
00046                         coupon = 0;
00047                         nbofmonth = 0;
00048                         break;
00049                 case Annual:
00050                         numberofcashflow = timetomaturity + 1;
00051                         coupon = _coupon;
00052                         nbofmonth = 12;
00053                         break;
00054                 case Semiannual:
00055                         numberofcashflow = 2.0*timetomaturity + 1;
00056                         coupon = _coupon/2.0;
00057                         nbofmonth = 6;
00058                         break;
00059                 case EveryFourthMonth:
00060                         numberofcashflow = 3.0*timetomaturity + 1;
00061                         coupon = _coupon/3.0;
00062                         nbofmonth = 4;
00063                         break;
00064                 case Quarterly:
00065                         numberofcashflow = 4.0*timetomaturity + 1;
00066                         coupon = _coupon/4.0;
00067                         nbofmonth = 3;
00068                         break;
00069                 case Bimonthly:
00070                         numberofcashflow = 6.0*timetomaturity + 1;
00071                         coupon = _coupon/6.0;
00072                         nbofmonth = 2;
00073                         break;
00074                 case Monthly:
00075                         numberofcashflow = 12.0*timetomaturity + 1;
00076                         coupon = _coupon/12.0;
00077                         nbofmonth = 1;
00078                         break;
00079                 default:
00080                         numberofcashflow = 1.0;
00081                         coupon = _coupon;
00082                         nbofmonth = 0;
00083                         break;
00084         }
00085 
00086 
00087 
00088         
00089         Date d(_firstcoupondate);
00090         Natural numberofCF = (int) (numberofcashflow + 0.1);
00091 
00092         valarray<Date> dates(numberofCF);
00093         valarray<Real> cashflows(numberofCF);
00094         
00095         dates[0]=d;
00096         Date dTest;
00097         cashflows[0] = _faceamount*coupon;
00098         Natural i;
00099         for(i=1;i<numberofCF;i++)
00100         {
00101                 dTest=d.plusMonths(i*nbofmonth);
00102                 dTest.applyConvention(Following);
00103                 dates[i]=dTest;
00104                 cashflows[i] = _faceamount*coupon;
00105         }
00106 
00107         if (_freq==Once)
00108                 cashflows[0] = _faceamount;
00109         else
00110                 cashflows[numberofCF-1] += _faceamount;
00111 
00112         cashflow CF(dates, cashflows);
00113         return CF;
00114 }
00115         
00116 Real bond::fairvalue(Date today){
00117 
00118         Real PV = quotedPrice(today);
00119         Real accruedinterest;
00120 
00121         if(today<=_issue ||today>=_maturity)
00122                 accruedinterest = 0;
00123         else
00124         {
00125                 cashflow CF = getCashflow();
00126                 valarray<Date> dates = CF.getDates();
00127                 valarray<Real> cashflows = CF.getCashflows();
00128 
00129                 Natural i=0;
00130                 while((dates[i]<today) && (i<dates.size()))
00131                         i++;
00132         
00133                 Date interestaccrualdate;
00134                 if (today<_firstcoupondate)
00135                         interestaccrualdate = _issue;
00136                 else
00137                         interestaccrualdate = dates[i-1];
00138 
00139                 Real numberofdays, numberofdays2, numberofcoupon;
00140 
00141 
00142                 switch(_freq){
00143                         case NoFrequency:
00144                                 numberofcoupon = 1.0;//to avoid division by zero
00145                                 break;
00146                         case Once:
00147                                 numberofcoupon = 1.0;
00148                                 break;
00149                         case Annual:
00150                                 numberofcoupon = 1.0;
00151                                 break;
00152                         case Semiannual:
00153                                 numberofcoupon = 2.0;
00154                                 break;
00155                         case EveryFourthMonth:
00156                                 numberofcoupon = 3.0;
00157                                 break;
00158                         case Quarterly:
00159                                 numberofcoupon = 4.0;
00160                                 break;
00161                         case Bimonthly:
00162                                 numberofcoupon = 6.0;
00163                                 break;
00164                         case Monthly:
00165                                 numberofcoupon = 12.0;
00166                                 break;
00167                         default:
00168                                 numberofcoupon = 1.0;
00169                                 break;
00170                 }
00171 
00172 
00173                 switch (_daycount) {
00174                         case ACT_365:
00175                                 numberofdays = TN_REAL(today.serialNumber()-interestaccrualdate.serialNumber());
00176                                 numberofdays2 = 365.0/numberofcoupon;
00177                                 break;
00178                         case ACT_360:
00179                                 numberofdays = TN_REAL(today.serialNumber()-interestaccrualdate.serialNumber());
00180                                 numberofdays2 = 360.0/numberofcoupon;
00181                                 break;
00182                         case Day30_365:
00183                                 numberofdays = TN_REAL(today.dayOfMonth()+30-interestaccrualdate.dayOfMonth()+30*(12*(today.year()-interestaccrualdate.year())+today.month()-interestaccrualdate.month()));
00184                                 numberofdays2 = 365.0/numberofcoupon;
00185                                 break;
00186                         case Day30_360:
00187                                 numberofdays = TN_REAL(today.dayOfMonth()+30-interestaccrualdate.dayOfMonth()+30*(12*(today.year()-interestaccrualdate.year())+today.month()-interestaccrualdate.month()));
00188                                 numberofdays2 = 360.0/numberofcoupon;
00189                                 break;
00190                         default:
00191                                 numberofdays = TN_REAL(today.serialNumber()-dates[i].serialNumber()); 
00192                                 numberofdays2 = 365.0/numberofcoupon;
00193                 }
00194                 accruedinterest = numberofdays/numberofdays2*_coupon/numberofcoupon*_faceamount;
00195         }
00196 
00197         return PV + accruedinterest;
00198 }
00199 
00200 Real bond::quotedPrice(Date today){
00201         
00202         cashflow CF = getCashflow();
00203         valarray<Date> dates = CF.getDates();
00204         valarray<Real> cashflows = CF.getCashflows();
00205 
00206         Natural i=0;
00207         while((dates[i]<today) && (i<dates.size()))
00208                 i++;
00209 
00210         Real PV = 0;
00211         if (i==dates.size()) return 0;
00212         else if (i!=dates.size()-1){
00213                 Natural j;
00214                 Real timetonextCF;
00215                 for(j=i;j<dates.size();j++){
00216                         timetonextCF = today.dayCount(dates[j], _daycount);
00217                         PV += cashflows[j]*_yc.discountFactor(timetonextCF);
00218                 }
00219         }
00220 
00221 
00222         return PV;
00223 
00224 }
00225 
00226 Real bond::duration(Date today){
00227         Real yield = yieldToMaturity(today);//, _yc);
00228         cashflow CF = getCashflow();
00229         valarray<Date> dates = CF.getDates();
00230         valarray<Real> cashflows = CF.getCashflows();
00231 
00232         Natural i=0;
00233         while((dates[i]<today) && (i<dates.size()))
00234                 i++;
00235         if (i==dates.size()) return 0;
00236         Real result = 0;
00237         Real PV = 0;
00238         Real timetonextCF;
00239         Natural j;
00240         for(j=i;j<dates.size();j++){
00241                         timetonextCF = today.dayCount(dates[j], _daycount);
00242                         result += cashflows[j]*exp(-yield*timetonextCF)*timetonextCF;
00243                         PV += cashflows[j]*exp(-yield*timetonextCF);
00244         }
00245 
00246         result /= PV;
00247         return result;
00248 
00249 }
00250 
00251 Real bond::convexity(Date today){
00252         Real yield = yieldToMaturity(today);//, _yc);
00253         cashflow CF = getCashflow();
00254         valarray<Date> dates = CF.getDates();
00255         valarray<Real> cashflows = CF.getCashflows();
00256 
00257         Natural i=0;
00258         while((dates[i]<today) && (i<dates.size()))
00259                 i++;
00260         if (i==dates.size()) return 0;
00261         Real result = 0;
00262         Real PV = 0;
00263         Real timetonextCF;
00264         Natural j;
00265         for(j=i;j<dates.size();j++){
00266                         timetonextCF = today.dayCount(dates[j], _daycount);
00267                         result += cashflows[j]*exp(-yield*timetonextCF)*timetonextCF*timetonextCF;
00268                         PV += cashflows[j]*exp(-yield*timetonextCF);
00269         }
00270 
00271         result /= PV;
00272         return result;
00273 
00274 }
00275 
00276 Real bond::yieldToMaturity(Date today){
00277         Real price = fairvalue(today);//, _yc);
00278         Real yield = 0.05;
00279         Real deriv_price, yield_price;
00280 
00281 
00282         cashflow CF = getCashflow();
00283         valarray<Date> dates = CF.getDates();
00284         valarray<Real> cashflows = CF.getCashflows();
00285 
00286         Natural i=0;
00287         while((dates[i]<today) && (i<dates.size()))
00288                 i++;
00289         if (i==dates.size()) return 0;
00290         
00291         Real timetonextCF;
00292         Natural k,j;
00293         for(k=0;k<100;k++){
00294                 deriv_price = 0;
00295                 yield_price = 0;
00296                 for(j=i;j<dates.size();j++){
00297                         timetonextCF = today.dayCount(dates[j], _daycount);
00298                         yield_price += cashflows[j]*exp(-yield*timetonextCF);
00299                         deriv_price += -timetonextCF*cashflows[j]*exp(-yield*timetonextCF);
00300                 }
00301                 yield += (price - yield_price)/deriv_price;
00302         }
00303         return yield;
00304 
00305 }
00306 
00307 treasurybond::treasurybond(Date issue, Date maturity, Date firstcoupondate, Real coupon, Frequency freq, Real faceamount, DayCountConvention daycount, yieldCurve yc)
00308 :       bond(issue, maturity, firstcoupondate, coupon, freq, faceamount, daycount, yc)
00309 {
00310 }
00311 
00312 treasurybond::treasurybond(Date issue, Date maturity, Date firstcoupondate, Real coupon, yieldCurve yc)
00313 :       bond(issue, maturity, firstcoupondate, coupon, Semiannual, 100.0, ACT_360, yc)
00314 {
00315 }
00316 
00317 treasurybond::treasurybond(Date issue, Date maturity, Real faceamount, DayCountConvention daycount, yieldCurve yc)
00318 :       bond(issue, maturity, maturity, 0.0, Once, faceamount, daycount, yc)
00319 {
00320 }       
00321 
00322 treasurybond treasurybond::shiftedbond(Real shift){
00323         yieldCurve shiftedyc(_yc.shiftZCBRateCurve(shift));
00324         treasurybond shiftedtbond(_issue, _maturity, _firstcoupondate, _coupon, _freq, _faceamount, _daycount, shiftedyc);
00325         return shiftedtbond;
00326 }
00327 
00328 Real treasurybond::rho(Date today){
00329         treasurybond tb = shiftedbond(0.001);
00330         Real Rho = (tb.fairvalue(today) - fairvalue(today))/0.001;
00331 
00332         return Rho;
00333 }
00334 
00335 
00336 riskybond::riskybond(Date issue, Date maturity, Date firstcoupondate, Real coupon, Frequency freq, Real faceamount,DayCountConvention daycount, yieldCurve yc,  creditCurve cc)
00337 :       bond(issue, maturity, firstcoupondate, coupon, freq, faceamount, daycount, yc),
00338         _cc(cc)
00339 {
00340 }
00341 
00342 riskybond::riskybond(Date issue, Date maturity, Real faceamount, DayCountConvention daycount, yieldCurve yc,  creditCurve cc)
00343 :       bond(issue, maturity, maturity, 0.0, Once, faceamount, daycount, yc),
00344         _cc(cc)
00345 {
00346 }
00347 
00348 Real riskybond::quotedPrice(Date today){
00349 
00350         cashflow CF = getCashflow();
00351         valarray<Date> dates = CF.getDates();
00352         valarray<Real> cashflows = CF.getCashflows();
00353 
00354         Natural i=0;
00355         while((dates[i]<today) && (i<dates.size()))
00356                 i++;
00357 
00358         Real PV = 0;
00359         if (i==dates.size()) return 0;
00360         else if (i!=dates.size()-1){
00361                 Natural j;
00362                 Real timetonextCF;
00363                 for(j=i+1;j<dates.size();j++){
00364                         timetonextCF = today.dayCount(dates[j], _daycount);
00365                         PV += cashflows[j]*_cc.riskyDiscountFactor(timetonextCF);
00366                 }
00367         }
00368 
00369 
00370         return PV;
00371 
00372 }
00373 
00374 riskybond riskybond::shiftedbond(Real shift){
00375         yieldCurve shiftedyc(_yc.shiftZCBRateCurve(shift));
00376         riskybond shiftedtbond(_issue, _maturity, _firstcoupondate, _coupon, _freq, _faceamount, _daycount, shiftedyc, _cc);
00377         return shiftedtbond;
00378 }
00379 
00380 Real riskybond::rho(Date today){
00381         riskybond tb = shiftedbond(0.001);
00382         Real Rho = (tb.fairvalue(today) - fairvalue(today))/0.001;
00383 
00384         return Rho;
00385 }

Note: Generated nightly - reload for latest version
Generated on Thu Dec 22 23:12:35 2005 for terreneuve by doxygen 1.3.6