Fixed Income Treasury Securities

Fixed income securities are financial instruments that pay a fixed amount of interest over a specified period of time. The most common fixed income securities are bonds, which are issued by governments, municipalities, and corporations. The fixed income market is one of the largest financial markets in the world, and it plays a critical role in the global economy.

Discounting model

In the VLQuantitativeFinancePackage we allow computing the present value of a cash flow stream using a discounting model. The present value of a cash flow stream can be computed using a ContinuousCompoundingModel or a DiscreteCompoundingModel.

VLQuantitativeFinancePackage.DiscreteCompoundingModelType
struct DiscreteCompoundingModel <: AbstractCompoundingModel

Immutable type that represents discrete compounding. This type has no fields and is passed as an argument to various functions to indicate that discrete compounding should be used in calculations.

source
VLQuantitativeFinancePackage.ContinuousCompoundingModelType
struct ContinuousCompoundingModel <: AbstractCompoundingModel

Immutable type that represents continuous compounding. This type has no fields and is passed as an argument to various functions to indicate that continuous compounding should be used in calculations.

source

Using the DiscreteCompoundingModel and ContinuousCompoundingModel types, we can compute the discount factors using the discount function. The discount function takes a discounting model, a discount rate, and the number of periods as input arguments and returns the discount factors for each period as a Dictionary object.

VLQuantitativeFinancePackage.discountMethod
function discount(model::AbstractCompoundingModel, rate::Float64, periods::Int; λ::Int64 = 2)::Dict{Int,Float64}

The discount function computes the discount factors for a given compounding model. We assume that the discount rate is constant over all periods.

Arguments

  • model::AbstractCompoundingModel: The compounding model to use to compute the discount factors. The model can be an instance of either a DiscreteCompoundingModel or a ContinuousCompoundingModel.
  • rate::Float64: The annual discount rate used to compute the discount factors.
  • periods::Int: The number of periods for which to compute the discount factors.
  • λ::Int64: The number of compounding events per year. The default value is 2.

Returns

  • Dict{Int,Float64}: A dictionary of the discount factors for the given compounding model. The keys are the period indexes and the values are the discount factors for 0 to periods.
source

Treasury secruity model types

We model United States Treasury debt securities, e.g., Treasury bills, Treasury notes, and Treasury bonds using the MyUSTreasuryZeroCouponBondModel and MyUSTreasuryCouponSecurityModel types, which are subtypes of the AbstractTreasuryDebtSecurity abstract type.

VLQuantitativeFinancePackage.MyUSTreasuryZeroCouponBondModelType
mutable struct MyUSTreasuryZeroCouponBondModel <: AbstractTreasuryDebtSecurity

A mutable struct that represents a U.S. Treasury zero coupon security.

Fields

  • par::Float64: The face or par value of the bond
  • rate::Union{Nothing, Float64}: Effective annual interest rate (discount rate specified as a decimal)
  • T::Union{Nothing,Float64}: Duration in years of the instrument, measured as a 365 day or a 52 week year
  • n::Int: Number of compounding periods per year (typically 2)

Computed Fields

  • price::Union{Nothing, Float64}: Price of the bond or note (computed property)
  • cashflow::Union{Nothing, Dict{Int,Float64}}: Cashflow dictionary (computed property) where the key is the period and the value is the discounted cashflow in a period
  • discount::Union{Nothing, Dict{Int,Float64}}: Discount factor dictionary (computed property) where the key is the period and the value is the discount factor in that period
source
VLQuantitativeFinancePackage.MyUSTreasuryCouponSecurityModelType
mutable struct MyUSTreasuryCouponSecurityModel <: AbstractTreasuryDebtSecurity

A mutable struct that represents a U.S. Treasury coupon bond. This type of security (note or bond) pays the holder of the instrument a fixed interest rate at regular intervals over the life of the security.

Fields

  • par::Float64: Par value of the bond
  • rate::Union{Nothing, Float64}: Annualized effective discount rate
  • coupon::Union{Nothing, Float64}: Coupon interest rate
  • T::Union{Nothing,Float64}: Duration in years of the note or bond, measured as a 365 day or a 52 week year
  • λ::Int: Number of coupon payments per year (typically 2)

Computed Fields

  • price::Union{Nothing, Float64}: Price of the bond or note (computed property)
  • cashflow::Union{Nothing, Dict{Int,Float64}}: Cashflow dictionary (computed property) where the key is the period and the value is the discounted cashflow in a period
  • discount::Union{Nothing, Dict{Int,Float64}}: Discount factor dictionary(computed property) where the key is the period and the value is the discount factor in that period
source
VLQuantitativeFinancePackage.buildMethod
function build(model::Type{MyUSTreasuryZeroCouponBondModel}, data::NamedTuple) -> MyUSTreasuryZeroCouponBondModel

This build method constructs an instance of the MyUSTreasuryZeroCouponBondModel type using the data in the NamedTuple argument.

Arguments

  • model::Type{MyUSTreasuryZeroCouponBondModel}: The type of model to build.
  • data::NamedTuple: The data to use to build the model.

The data::NamedTuple argument must contain the following keys:

  • par::Float64: The face or par value of the bond
  • rate::Union{Nothing, Float64}: Effective annual interest rate (discount rate specified as a decimal)
  • T::Union{Nothing,Float64}: Duration in years measured as a 365 day or a 52 week year
  • n::Int: Number of compounding periods per year (typically 2)
source
VLQuantitativeFinancePackage.buildMethod
function build(model::Type{MyUSTreasuryCouponSecurityModel}, data::NamedTuple) -> MyUSTreasuryCouponSecurityModel

This build method constructs an instance of the MyUSTreasuryCouponSecurityModel type using the data in the NamedTuple.

Arguments

  • model::Type{MyUSTreasuryCouponSecurityModel}: The type of model to build.
  • data::NamedTuple: The data to use to build the model.

The data::NamedTuple must contain the following keys:

  • par::Float64: Par value of the bond
  • rate::Union{Nothing, Float64}: Annualized effective discount rate
  • coupon::Union{Nothing, Float64}: Coupon interest rate
  • T::Union{Nothing,Float64}: Duration in years of the note or bond, measured as a 365 day or a 52 week year
  • λ::Int: Number of coupon payments per year (typically 2)

Return

This function returns an instance of the MyUSTreasuryCouponSecurityModel type. To populate the model, use the price function or a short-cut function involving a compounding model.

Example

Let's build a MyUSTreasuryCouponSecurityModel instance and populate the price, cashflow and discount datastructures for a T = 20-yr bond, with a coupon rate of c = 1.750%, a yield (discount rate) rate = 1.850%, two coupon payments per year, i.e., $\lambda = 2$ and a face (par) value of $V_{P}$ = 100 USD:

test_bond = build(MyUSTreasuryCouponSecurityModel, (
    T = 20.0, rate = 0.01850, coupon = 0.01750, λ = 2, par = 100.0
)) |> discount_model;

where the discount_model refers to either a DiscreteCompoundingModel or a ContinuousCompoundingModel instance.

source

Computing Treasury security prices

To compute the price of a Treasury security, we use the price function that takes a AbstractTreasuryDebtSecurity object and a discounting model as input arguments. We construct MyUSTreasuryZeroCouponBondModel and MyUSTreasuryCouponSecurityModel objects by specifying the maturity date, the face value of the bond the effective annual interest rate and other data that are specific to the bill, note or bond in a build function where the data is specified in a NamedTuple format.

VLQuantitativeFinancePackage.priceFunction
function price(model::MyUSTreasuryCouponSecurityModel, compounding::T) -> MyUSTreasuryCouponSecurityModel where T <: AbstractCompoundingModel

The price(...) function computes the price of a MyUSTreasuryCouponSecurityModel instance using a discrete or continuous compounding model.

Arguments

  • model::MyUSTreasuryCouponSecurityModel: an instance of the MyUSTreasuryCouponSecurityModel type.
  • compounding::T: an instance of a type that is a subtype of AbstractCompoundingModel, i.e., a discrete or continuous compounding model.

Returns

  • MyUSTreasuryCouponSecurityModel: an updated instance of the MyUSTreasuryCouponSecurityModel type with the price computed using the compounding model.
source
function price(model::MyUSTreasuryZeroCouponBondModel, compounding::T) -> MyUSTreasuryZeroCouponBondModel where T <: AbstractCompoundingModel

The price(...) function computes the price of a MyUSTreasuryZeroCouponBondModel instance using a discrete or continuous compounding model.

Arguments

  • model::MyUSTreasuryZeroCouponBondModel: an instance of the MyUSTreasuryZeroCouponBondModel type.
  • compounding::T: an instance of a type that is a subtype of AbstractCompoundingModel, i.e., a discrete or continuous compounding model.

Returns

  • MyUSTreasuryZeroCouponBondModel: an updated instance of the MyUSTreasuryZeroCouponBondModel type with the price computed using the compounding model.
source

Short-cut syntax

We also provide a short-cut syntax to compute the price of a Treasury security which indirectly calls the price function. The short-cut syntax allows the user to specify the data required to construct a AbstractTreasuryDebtSecurity object, and then pass the data to the price function in a single call.

The short-cut syntax is as follows:

(compounding::DiscreteCompoundingModel)(model::MyUSTreasuryCouponSecurityModel) = _price_discrete_compounding(model::MyUSTreasuryCouponSecurityModel)
(compounding::ContinuousCompoundingModel)(model::MyUSTreasuryCouponSecurityModel) = _price_continuous_compounding(model::MyUSTreasuryCouponSecurityModel)
(compounding::DiscreteCompoundingModel)(model::MyUSTreasuryZeroCouponBondModel) = _price_discrete_compounding(model::MyUSTreasuryZeroCouponBondModel)
(compounding::ContinuousCompoundingModel)(model::MyUSTreasuryZeroCouponBondModel) = _price_continuous_compounding(model::MyUSTreasuryZeroCouponBondModel)

To use the short-cut syntax, the user must first construct a AbstractTreasuryDebtSecurity object using the build function and then pass the object to the short-cut syntax function. For example, to compute the price of a 20-year Treasury bond with a coupon rate of 1.750%, a yield (discount rate) of 1.850%, two coupon payments per year, and a face value of 100 USD, the user can use the following code:

test_bond = build(MyUSTreasuryCouponSecurityModel, (
    T = 20.0, rate = 0.01850, coupon = 0.01750, λ = 2, par = 100.0
)) |> discount_model;

where the discount_model refers to either a DiscreteCompoundingModel or a ContinuousCompoundingModel instance.

Term structure of interest rates

Fill me in

VLQuantitativeFinancePackage.MySymmetricBinaryInterestRateLatticeModelType
mutable struct MySymmetricBinaryInterestRateLatticeModel <: AbstractInterestRateTreeModel

The MySymmetricBinaryInterestRateLatticeModel mutable struct represents a binary lattice model for simulating interest rates.

Required fields

  • u::Float64: The up-factor for the lattice
  • d::Float64: The down-factor for the lattice
  • p::Float64: The probability of an up move in the lattice
  • rₒ::Float64: The initial interest rate (the root value of the lattice)
  • T::Int64: The number of levels in the tree (zero based), so the tree will have a total of T + 1 levels (including the root level).

Computed fields

  • connectivity::Union{Nothing,Dict{Int64, Array{Int64,1}}}: A dictionary that holds the connectivity of the lattice where the key is the node index and the value is an array of the connected nodes.
  • levels::Union{Nothing,Dict{Int64,Array{Int64,1}}}: A dictionary that holds the node indexes on each level of the lattice where the key is the level index and the value is an array of the node indexes on that level.
  • data::Union{Nothing, Dict{Int64, MyBinaryInterestRateLatticeNodeModel}}: A dictionary that holds the lattice data for each node where nodes are modeled as MyBinaryInterestRateLatticeNodeModel instances.
source
VLQuantitativeFinancePackage.MyBinaryInterestRateLatticeNodeModelType
mutable struct MyBinaryInterestRateLatticeNodeModel

The MyBinaryInterestRateLatticeNodeModel mutable struct represents a node in a binary lattice model for simulating interest rates. This node type is created during the initialization of a lattice model and is used to store the probability, rate, and price data for each node.

Fields

  • probability::Float64: The probability of reaching the node in the binary lattice
  • rate::Float64: The interest rate at the node
  • price::Float64: The price at the node (used for Treasury security pricing)
source
VLQuantitativeFinancePackage.expectationMethod
function expectation(model::MySymmetricBinaryInterestRateLatticeModel) -> Dict{Int64, Float64}

The expectation function computes the expectation for each tree level in the lattice model.

Arguments

Returns

  • Dict{Int64, Float64}: A dictionary where the key is the level index and the value is the expectation at that level.
source
VLQuantitativeFinancePackage.varianceMethod
function variance(model::MySymmetricBinaryInterestRateLatticeModel) -> Dict{Int64, Float64}

The variance function computes the variance for each tree level in the lattice model.

Arguments

Returns

  • Dict{Int64, Float64}: A dictionary where the key is the level index and the value is the variance at that level.
source

Separating the principal and interest payments

Registered Interest and Principal of Securities (STRIPS) bonds are a unique type of fixed-income investment instrument that provides investors with an alternative way to access the coupon payments of Treasury securities. STRIPS bonds are created by separating a Treasury securities coupon and principal components and trading them as individual zero-coupon securities. This process allows investors to purchase and trade the coupon or principal components separately, providing greater flexibility in managing their investment portfolios.

For example, a 5-year Treasury note with annual coupon payments of $C$ USD and a face (par) value of $V_{P}$ (USD) can be stripped into six separate zero-coupon securities, i.e., five zero-coupon bonds, each with face values of $C$ and maturity of $T$= 1,2,3,4 and 5 years, and a six security with face (par) value of $V_{P}$ USD with a duration of $T$ = 5 years. In the general case, a treasury note or bond with $N=\lambda{T}$ coupon payments, where $T$ denotes the maturity in years, and $\lambda$ represents the number of coupon payments per year, can be stripped into $N+1$ separate zero-coupon securities.

VLQuantitativeFinancePackage.stripFunction
function strip(model::MyUSTreasuryCouponSecurityModel) -> Dict{Int, MyUSTreasuryZeroCouponBondModel}

Strips the coupon and par value payments from a parent coupon security.

The strip(...) function takes a model::MyUSTreasuryCouponSecurityModel of the security we wish to strip and returns a Dictionary holding MyUSTreasuryZeroCouponBondModel instances created from the parent security. The keys of the dictionary correspond to the temporal index of the created security.

source
VLQuantitativeFinancePackage.YTMFunction
function YTM(model::MyUSTreasuryZeroCouponBondModel, compounding::AbstractCompoundingModel; rₒ::Float64 = 0.01)::Float64

This function computes the Yield to Maturity (YTM) for a given bond model using the BFGS optimization algorithm. The YTM is the interest (discount) rate that minimizes the Net Present Value (NPV) of the zero coupon bond.

Arguments

  • model::MyUSTreasuryZeroCouponBondModel: A zero coupon bond model that contains the bond data, sans the interest (discount) rate.
  • compounding::AbstractCompoundingModel: The compounding model to use to compute the discount factors. The model can be an instance of either a DiscreteCompoundingModel or a ContinuousCompoundingModel.

Optional Arguments

  • rₒ::Float64 = 0.01: The initial guess for the annual interest (discount) rate. The default value is 0.01.

Returns

  • Float64: The annual interest (discount) rate that minimizes the NPV of the bond.
source