Constructing Term Structure from yield Curve C++
We can obtain from yield curve the term structure using Bootstrap method. Let's see how we can do it. It is a nice and easy program. I did some comments in the program body, so I will ommit the description here :)
# Main function
*********************************************************************************************
#include<iostream> #include"levelbond.h" #include"Cal.h" #include<vector> using namespace std; int main() { //construct vector and put the given levelbond into the vector; vector<levelbond> bondseries; vector<levelbond>::iterator bondseries_iter = bondseries.begin(); levelbond six_month(4, 100, 0.5); bondseries.push_back(six_month); levelbond one_year(5, 100, 1); bondseries.push_back(one_year); levelbond two_year(7, 100, 2); bondseries.push_back(two_year); levelbond three_year(9, 100, 3); bondseries.push_back(three_year); levelbond five_year(9.25, 100, 5); bondseries.push_back(five_year); levelbond seven_year(9.5, 100, 7); bondseries.push_back(seven_year); levelbond ten_year(10, 100, 10); bondseries.push_back(ten_year); // To construct a complete term of levelbond, which is more easy to compute! for (bondseries_iter = bondseries.begin(); bondseries_iter != bondseries.end()-1; bondseries_iter++) { double m = ((*(bondseries_iter + 1)).get_maturity() - (*(bondseries_iter)).get_maturity()) / 0.5 - 1; if (m > 0) { double insert_coupon = (*(bondseries_iter)).get_rawcoupon() + ((*(bondseries_iter + 1)).get_rawcoupon() - (*(bondseries_iter)).get_rawcoupon()) / (m + 1); //calculate the coupon of the inserted bond; double insert_maturity = (*bondseries_iter).get_maturity() + 0.5;// every inserted bond's maturity will be 0.5year+last one's maturity e.g 1-->1.5 and so on; levelbond insertbond(insert_coupon, 100, insert_maturity);//create the inserted bond bondseries.insert((bondseries_iter + 1), insertbond); // Inserted!!!! bondseries_iter = bondseries.begin();//NOTE: Why I do this? since when I add an element into the vector, the previous iterator becomes useless, it will point to strange things, so basically, I am assigning a new iterator for this "relative new "vector! } //now we have a new vector consists levelbond with iterval of 6 months!!!!!! }
cal calculator(bondseries); calculator.spot_rate(); //cout<<calculator.get_finalresult()[2]; return 1; }
#2 Level Bond
**********************************************************************************************************
levelbond::levelbond(double c, double p, double m){ coupon = c / 100 / frequency; rawcoupon=c; paymentnum = m*frequency; price = p*10; maturity = m; } double levelbond::expression_value(double ytm_tester) { double bondvalue = 0; double den = 1.0 + ytm_tester / frequency; for (int i = 0; i <paymentnum; i++) { bondvalue += coupon*facevalue / pow(den, i + 1); } bondvalue += facevalue / pow(den, paymentnum); double expression = (bondvalue - price); return expression; } double levelbond::derivative(double root_tester) { double expression_increase = expression_value(root_tester + mini) - expression_value(root_tester); double root_increase = mini; double deriv = expression_increase / root_increase; return deriv; } int levelbond::check(double a, double b){ double m = abs(a - b); if (m <= epsi) return 1; else return 0;
} double levelbond::mainexpression_value(double previous_value, double ytm_tester) { double value = 0; double den = 1.0 + ytm_tester / frequency; value = previous_value + (facevalue + coupon*facevalue) / pow(den, paymentnum);// don't use coupon but coupon*facevalue!!!!! double expression = (value - price); return expression; } double levelbond::mainderivative(double previous_value, double root_tester) {
double expression_increase = mainexpression_value(previous_value, root_tester + mini) - mainexpression_value(previous_value, root_tester); double root_increase = mini; double deriv = expression_increase / root_increase; return deriv;
} void levelbond::vtmcalculator() { while (1) { ytm = ytm0 - expression_value(ytm0) / derivative(ytm0); if (check(ytm, ytm0)) break; ytm0 = ytm; } } void levelbond::calculator(double previous_value){
while (1) { spot_rate = r0 - mainexpression_value(previous_value,r0) / mainderivative(previous_value,r0); if (check(spot_rate, r0)) break; r0 = spot_rate; }
}
double levelbond::get_coupon(){ return coupon;} double levelbond::get_maturity(){ return maturity; } double levelbond::get_price(){ return price; }
#3 Calculaltion Class
**********************************************************************************************
cal::cal(vector<levelbond> input){ levelterm = input; } void cal::spot_rate(){ vector<levelbond>::iterator iter = levelterm.begin(); (*iter).vtmcalculator(); spot_termstructure.push_back((*iter).get_ytm());//get the first spot double p = 1 / (1 + (*iter).get_ytm() / 2); iter++;// point to following terms; // cout << p<<endl; for (; iter!=levelterm.end(); iter++) { (*iter).calculator(((*iter).get_coupon())*1000*p);// 调用本levelbond的实例的计算函数,输入参数为前面的累计金额previous_value spot_termstructure.push_back((*iter).get_spot()); double den = 1 + (*iter).get_spot() / 2; p+=1/pow(den, (*iter).get_paymentnum()); cout << "spot rate:" << (*iter).get_spot() << endl; //" The discount factor " << pow((1 / (1 + (*iter).get_spot())), (*iter).get_paymentnum()) << endl; } } vector<double>cal::get_finalresult(){ return spot_termstructure; };