Question: 2.1 Bond class, fair value, duration & yield Let us write a bond class to perform various calculations relevant for bonds. A real bond class

 2.1 Bond class, fair value, duration & yield Let us writea "bond class" to perform various calculations relevant for bonds. A realbond class has a lot of data and class methods. We shallwrite a simplified bond class to calculate the fair value, Macaulay durationand modified duration, given an input yield. We shall also calculate theyield, given an input target price for the bond. Although it isa simple model, our bond class will have some of the corefeatures of a real bond class in a financial software library. 2.2Class declaration We shall follow a convention to begin the names ofdata members with an underscore This convention is widely used in industry.I shall write "std:: below but you can write "using namespace std;"

2.1 Bond class, fair value, duration & yield Let us write a "bond class" to perform various calculations relevant for bonds. A real bond class has a lot of data and class methods. We shall write a simplified bond class to calculate the fair value, Macaulay duration and modified duration, given an input yield. We shall also calculate the yield, given an input target price for the bond. Although it is a simple model, our bond class will have some of the core features of a real bond class in a financial software library. 2.2 Class declaration We shall follow a convention to begin the names of data members with an underscore This convention is widely used in industry. I shall write "std:: below but you can write "using namespace std;" in your code . Our class has the following private data members: (i) double Face, (ii) double _issue, (iii) double maturity, (iv) int .cpnFreq, (v) int _numCpnPeriods, (vi) std: : vector cpmAmt, (vii) std: : vector .cpnDate . We want our Bond class to have methods to perform the following functions 1. Set the coupons (for variable rate coupons) 2. Calculate the fair value, given an input yield 3. Calculate the Macaulay duration and modified duration, given an input yield . The calculation methods are all "const" but setting the coupons is not const Explain why Write a Bond class with the following signature class Bond public Bond (double F, double issue_date, int num_periods, int freq, const std: :vector &c); Bond; void setFlatCoupons (double c); void setCoupons (const std: :vector &c); double FairValue (double t0, double y) const; double maturityO const I return _maturity; h double issue) const return _issue; int FV_duration(double t0, double y, double &B, double &Mac_dur, double &mod_dur) const; private // data double _Face; double -issue; double _maturity; int _cpnFreq; int _numCpnPeriods; std::vector -cpnAmt; std: :vector _cpnDate; d; 2.6 Fair value & duration: FV duration() The inputs are (i) to, (i) y (both double). The outputs are ii double &B, (iv) double &Mac dur, (v) double &mod dur o Initialize B - 0, Mac dur - 0 and mod dur -0 Validation tests: 1. If to - maturity, then return 1 (fail) and exit 2. This is why the function return type is "int" not void . The mathematical formula for the bond fair value B was given in the lectures 1. Note that in the mathematical formula, the indexing runs from i-1 through n. 2. The coupons are indexed as c1,... , Cn and the yield y is a decimal number 3. We only include terms in the sum where ti -to > 0 C2 (1+y/f)/(n-to) (1 +y/f)/(t2-to) rm (numerator) 4. The definition of "numerator i" in eq. (2.6.1) is obvious 5. The formula for the Macaulay duration is (numerator) DMacaulay B (2.6.2) 6. The formula for the modified duration is DMacaulay mod The input value of the yield y is a percentage, so if the yield is 5% then y = 5 1. Hence employ an internal variable ydecimal-0.01 * y, to avoid "factor of 100" errors in your code. . The value of ti is obtaned from the coupon dates vector I. However, we have to guard against floating point roundoff error 2. Define a tolerance parameter "const double tol-1.0e-6 in your function. 3. Only include terms in the sum such that ti2to tol. Write a loop (s) to compute the sums in eqs. (2.6.1) and (2.6.2) . The modified duration is easy to obtain from the Macaulay duration (see eq. (2.6.3)) . Return 0 (success) and exit 2.7 Tests . Here are some tests to help you to check that your code is working correctly . To keep things simple, use F 100 in all your tests. There is no point in being too clever Put to -0 and use a constant coupon c. Then if the yield equals the coupon y- c, you should obtain FV100 . Apply your code to the bonds in HW1. You should obtain the same results you obtained in HW1 Put to-0 and y-0. Then the fair value is a straight sum of the values of the cashflows Your program should obtain the result Ci . Put c-0. This is known as a zero coupon bond and they do exist. A zero coupon bond pays only one cashflow, which is to pay the face value at maturity. The formula is coupon1+v/ fmaturty- (2.7.2) . The Macaulay duration of a zero coupon bond equals the time to maturity: maturity -to (2.7.3) T'his is an important fact. . For fixed values of to and y, the fair value increases if the coupons increase . If the coupons are positive, the value of the Macaulay duration is less than Tmaturity - to. If you multiply all the coupons by a factor of 2 (or any number > 1), the value of the Macaulay duration will decrease . For a given face and coupons, etc., the fair value of a bond decreases as the yield y increases (This is in fact a general theorem. It was proved in the 1930s, I think.) * Try different values of the issue date and print the values of the coupon dates and check Try different values of to and check that the fair value calculation includes only the correct coupons 2.8 Yield from bond price: yield() We employ the bisection algorithm . The fundamental idea is simple and was explained in class. It goes as follows 1. Given a target value, we wish to find the yield y such that B(y) - Btarget 2. We know from eq. (2.6.1) that B(v) is a continuous function of y 3. We also know that B(y) decreases as the value of y increases 4. Hence we find a low yield ylow such that B(ylow) > Btarget and a high yield yhigh such that B(yhigh) 0. 4. If yes, then the values of B(low) and B(yhigh) do not bracket Btarget and we have failed. 5. Set y = 0 and "return 1" (fail) and exit If we have made it this far, then we know that we have bracketed the answer, and the true yield y lies between yhow and Vhigh . Hence we now begin the main bisection iteration loop for (num-iter 1; num-iter 0.0 2. If yes, then update ylow-y . Else obviously B and B(high) are on the same side of Btarget, so update yhigh = y Don't be in a rush to iterate! S tol, then this is good enough. 2. The algorithm has converged 3. Hence "return 0" (success) and exit If we have come this far, continue with the iteration loop . If we exit the iteration loop after max iter steps and the calculation still has not converged, then set y 0 and "return 1" (fail) 1. This can happen if the tolerance tol is too small or the value of max iter is too small 2. Reasonable values to use are tol 1.0e-4 and max iter- 100 . We have reached the end of the function. By now either we have a "good enough" answer return value = 0 success) or not (return value-1-fail 2.9 Tests . Here are some tests to help you to check that your code is working correctly. Remember to use F-100 in all your tests. There is no point in being too clever. Set to equal to the issue date (newly issued bond). Use a flat coupon c (set it using the constructor or use setFlatCoupons) 1. Try an input Barget-100. If your function works correctly, it should output y = c (up to the tolerance), for any value of c and any value of freq and any value of T (provided freq * T >- 1. Remember that if F- 100 and y -c (the yield equals the coupon) for a newly issued bond, then B- 100. The converse also holds true. 2. If Btarget c. 3. If Btarget > 100 then your output should be y -1. Use any value to 2 0 and to T. Use a constant coupon c or input a vector of coupons using set-coupons. 1. Choose some value fir the yield, say y, and calculate the fair value, say B1. 2. Set a target Btarget B1 +1. 3. Calculate the yield, say the output is y2. 4. Calculate the fair value using y2, say the answer is B2 5. If you have done your work correctly, you should obtain B2- Bi 1 (up to tolerance) 2.1 Bond class, fair value, duration & yield Let us write a "bond class" to perform various calculations relevant for bonds. A real bond class has a lot of data and class methods. We shall write a simplified bond class to calculate the fair value, Macaulay duration and modified duration, given an input yield. We shall also calculate the yield, given an input target price for the bond. Although it is a simple model, our bond class will have some of the core features of a real bond class in a financial software library. 2.2 Class declaration We shall follow a convention to begin the names of data members with an underscore This convention is widely used in industry. I shall write "std:: below but you can write "using namespace std;" in your code . Our class has the following private data members: (i) double Face, (ii) double _issue, (iii) double maturity, (iv) int .cpnFreq, (v) int _numCpnPeriods, (vi) std: : vector cpmAmt, (vii) std: : vector .cpnDate . We want our Bond class to have methods to perform the following functions 1. Set the coupons (for variable rate coupons) 2. Calculate the fair value, given an input yield 3. Calculate the Macaulay duration and modified duration, given an input yield . The calculation methods are all "const" but setting the coupons is not const Explain why Write a Bond class with the following signature class Bond public Bond (double F, double issue_date, int num_periods, int freq, const std: :vector &c); Bond; void setFlatCoupons (double c); void setCoupons (const std: :vector &c); double FairValue (double t0, double y) const; double maturityO const I return _maturity; h double issue) const return _issue; int FV_duration(double t0, double y, double &B, double &Mac_dur, double &mod_dur) const; private // data double _Face; double -issue; double _maturity; int _cpnFreq; int _numCpnPeriods; std::vector -cpnAmt; std: :vector _cpnDate; d; 2.6 Fair value & duration: FV duration() The inputs are (i) to, (i) y (both double). The outputs are ii double &B, (iv) double &Mac dur, (v) double &mod dur o Initialize B - 0, Mac dur - 0 and mod dur -0 Validation tests: 1. If to - maturity, then return 1 (fail) and exit 2. This is why the function return type is "int" not void . The mathematical formula for the bond fair value B was given in the lectures 1. Note that in the mathematical formula, the indexing runs from i-1 through n. 2. The coupons are indexed as c1,... , Cn and the yield y is a decimal number 3. We only include terms in the sum where ti -to > 0 C2 (1+y/f)/(n-to) (1 +y/f)/(t2-to) rm (numerator) 4. The definition of "numerator i" in eq. (2.6.1) is obvious 5. The formula for the Macaulay duration is (numerator) DMacaulay B (2.6.2) 6. The formula for the modified duration is DMacaulay mod The input value of the yield y is a percentage, so if the yield is 5% then y = 5 1. Hence employ an internal variable ydecimal-0.01 * y, to avoid "factor of 100" errors in your code. . The value of ti is obtaned from the coupon dates vector I. However, we have to guard against floating point roundoff error 2. Define a tolerance parameter "const double tol-1.0e-6 in your function. 3. Only include terms in the sum such that ti2to tol. Write a loop (s) to compute the sums in eqs. (2.6.1) and (2.6.2) . The modified duration is easy to obtain from the Macaulay duration (see eq. (2.6.3)) . Return 0 (success) and exit 2.7 Tests . Here are some tests to help you to check that your code is working correctly . To keep things simple, use F 100 in all your tests. There is no point in being too clever Put to -0 and use a constant coupon c. Then if the yield equals the coupon y- c, you should obtain FV100 . Apply your code to the bonds in HW1. You should obtain the same results you obtained in HW1 Put to-0 and y-0. Then the fair value is a straight sum of the values of the cashflows Your program should obtain the result Ci . Put c-0. This is known as a zero coupon bond and they do exist. A zero coupon bond pays only one cashflow, which is to pay the face value at maturity. The formula is coupon1+v/ fmaturty- (2.7.2) . The Macaulay duration of a zero coupon bond equals the time to maturity: maturity -to (2.7.3) T'his is an important fact. . For fixed values of to and y, the fair value increases if the coupons increase . If the coupons are positive, the value of the Macaulay duration is less than Tmaturity - to. If you multiply all the coupons by a factor of 2 (or any number > 1), the value of the Macaulay duration will decrease . For a given face and coupons, etc., the fair value of a bond decreases as the yield y increases (This is in fact a general theorem. It was proved in the 1930s, I think.) * Try different values of the issue date and print the values of the coupon dates and check Try different values of to and check that the fair value calculation includes only the correct coupons 2.8 Yield from bond price: yield() We employ the bisection algorithm . The fundamental idea is simple and was explained in class. It goes as follows 1. Given a target value, we wish to find the yield y such that B(y) - Btarget 2. We know from eq. (2.6.1) that B(v) is a continuous function of y 3. We also know that B(y) decreases as the value of y increases 4. Hence we find a low yield ylow such that B(ylow) > Btarget and a high yield yhigh such that B(yhigh) 0. 4. If yes, then the values of B(low) and B(yhigh) do not bracket Btarget and we have failed. 5. Set y = 0 and "return 1" (fail) and exit If we have made it this far, then we know that we have bracketed the answer, and the true yield y lies between yhow and Vhigh . Hence we now begin the main bisection iteration loop for (num-iter 1; num-iter 0.0 2. If yes, then update ylow-y . Else obviously B and B(high) are on the same side of Btarget, so update yhigh = y Don't be in a rush to iterate! S tol, then this is good enough. 2. The algorithm has converged 3. Hence "return 0" (success) and exit If we have come this far, continue with the iteration loop . If we exit the iteration loop after max iter steps and the calculation still has not converged, then set y 0 and "return 1" (fail) 1. This can happen if the tolerance tol is too small or the value of max iter is too small 2. Reasonable values to use are tol 1.0e-4 and max iter- 100 . We have reached the end of the function. By now either we have a "good enough" answer return value = 0 success) or not (return value-1-fail 2.9 Tests . Here are some tests to help you to check that your code is working correctly. Remember to use F-100 in all your tests. There is no point in being too clever. Set to equal to the issue date (newly issued bond). Use a flat coupon c (set it using the constructor or use setFlatCoupons) 1. Try an input Barget-100. If your function works correctly, it should output y = c (up to the tolerance), for any value of c and any value of freq and any value of T (provided freq * T >- 1. Remember that if F- 100 and y -c (the yield equals the coupon) for a newly issued bond, then B- 100. The converse also holds true. 2. If Btarget c. 3. If Btarget > 100 then your output should be y -1. Use any value to 2 0 and to T. Use a constant coupon c or input a vector of coupons using set-coupons. 1. Choose some value fir the yield, say y, and calculate the fair value, say B1. 2. Set a target Btarget B1 +1. 3. Calculate the yield, say the output is y2. 4. Calculate the fair value using y2, say the answer is B2 5. If you have done your work correctly, you should obtain B2- Bi 1 (up to tolerance)

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!