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.DiscreteCompoundingModel
— Typestruct 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.
VLQuantitativeFinancePackage.ContinuousCompoundingModel
— Typestruct 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.
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.discount
— Methodfunction 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 aDiscreteCompoundingModel
or aContinuousCompoundingModel
.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 is2
.
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 toperiods
.
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.MyUSTreasuryZeroCouponBondModel
— Typemutable 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 bondrate::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 yearn::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 thekey
is the period and thevalue
is the discounted cashflow in a perioddiscount::Union{Nothing, Dict{Int,Float64}}
: Discount factor dictionary (computed property) where thekey
is the period and thevalue
is the discount factor in that period
VLQuantitativeFinancePackage.MyUSTreasuryCouponSecurityModel
— Typemutable 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 bondrate::Union{Nothing, Float64}
: Annualized effective discount ratecoupon::Union{Nothing, Float64}
: Coupon interest rateT::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 thekey
is the period and thevalue
is the discounted cashflow in a perioddiscount::Union{Nothing, Dict{Int,Float64}}
: Discount factor dictionary(computed property) where thekey
is the period and thevalue
is the discount factor in that period
VLQuantitativeFinancePackage.build
— Methodfunction 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 bondrate::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 yearn::Int
: Number of compounding periods per year (typically 2)
VLQuantitativeFinancePackage.build
— Methodfunction 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 bondrate::Union{Nothing, Float64}
: Annualized effective discount ratecoupon::Union{Nothing, Float64}
: Coupon interest rateT::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.
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.price
— Functionfunction 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 theMyUSTreasuryCouponSecurityModel
type.compounding::T
: an instance of a type that is a subtype ofAbstractCompoundingModel
, i.e., a discrete or continuous compounding model.
Returns
MyUSTreasuryCouponSecurityModel
: an updated instance of theMyUSTreasuryCouponSecurityModel
type with the price computed using the compounding model.
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 theMyUSTreasuryZeroCouponBondModel
type.compounding::T
: an instance of a type that is a subtype ofAbstractCompoundingModel
, i.e., a discrete or continuous compounding model.
Returns
MyUSTreasuryZeroCouponBondModel
: an updated instance of theMyUSTreasuryZeroCouponBondModel
type with the price computed using the compounding model.
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.MySymmetricBinaryInterestRateLatticeModel
— Typemutable 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 latticed::Float64
: The down-factor for the latticep::Float64
: The probability of an up move in the latticerₒ::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 ofT + 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 thekey
is the node index and thevalue
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 thekey
is the level index and thevalue
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 asMyBinaryInterestRateLatticeNodeModel
instances.
VLQuantitativeFinancePackage.MyBinaryInterestRateLatticeNodeModel
— Typemutable 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 latticerate::Float64
: The interest rate at the nodeprice::Float64
: The price at the node (used for Treasury security pricing)
VLQuantitativeFinancePackage.build
— Methodfunction build(model::Type{MySymmetricBinaryInterestRateLatticeModel}, data::NamedTuple) -> MySymmetricBinaryInterestRateLatticeModel
VLQuantitativeFinancePackage.populate
— Methodfunction populate(model::MySymmetricBinaryInterestRateLatticeModel) -> MySymmetricBinaryInterestRateLatticeModel
The populate
function completes the initializing of a MySymmetricBinaryInterestRateLatticeModel
model.
Arguments
model::MySymmetricBinaryInterestRateLatticeModel
: An instance of theMySymmetricBinaryInterestRateLatticeModel
type constructed using the correspondingbuild
function.
VLQuantitativeFinancePackage.expectation
— Methodfunction expectation(model::MySymmetricBinaryInterestRateLatticeModel) -> Dict{Int64, Float64}
The expectation
function computes the expectation for each tree level in the lattice model.
Arguments
model::MySymmetricBinaryInterestRateLatticeModel
: An instance of theMySymmetricBinaryInterestRateLatticeModel
type constructed using the correspondingbuild
andpopulate
functions.
Returns
Dict{Int64, Float64}
: A dictionary where thekey
is the level index and thevalue
is the expectation at that level.
VLQuantitativeFinancePackage.variance
— Methodfunction variance(model::MySymmetricBinaryInterestRateLatticeModel) -> Dict{Int64, Float64}
The variance
function computes the variance for each tree level in the lattice model.
Arguments
model::MySymmetricBinaryInterestRateLatticeModel
: An instance of theMySymmetricBinaryInterestRateLatticeModel
type constructed using the correspondingbuild
andpopulate
functions.
Returns
Dict{Int64, Float64}
: A dictionary where thekey
is the level index and thevalue
is the variance at that level.
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.strip
— Functionfunction 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.
VLQuantitativeFinancePackage.YTM
— Functionfunction 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 aDiscreteCompoundingModel
or aContinuousCompoundingModel
.
Optional Arguments
rₒ::Float64 = 0.01
: The initial guess for the annual interest (discount) rate. The default value is0.01
.
Returns
Float64
: The annual interest (discount) rate that minimizes the NPV of the bond.