Root Finding / Yield to Maturity of a Bond

Best if used on a desktop.

The below tool calculates the YTM (\(\lambda\)) of a bond given its current market price using the Binary Search and Newton's Method algorithms. The goal is to find a value \(\lambda\) such that \[ \left\lvert f(\lambda) - P) \right\rvert \le \epsilon \iff\] \[- \epsilon \le F(\lambda) - P \le \epsilon \iff\] \[P - \epsilon \le F(\lambda) \le P + \epsilon \] where \[f(\lambda) = \sum_{i=1}^{n*t - 1} \frac{c_i/n}{1 + (\lambda / n)^{i}} + \frac{F + c_i/n}{1 + (\lambda / n)^{n * t}} \] While the results are not exact, an error (epsilon: \(\epsilon \)) is provided for how close the approximation methods need to be to the market price \(P\). The goal is to get the market price \(P\) of the bond as close to the discounted value of its future cash flows as possible given some value \(\lambda\). This value \(\lambda\) is defined as the bonds Yield to Maturity.






























(Note: The Program has a max of
1000 iterations)


Bond Valuation: For a bond with a Face Value \(F\), maturing in \(t\) years, paying an annual coupon of rate \(c\), with \(n\) payment periods per year of that coupon we define its present value \(P\) as: \[P = \sum_{i=1}^{n*t - 1} \frac{c_i/n}{1 + (\lambda / n)^{i}} + \frac{F + c_i/n}{1 + (\lambda / n)^{n * t}} \] \(\lambda\) represents the Yield to Maturity (YTM) of the bond. The YTM is defined as the rate that makes the present value of the future cash flows from the bond (including the principal) equal to the market value of the bond. Thus, in effect, the YTM of a bond is analogous to the Internal Rate of Return of (IRR) of the stream of cash flows. Mathematically this akin to finding the roots of a degree \(n*t\) polynomial which can be done numerically.

Both the Binary Search and Newton's Method algorithms aim to solve the below equation iteratively: \[ 0 = -P + \sum_{i=1}^{n*t - 1} \frac{c_i/n}{1 + (\lambda / n)^{i}} + \frac{F + c_i/n}{1 + (\lambda / n)^{n * t}} \]

Binary Search: Given that we are using the real number line as our input list for the binary search algorithm we can exploit the fact that the number line is sorted and use a simple Binary Search. A costly alternative would be to simply pick every number from 0 to 1 as \(\lambda\) with intervals of .001 for example and for each choice check to see if it solves the above equation given our error. This would take \(O(n)\) time, where n is the size of our number line range.

We can improve this significantly is we use a Binary Search which takes \(Olog(n)\) time. We first start with an initial guess for \(\lambda\), the midpoint of an upper and lower bound, and then check that value in our equation. If \(F(\lambda)\) is greater than the market price then we know we need to increase \(\lambda\) for the next check. If \(F(\lambda)\) is less than the market price then we know we need to decrease \(\lambda\) for the next check. We increase and decrease our guess for \(\lambda\) by adjusting our upper and lower bounds on each iteration. We do this until \( \left\lvert f(\lambda) - P) \right\rvert \le \epsilon \). Read more about the binary search algorithm here: https://en.wikipedia.org/wiki/Binary_search_algorithm


Newton's Method: The second method used to solve the above equation is Newton's Method wherein we find the root of the above function by choosing an initial guess \(\lambda_0\), and use that guess as an argument to the below function to generate the value \(\lambda_1\). We then then use \(\lambda_1\) to generate \(\lambda_2\) and so on until our choice of \(\lambda\) satisfies the above equation. \[0 = f(\lambda_0) + f'(\lambda_0)(\lambda_1 - \lambda_0)\] \[\lambda_1 = \lambda_0 - \frac{f(\lambda_0)}{f'(\lambda_0)} \] Read more about Newton's Method here: https://en.wikipedia.org/wiki/Newton%27s_method

Sources