Hi I have written a program for bootstrapping bond interest rates. The bond price I am getting is 101.99825... when it should be more like 101.999999.....
The inputs to test are Bond Price = 102, ttm = 36, f = 2, face = 100, n = 5.
Heres the program, tried to automate as best as possible.
// ImpliedBondYield.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;
double b_est(double x);
double f_deriv(double y);
double midpoint(double t, double t1, double r1, double t2, double r2);
int _tmain(int argc, _TCHAR* argv[])
{
int B;
cout << "Enter Bond Price: ";
cin >> B;
int ttm;
cout << "Enter ttm: ";
cin >> ttm ;
int f;
cout << "Enter f: ";
cin >> f;
double face;
cout << "Enter face: ";
cin >> face ;
double coupon;
cout << "Enter coupn: ";
cin >> coupon;
vector<double> t_cash_flow;
vector<double> v_cash_flow;
vector<double> disc;
vector<double> rates;
int months_between_cashflows = 12 / f; // Note: integer division
int initial_cashflow_month = ttm % months_between_cashflows;
// Assume no payment if t = 0, go to next cashflow time
if (0 == initial_cashflow_month)
{
initial_cashflow_month = months_between_cashflows;
}
for (int cashflow_month = initial_cashflow_month;
cashflow_month <= ttm;
cashflow_month += months_between_cashflows)
{
t_cash_flow.push_back(static_cast<double>(cashflow_month) / 12.0);
v_cash_flow.push_back(coupon / static_cast<double>(f) +
static_cast<double>(cashflow_month / ttm) * face);
}
double x=0.05;
/* for (unsigned int i = 2; i < t_cash_flow.size(); i++)
{
rates.push_back(static_cast<double>(midpoint(t_cash_flow[i], 1, 0.04937, 3, x)));
}*/
for(unsigned int i = 0; i < t_cash_flow.size(); i++)
{
cout << "t_cash_flow[" << i << "] = " << t_cash_flow[i] << endl;
}
for(unsigned int i = 0; i < v_cash_flow.size(); i++)
{
cout << "v_cash_flow[" << i << "] = " << v_cash_flow[i] << endl;
}
/*for(unsigned int i = 0; i < v_cash_flow.size(); i++)
{
cout << "rates[" << i << "] = " << rates[i] << endl;
}*/
double best;
double fderiv;
double tol = 10E-6;
double x0 = 0.05;
double xnew = x0;
double xold = x0 - 1.0;
while(abs(xnew - xold) > tol)
{
best = 0;
fderiv = 0;
rates.clear();
xold = xnew;
rates.push_back(2 * log(100/97.5));
rates.push_back(log(102.5/(100 - 2.5*exp(-(0.5*rates[0])))));
for (unsigned int i = 2; i < t_cash_flow.size(); i++)
{
rates.push_back(static_cast<double>(midpoint(t_cash_flow[i], 1, rates[1], 3, xold)));
}
for(unsigned int i = 0; i < v_cash_flow.size(); i++)
{
cout << "rates[" << i << "] = " << rates[i] << endl;
}
for(unsigned int i=0; i<v_cash_flow.size(); ++i)
{
best += ( v_cash_flow[i]*exp(-rates[i]*t_cash_flow[i]) );
fderiv = fderiv + t_cash_flow[i]*v_cash_flow[i]*exp(-rates[i]*t_cash_flow[i]);
}
xnew = xold + ((best - B)/fderiv);
cout << setprecision (12) << "xnew: " << xnew << " xold: " << xold << endl;
}
for(unsigned int i = 0; i < v_cash_flow.size(); i++)
{
cout << "rates[" << i << "] = " << rates[i] << endl;
}
for(unsigned int i=0; i<v_cash_flow.size(); ++i)
{
disc.push_back(static_cast<double>(exp(-t_cash_flow[i]*rates[i])));
Bp = Bp + v_cash_flow[i]*disc[i];
}
cout << setprecision (16) << "Implied Yield= " << xnew << endl;
cout << setprecision (16) << "Bond Price= " << Bp << endl;
cout << setprecision (16) << "error= " << B - Bp << endl;
system ("pause");
return 0;
}
double midpoint(double t, double t1, double r1, double t2, double r2)
{
double func;
func = ((t - t1)/(t2 - t1))*r2 + ((t2 - t)/(t2 - t1))*r1;
return func;
}
Any clues why its not meeting the tol of 10E-6.