Tutorials › Exam FM - Financial Mathematics › A Matrix View of Coupon-Bond Bootstrapping

Exam FM · Bootstrapping the Curve · Tutorial 744 of 998

A Matrix View of Coupon-Bond Bootstrapping

Represent bond prices as a matrix equation, then use the triangular cash-flow structure to solve for discount factors in maturity order.

Advanced 11 min read

What You'll Learn

  • Define a discount-factor vector for the cash-flow dates being bootstrapped
  • Build a bond cash-flow matrix and price vector from full bond prices
  • Explain why cash flows make the system lower triangular when maturities align with the date grid
  • Solve a small bootstrap by forward substitution and in matrix notation
  • Check uniqueness using the diagonal entries of the cash-flow matrix
  • Identify when missing maturities leave discount factors underdetermined

Why View a Bootstrap as a Matrix?

A coupon-bond bootstrap is often calculated one maturity at a time: use the shortest bond to find its discount factor, then use that factor to solve for the next one. A matrix view expresses all those price equations together. It makes the structure of the calculation visible, clarifies why substitution works, and helps identify whether the available bonds determine every requested discount factor.

The setup uses full prices and known, deterministic cash flows. Suppose the relevant payment dates are \(t_1<t_2<\cdots<t_n\). Let \(D_j\) denote the discount factor from payment date \(t_j\) to the valuation date. The present value of a known cash flow \(C_j\) at \(t_j\) is \(C_jD_j\). A bond's full price is the sum of the present values of all its remaining cash flows.

Definition: The cash-flow matrix \(A\) has one row for each bond and one column for each payment date. Its entry \(A_{ij}\) is the cash flow of bond \(i\) at date \(t_j\), with zero entered if there is no payment on that date. The discount-factor vector is \(D=(D_1,\ldots,D_n)^{\mathsf T}\), and the price vector \(P\) contains the corresponding full bond prices. When the rows and columns are arranged on a compatible date grid, the pricing equations are \(AD=P\).

For example, a bond with a coupon at \(t_1\) and a coupon plus redemption at \(t_2\) contributes a row with two nonzero entries. A bond that matures at \(t_2\) has no cash flows at later dates, so its row has zeros in later columns. That pattern is the source of the triangular structure.

Why the System Is Triangular

Assume there is one bond maturing at each of the ordered dates \(t_1,\ldots,t_n\), and bond \(i\) has no cash flows after its maturity \(t_i\). If the bonds and dates are ordered by maturity, then \(A_{ij}=0\) whenever \(j>i\). The matrix is therefore lower triangular. Payments before maturity can create nonzero entries to the left of the diagonal; the maturity payment appears on the diagonal.

The diagonal entry \(A_{ii}\) is the cash flow of bond \(i\) at its own maturity. For an ordinary coupon bond with a positive redemption payment, that entry is positive. Consequently, the factors can be solved sequentially, provided each diagonal entry is nonzero and the prices and cash flows refer to the same valuation date and payment dates.

$$ \begin{pmatrix} A_{11} & 0 & 0 & \cdots & 0\\ A_{21} & A_{22} & 0 & \cdots & 0\\ A_{31} & A_{32} & A_{33} & \cdots & 0\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ A_{n1} & A_{n2} & A_{n3} & \cdots & A_{nn} \end{pmatrix} \begin{pmatrix} D_1\\D_2\\D_3\\\vdots\\D_n \end{pmatrix} = \begin{pmatrix} P_1\\P_2\\P_3\\\vdots\\P_n \end{pmatrix} $$

The first row gives \(A_{11}D_1=P_1\). Once \(D_1\) is known, the second row gives \(D_2\); after that, the third row gives \(D_3\), and so on. In general, row \(i\) gives

$$ D_i=\frac{P_i-\displaystyle\sum_{j=1}^{i-1}A_{ij}D_j}{A_{ii}}, \qquad A_{ii}\ne 0. $$

This is forward substitution. The formula is not a separate pricing rule: it is the \(i\)th row of \(AD=P\), rearranged to isolate the one factor not yet known.

Why the Matrix Equation Holds

The matrix form follows directly from the present-value principle. Bond \(i\) pays \(A_{ij}\) at date \(t_j\). Under the stated discount-factor model, that payment has present value \(A_{ij}D_j\). Adding the present values across dates gives the bond's full price \(P_i\):

$$ P_i=A_{i1}D_1+A_{i2}D_2+\cdots+A_{in}D_n. $$

Each such equation is one row of \(AD=P\). Collecting the equations does not change the valuation assumptions; it simply records them together. This representation applies when the cash flows are known and the same date-specific discount factors are used to value every bond. It does not, by itself, resolve uncertain cash flows, mismatched settlement dates, or prices that are not full prices.

Worked Example: Building and Solving a Two-Bond System

At a common valuation date, two annual-payment bonds have full prices of $98.88 and $97.44. The one-year bond pays $103 at year 1. The two-year bond pays $4 at year 1 and $104 at year 2. Find \(D_1\) and \(D_2\) by writing the matrix system and solving it. Assume the quoted cash flows are certain and use the same discount factors for both bonds.

Method. Put the dates in increasing order, enter each bond's cash flows in its row, and use forward substitution. This avoids the common mistake of treating the second bond's full price as if it were entirely a year-2 payment.

The cash-flow matrix and price vector are

$$ A= \begin{pmatrix} 103&0\\ 4&104 \end{pmatrix}, \qquad P= \begin{pmatrix} 98.88\\97.44 \end{pmatrix}. $$

The first row gives \(103D_1=98.88\), so

$$ D_1=\frac{98.88}{103}=0.96. $$

The second row is \(4D_1+104D_2=97.44\). Substitute \(D_1=0.96\):

$$ 4(0.96)+104D_2=97.44, \qquad 104D_2=97.44-3.84=93.60, \qquad D_2=\frac{93.60}{104}=0.90. $$

Check. The first price is \(103(0.96)=98.88\). The second is \(4(0.96)+104(0.90)=3.84+93.60=97.44\), as quoted. The factors are therefore \(D_1=0.96\) and \(D_2=0.90\).

Reading the Matrix and Solving by Substitution

Rows represent bonds, not dates; columns represent dates, not bonds. This distinction matters when translating a description into \(A\). A coupon is entered in every column where it is paid, and the redemption payment is added to the final coupon in the maturity column. A zero belongs in a column when that bond has no payment on that date.

The matrix is lower triangular only under a compatible ordering: each row's bond must mature at the date corresponding to its diagonal column, with the dates and bonds sorted by maturity. If the bonds are listed in another order, reorder the rows before applying forward substitution. Reordering rows also requires reordering the price vector in the same way.

1
Choose the date grid.
List the distinct payment dates relevant to the bonds, in increasing order, and define one discount factor for each date.
2
Record cash flows.
Enter each bond's coupon and redemption payments in the corresponding columns; enter zero for dates with no payment.
3
Align rows and prices.
For a square triangular bootstrap, order one bond per maturity-date column by increasing maturity, and place its full price in the matching row of \(P\).
4
Solve from the first row down.
At each row, subtract the present values of already-solved earlier cash flows, then divide by the diagonal cash flow.

Worked Example: Solving a Three-Maturity System in Matrix Notation

Three annual-payment bonds have maturities at years 1, 2, and 3. Their cash-flow rows are \((104,0,0)\), \((5,105,0)\), and \((3,3,103)\), and their full prices are $100.88, $100.40, and $94.22, respectively. Find the three discount factors. Assume certain cash flows and a common valuation date.

Method. Write \(AD=P\), then solve the lower-triangular system by forward substitution. Keeping each solved factor exact through the next row avoids introducing unnecessary rounding error.

$$ \begin{pmatrix} 104&0&0\\ 5&105&0\\ 3&3&103 \end{pmatrix} \begin{pmatrix} D_1\\D_2\\D_3 \end{pmatrix} = \begin{pmatrix} 100.88\\100.40\\94.22 \end{pmatrix}. $$

From row 1,

$$ D_1=\frac{100.88}{104}=0.97. $$

Row 2 gives \(5D_1+105D_2=100.40\). Substituting the first factor,

$$ 105D_2=100.40-5(0.97)=100.40-4.85=95.55, \qquad D_2=\frac{95.55}{105}=0.91. $$

Row 3 gives \(3D_1+3D_2+103D_3=94.22\). Therefore,

$$ 103D_3=94.22-3(0.97)-3(0.91) =94.22-2.91-2.73=88.58, \qquad D_3=\frac{88.58}{103}=0.86. $$

Check. Substitution into the three rows gives \(104(0.97)=100.88\), \(5(0.97)+105(0.91)=4.85+95.55=100.40\), and \(3(0.97)+3(0.91)+103(0.86)=2.91+2.73+88.58=94.22\). Thus the solution is \((D_1,D_2,D_3)=(0.97,0.91,0.86)\).

Matrix Notation, Uniqueness, and Limits

In matrix notation, the bootstrap is the solution of \(AD=P\). A square lower-triangular matrix has a unique solution if every diagonal entry is nonzero. One way to see this is that the determinant of a triangular matrix is the product of its diagonal entries:

$$ \det(A)=\prod_{i=1}^{n}A_{ii}. $$

If every \(A_{ii}\ne 0\), then \(\det(A)\ne 0\), so \(A\) is invertible and the factors are uniquely determined by \(P\). In practical coupon bonds, a positive redemption payment normally makes the maturity cash flow, and hence the relevant diagonal entry, positive.

The triangular form also explains what happens when data are missing. If there is no bond that isolates or otherwise identifies a new terminal date, a system may contain more unknown discount factors than independent price equations. It is then not a complete bootstrap: more information or an explicitly specified interpolation assumption would be needed. A matrix equation makes this issue visible instead of concealing it in a sequence of attempted divisions.

A matrix view does not mean that every available bond must be included in one square system. Extra bonds can produce additional equations, while a missing maturity can leave a factor unidentified. The central test is whether the equations actually determine the requested factors under the stated cash-flow and discounting assumptions. Also distinguish a full price from a clean price: the cash-flow present-value equation equates to the full price, so any accrued interest adjustment must be handled before placing the price in \(P\).

Worked Example: Reordering Bonds Before Solving

Three bonds are quoted in this order: a three-year bond with cash flows \((2,2,102)\) and full price $90.42; a one-year bond paying $101 at year 1 with full price $96.96; and a two-year bond with cash flows \((4,104,0)\) and full price $97.44. Place the equations in maturity order and solve for \(D_1,D_2,D_3\). Assume all cash flows are certain and measured from the same valuation date.

Method. Reorder both the bond rows and their prices by maturity, then use forward substitution. The common mistake is to leave the price vector in the original quote order after rearranging the matrix.

$$ \begin{pmatrix} 101&0&0\\ 4&104&0\\ 2&2&102 \end{pmatrix} \begin{pmatrix} D_1\\D_2\\D_3 \end{pmatrix} = \begin{pmatrix} 96.96\\97.44\\90.42 \end{pmatrix}. $$

The first equation gives \(D_1=96.96/101=0.96\). The second gives

$$ 104D_2=97.44-4(0.96)=97.44-3.84=93.60, \qquad D_2=93.60/104=0.90. $$

The third equation gives

$$ 102D_3=90.42-2(0.96)-2(0.90) =90.42-1.92-1.80=86.70, \qquad D_3=86.70/102=0.85. $$

Check. The maturity-ordered equations give prices \(101(0.96)=96.96\), \(4(0.96)+104(0.90)=97.44\), and \(2(0.96)+2(0.90)+102(0.85)=90.42\). The solution is \(D_1=0.96,\ D_2=0.90,\ D_3=0.85\), and the original quote order has not changed the corresponding bond prices.

Common Mistakes and Why This View Matters

  • Putting coupons in the wrong columns. Each entry is dated cash flow, not a coupon rate or a present value. The discount factor is applied later through matrix multiplication.
  • Leaving out redemption. The final cash flow is usually the final coupon plus the redemption amount, not the coupon alone.
  • Mixing row order and price order. Any row permutation must be applied to the price vector as well, or the equations no longer describe the stated bonds.
  • Rounding an intermediate factor too early. Use the unrounded quotient in subsequent rows when it is not exact; round only the final reported factors to the precision requested.
  • Assuming every data set gives a square triangular system. The triangular solve requires a compatible date grid and sufficient independent equations. Missing terminal maturities can leave factors undetermined.

This representation is useful because it separates the cash-flow information, stored in \(A\), from the unknown discounting information, stored in \(D\). It also provides a systematic route from quoted bond prices to factors without changing the underlying present-value logic. The same organization is useful whether the arithmetic is done by hand or entered into a linear-system solver.

Check Your Understanding

For each problem, write the relevant cash-flow equations before solving or assessing whether the factors are identifiable.

  1. A one-year bond pays $100 at year 1 and costs $96. A two-year bond pays $5 at year 1 and $105 at year 2 and costs $101.40. Find \(D_1\) and \(D_2\). (Answer: \(D_1=0.96,\ D_2=0.92\).)
  2. Three bonds have maturity-ordered cash-flow rows \((102,0,0)\), \((3,103,0)\), and \((2,2,102)\), with full prices $98.94, $97.67, and $93.54. Find the discount-factor vector. (Answer: \(D_1=0.97,\ D_2=0.92,\ D_3=0.88\).)
  3. A one-year bond pays $101 at year 1 for a full price of $96.96. A two-year bond pays $4 at year 1 and $104 at year 2 for a full price of $97.44. Write \(AD=P\) and state whether its triangular system has a unique solution. (Answer: \(A=\begin{pmatrix}101&0\\4&104\end{pmatrix}\), \(P=\begin{pmatrix}96.96\\97.44\end{pmatrix}\); yes, since both diagonal entries are nonzero.)
  4. There are three unknown factors \(D_1,D_2,D_3\). The only bonds available have cash-flow rows \((100,0,0)\) and \((5,5,105)\), with full prices $96 and $99. Can all three factors be uniquely determined from these data? (Answer: No. There are two independent price equations for three unknown factors, so the system does not uniquely determine all three.)
  5. A two-year bond is listed before a one-year bond. Their respective cash-flow rows and full prices are \((4,104)\) at $97.44, and \((101,0)\) at $96.96. Give the maturity-ordered system and its solution. (Answer: \(\begin{pmatrix}101&0\\4&104\end{pmatrix}\begin{pmatrix}D_1\\D_2\end{pmatrix}=\begin{pmatrix}96.96\\97.44\end{pmatrix}\), with \(D_1=0.96,\ D_2=0.90\).)
Clinical Biostats