Thursday, February 7, 2013

C++ - Coding - Deterministic Coupon Bond Pricer

Question You must price a coupon bond with a principle of $100 maturing in 2 years time. Two coupons of $5 are paid at the end of year one and year two, and the continuous compound interest rate is a constant 10%. Extend your code to price a coupon bond with any specification.

The aim of this is to create a step by step approach to coding up a coupon bond so that it can accept any number of coupons, interest rate, maturity, time, principle or coupon value. This is not as easy as it sound and we need to consider what the effect of letting different parameters vary can have on our code. First we start by declaring the variables and parameters in the problem. Differentiating between the two is not essential here but for more advanced coding this difference does become important. In this problem only time is variable (since we assume interest rates are constant). We are going to specify the number of coupons paid out per year to be an integer or in other words a number that we can count. The initial program looks like

#include <cmath>
#include <iostream>
using namespace std;

int main()
{
  // variables 
  double t=0;
  // parameters 
  double maturity=2.,principle=100.,coupon=5.,interestRate=0.1;
  // counting parameters
  int couponsPerYear=1;
  return 0;
}

Next we add in something to calculate the bond value manually for the given problem above, trying to use the variables and parameters we have declared as much as possible.

  // store the value of the bond
  double bondValue=0.;
  // add in coupons
  bondValue = bondValue + coupon*exp(-interestRate*(1.-t));
  bondValue = bondValue + coupon*exp(-interestRate*(2.-t));
  // finally add principle
  bondValue = bondValue + principle*exp(-interestRate*(maturity-t));
  cout << " The value of the bond is " << bondValue <<endl;

Now the only place here where we have had to do something manually is for the coupon payments. Given the problem as outlined we have to add in just two coupons so doing it manually is not a problem. However if we where to specify a bond with 4 coupon payments per year over 25 years then this would become a bit tedious, so obviously we should use a loop instead. This infers that we should add an extra local variable to count how many coupons there are in total, as well as a time variable “ti” to keep track of when coupons are paid. The coupons run from i = 1 up to and including the total number assuming that t = 0.

  int totalNumberCoupons=maturity*couponsPerYear;
  for(int i=1;i<=totalNumberCoupons;i++)
  {
    double ti=double(i)/double(couponsPerYear);
    bondValue = bondValue + coupon*exp(-interestRate*(ti-t));
  }

Now we introduce a variable “couponStart” to signify the index of the first coupon to be paid. We calculate this index as

 int startCoupon=floor(t*couponsPerYear) + 1;

Here we are assuming that coupons are paid at the end of a year, rather than at the start of the next, which means that we can find the time of the next coupon by taking the “floor” of “t” multiplied by “couponsPerYear” and then adding 1. We use the floor function rather than a straight conversion to “int” to maintain compatibility if t is negative. The result is that ti is always strictly greater than t, so if t=ti we assume the coupon has already been paid and therefore no coupons are paid at t=0 even if it counts as a coupon date. To get the loop to run over only the appropriate coupon dates initialise i at “couponStart” rather than 1. At this stage your code should look like

#include <cmath>
#include <iostream>
using namespace std;

int main()
{
  // variables  
  double t=0.;
  // parameters
  double maturity=2.,principle=100.,coupon=5.,interestRate=0.1;
  // counting parameters
  int couponsPerYear=1;
  // store the value of the bond
  double bondValue=0.;
  // add in coupons
  int startCoupon=floor(t*couponsPerYear) + 1;
  int totalNumberCoupons=maturity*couponsPerYear;
  for(int i=startCoupon;i<=totalNumberCoupons;i++)
  {
    double ti=double(i)/double(couponsPerYear);
    bondValue = bondValue + coupon*exp(-interestRate*(ti-t));
  }
  // finally add principle
  bondValue = bondValue + principle*exp(-interestRate*(maturity-t));
  cout << " The value of the bond is " << bondValue <<endl;
  return 0;
}

To be consistent you may wish to specify a condition on maturity that the principle is only paid if t T. In order to complete the task, you should create a function using the definition

double couponBondPrice(double t,double maturity,double principle,double coupon,double interestRate,int couponsPerYear)

You can copy/paste the code from main into the function, deleting the declarations for all the variables and parameters passed in as arguments and then return “bondValue”. The algorithm should then be thoroughly tested using different parameters and checking cases such a negative values of parameters etc. The final code and algorithm looks like

#include <cmath>
#include <iostream>
using namespace std;

double couponBondPrice(double t,double maturity,double principle,double coupon,double interestRate,int couponsPerYear)
{
  // store the value of the bond
  double bondValue=0.;
  // add in coupons
  int startCoupon=floor(t*couponsPerYear) + 1;
  int totalNumberCoupons=maturity*couponsPerYear;
  for(int i=startCoupon;i<=totalNumberCoupons;i++)
  {
    double ti=double(i)/double(couponsPerYear);
    bondValue = bondValue + coupon*exp(-interestRate*(ti-t));
  }
  // finally add principle
  if(t<=maturity)
    bondValue = bondValue + principle*exp(-interestRate*(maturity-t));
  return bondValue;
}

int main()
{
  // output bond price  
  cout << " The value of the bond is " << couponBondPrice(0.,2.,100.,5.,0.1,1) <<endl;
  return 0;
}

No comments:

Post a Comment