Bootsrapping Curve Models
Overview
The bootstrap is an iterative method for determining a set of zero coupon rates from a series of bonds.
The method described below uses
matrices and vectors
to describe the algorithm
(see
Nawallkha chpt 3)
Bootstrap
The method begins with a set of bonds and a set of prices for each bond.
The prices are arranged as a price vector
{% P = [P_1, P_2, ... , P_n]^T %}
where {% P_i %} is the price of the ith bond.
The cash flows of the bonds are arranged in a matrix. The cash flow matrix is given by
{%
C = \begin{bmatrix}
C_{1 1} & C_{1 2} & C_{1 3}\\
C_{2 1} & C_{2 2} & C_{2 3}\\
C_{3 1} & C_{3 2} & C_{3 3} \\
\end{bmatrix}
%}
where {% C_{i j} %} is the jth cash flow of the ith bond. The jth cash
flow of each bond occurs on the same date. If no cash flow occurs
for that date for a given bond, the value is set to zero.
The discount rates are arranged as a discount vector
{% D = [D_1, D_2, ... , D_n]^T %}
where {% D_i %} is the ith discount rate applied to the ith cash flow.
The the bond prices should be related to the cash flows as follows:
{% \vec{P} = C \vec{D} %}
which implies that the discount vector can be computed as
{% \vec{D} = C^{-1} \vec{P} %}
(see
matrix inverse)
If the matrix of cash flows is not invertable, as is typically the case when
one has more instruments that dates, one can use the matrix
pseudo inverse
to calculate a least squares estimate of the discount rates.
Implementation
let la = await import('/lib/linear-algebra/v1.0.0/linear-algebra.mjs');
let prices = [100,102,99];
let cashFlows = [[100,0,0],[10,0,100],[0,5,100]]
let discounts = la.multiply(la.inverse(cashFlows), prices.map(p=>[p]));
Try it!