Computing Bond Yield with Newton’s Method

The cat of Entrevaux

In fixed income analysis it is often required to calculate the yield of some coupon paying instrument, for example a bond. Very simply, an yield of a bond is defined as a single rate of return. Under continuous compounding, given a set of interest rates \{r_{T_1}, r_{T_2}, ..., r_{T_n}\}, the yield y equates the present value of the bond computed under a given set of rates. In other words:

\sum_{i=1}^{n}exp(-r_{T_i}T_i) C_{T_i}=\sum_{i=1}^{n}exp(-yT_i) C_{T_i}

where C_{T_i} is a coupon paid out at time T_i . Usually, one solves for y using some iterative guess-work, e.g. goal seek. In this post I will show you a well-know Newton’s recursive method that can be used to base such goal seek on.

The Newton’s Method

The Newton’s method is based on a recursive approximation formula:

x_{i+1}=x_i-\frac{f(x_i)}{f'(x_i)}

Let B=\sum_{i=1}^{n}exp(-yT_i) C_{T_i} be the price(or present value) of the bond expressed via its yield. Then, taking x to represent interest rate, we have:
f(x) = \sum_{i=1}^{n}exp(-x_{T_i}T_i) C_{T_i} - B = 0 and f'(x)=-\sum_{i=1}^{n}T_i C_{T_i} exp (-x_{T_i}T_i)

The recursive formula to solve for yield becomes:

x_{i+1}=x_i+\frac{\sum_{i=1}^{n}exp(-x_{T_i}T_i) C_{T_i} - B}{\sum_{i=1}^{n}T_i C_{T_i} exp (-x_{T_i}T_i)}

Goal Seek in C#

Now let’s take a look at an example implementation. The while loop in CalculateYield method implements the goal seek. This is a very simple example, and we pretend to have the bond price.

using System;
using System.Collections.Generic;
using System.Linq;

namespace YieldCalculator
{
    class EntryPoint
    {
        static void Main(string[] args)
        {
            // use some numbers to illustrate the point
            // maturities in months
            int[] maturities = { 6, 12, 18, 24, 30, 36 };
            double[] yearFrac = maturities.Select(i => i / 12.0).ToArray();
            // bond principle
            double P = 100;
            // bond price
            double B = 108;
            double couponRate = 0.1;
            // calculate future cashflows
            double[] cashflows = maturities.Select(i => (P * couponRate) / 2.0).ToArray();
            // add principle repayment
            cashflows[cashflows.Count() - 1] = P + cashflows[cashflows.Count() - 1];

            double initialGuess = 0.1;
            Console.WriteLine(CalculateYield(initialGuess, cashflows, yearFrac, B));
        }

        static double CalculateYield(double initialGuess, double[] cashflows, double[] yearFrac, double B)
        {
            double error = 0.000000001;
            double x_i = initialGuess-1.0;
            double x_i_next = initialGuess;

            double numerator;
            double denominator;
 
            while (Math.Abs(x_i_next - x_i) > error)
            {
                x_i = x_i_next;
                // linq's Zip is handy to perform a sum over expressions involving several arrays
                numerator = cashflows.Zip(yearFrac, (x,y) => (x * Math.Exp(y *-1*x_i))).Sum();
                denominator = yearFrac.Zip(cashflows, (x,y) => (x*y*Math.Exp(x*-1*x_i))).Sum();
                x_i_next = x_i + (numerator - B) / denominator;
            }
            return x_i_next;
        }
    }
}

Note how handy is LINQ’s Zip function to calculate a sum over an expression involving two arrays.

And now to the burning question – why the picture of a cat? The answer is even simpler than this post: It is a cute cat, so, why not?

Advertisements
This entry was posted in Numerical Analysis and tagged , . Bookmark the permalink.