# Bond Lab is a software application for the analysis of
# fixed income securities it provides a suite of applications
# mortgage backed, asset backed securities, and commerical mortgage backed
# securities Copyright (C) 2018 Bond Lab Technologies, Inc.
# The following script is used to calculate Term Structure
# metrics for mortgage backed securities. To create the script
# the standard procedure is followed set class, set generics,
# set methods, functions. This class is a sub class (document superclass)
#' @include TermStructure.R
NULL
#' An S4 class MortgageTermStructure
#'
#' @slot Cusip A character the cusip number
#' @slot Issuer A character the Issuer name
#' @slot Coupon A numeric value the coupon
#' @slot Term A numeric value the amorization term
# #' @slot ZeroVolSpread A numeric value the spread to the spot rate curve
#' @slot EffDuration A numeric value the effective duration
#' @slot EffConvexity A numeric value the effective convexity
#' @slot KeyRateTenor A numeric value the Key Rate Tenor
#' @slot KeyRateDuration A numeric value the Key Rate Duration
#' @slot KeyRateConvexity A numeric value the Key Rate Convexity
#' @importFrom stats approx
#' @importFrom grDevices adjustcolor
#' @exportClass MortgageTermStructure
setClass("MortgageTermStructure",
representation(
Cusip = "character",
Issuer = "character",
Coupon = "numeric",
Term = "numeric",
#ZeroVolSpread = "numeric",
EffDuration = "numeric",
EffConvexity = "numeric",
KeyRateTenor = "numeric",
KeyRateDuration = "numeric",
KeyRateConvexity = "numeric"))
#'@title Plot Key Rate Duration
#'@description Generic function to plot key rate duration
#'@param object MortgageTermStructure object
#'@export plotkrd
setGeneric('plotkrd', function(object)
{standardGeneric('plotkrd')})
#'@title Plot Key Rate Convexity
#'@description Generic function to plot key rate convexity
#'@param object MortgageTermStructure object
#'@export plotkrc
setGeneric('plotkrc', function(object)
{standardGeneric('plotkrc')})
# Note standard generic Cusip is defined in MBSDetails.R
# Note standard generic Issuer is defined in MBSDetails.R
# Note standard generic Coupon is defined in MBSDetails.R
# Note standard generic Term is defined in MBSDetails.R
# Note standard generic ZeroVolSpread is defined in CurveSpreads.R
#' A standard generic function to access the slot EffDuration
#' @param object an S4 class object
#' @export EffDuration
setGeneric("EffDuration", function(object)
{standardGeneric("EffDuration")})
#' A standard generic function to access the slot EffConvexity
#' @param object an S4 class object
#' @export EffConvexity
setGeneric("EffConvexity", function(object)
{standardGeneric("EffConvexity")})
#' A standard generic function to access the slot KeyRateTenor
#' @param object an S4 class object
#' @export KeyRateTenor
setGeneric("KeyRateTenor", function(object)
{standardGeneric("KeyRateTenor")})
#' A standard generic function to access the slot KeyRateDuration
#' @param object an S4 class object
#' @export KeyRateDuration
setGeneric("KeyRateDuration", function(object)
{standardGeneric("KeyRateDuration")})
#' A standard generic function to access the slot KeyRateConvexity
#' @param object an S4 class object
#' @export KeyRateConvexity
setGeneric("KeyRateConvexity", function(object)
{standardGeneric("KeyRateConvexity")})
setMethod("initialize",
signature("MortgageTermStructure"),
function(.Object,
Cusip = "character",
Issuer = "character",
Coupon = "numeric",
Term = "numeric",
#ZeroVolSpread = "numeric",
EffDuration = "numeric",
EffConvexity = "numeric",
KeyRateTenor = "numeric",
KeyRateDuration = "numeric",
KeyRateConvexity = "numeric",
...){
callNextMethod(.Object,
Cusip = Cusip,
Issuer = Issuer,
Coupon = Coupon,
Term = Term,
#ZeroVolSpread = ZeroVolSpread,
EffDuration = EffDuration,
EffConvexity = EffConvexity,
KeyRateTenor = KeyRateTenor,
KeyRateDuration = KeyRateDuration,
KeyRateConvexity = KeyRateConvexity,
...)
})
#'@title Plot Mortgage Key Rate Duration
#'@description A method to plot mortgage key rate duration
#'@param object MortgageTermStructure object
#'@importFrom stats ecdf
#'@importFrom grDevices rgb
#'@importFrom graphics axis grid hist lines mtext par plot barplot
#'@exportMethod plotkrd
setMethod('plotkrd', signature('MortgageTermStructure'),
function(object){
colors = rep(c('orange'),13)
colors_transparent <- adjustcolor(colors, alpha.f = 0.6)
barplot(object@KeyRateDuration, col = colors_transparent,
main = paste(object@Issuer,
format(round(object@Coupon,2), nsmall =2),
object@Term,'-year Key Rate Duration'),
sub = paste('Effective Duration =',
format(round(sum(object@KeyRateDuration),2), nsmall = 2)),
names.arg = object@KeyRateTenor,
ylab = 'Key Rate Duration',
xlab = 'Key Rate Tenor',
border = colors)
})
#'@title Plot Mortgage Key Rate Convexity
#'@description A method to plot mortgage key rate convexity
#'@param object MortgageTermStructure object
#'@importFrom stats ecdf
#'@importFrom grDevices rgb
#'@importFrom graphics axis grid hist lines mtext par plot barplot
#'@exportMethod plotkrc
setMethod('plotkrc', signature('MortgageTermStructure'),
function(object){
colors = rep(c('orange'),13)
colors_transparent <- adjustcolor(colors, alpha.f = 0.6)
barplot(object@KeyRateConvexity, col = colors_transparent,
main = paste(object@Issuer,
format(round(object@Coupon,2), nsmall =2),
object@Term,'-year Key Rate Duration'),
sub = paste('Effective Convexity =',
format(round(sum(object@KeyRateConvexity),2), nsmall = 2)),
names.arg = object@KeyRateTenor,
ylab = 'Key Rate Convexity',
xlab = 'Key Rate Tenor',
border = colors)
})
#'@title Cusip
#'@description Get Cusip from object of type MortgageTermStructure
#'@param object MortgageTermStructure
#'@exportMethod Cusip
setMethod('Cusip', signature('MortgageTermStructure'),
function(object){object@Cusip})
#'@title Issuer
#'@description Get Issuer from object of type MortgageTermStrucutre
#'@param object MortgageTermStructure
#'@exportMethod Issuer
setMethod('Issuer', signature('MortgageTermStructure'),
function(object){object@Issuer})
#'@title Coupon
#'@description Get Coupon from object of type MortgageTermStructure
#'@param object MortgageTermStructure
#'@exportMethod Coupon
setMethod('Coupon', signature('MortgageTermStructure'),
function(object){object@Coupon})
#'@title Term
#'@description Get Term from object of type MortgageTermStructure
#'@param object MortgageTermStructure
#'@exportMethod Term
setMethod('Term', signature('MortgageTermStructure'),
function(object){object@Term})
# #'@title Zero Volatility Spread
# #'@description Get ZeroVolSpread from object of type MortgageTermStructure
# #'@param object MortgageTermStructure object
# #'@exportMethod ZeroVolSpread
# setMethod('ZeroVolSpread', signature('MortgageTermStructure'),
# function(object){object@ZeroVolSpread})
# #' Method to extract SpotSpread from S4 class
# #' @param object The name of the S4 object of type MortgageTermStructure
# #' @exportMethod SpotSpread
# setMethod("SpotSpread", signature("MortgageTermStructure"),
# function(object){object@SpotSpread})
#' Method to extract EffDuration from S4 class
#' @param object The name of the S4 object of type MortgageTermStructure
#' @exportMethod EffDuration
setMethod("EffDuration", signature("MortgageTermStructure"),
function(object){object@EffDuration})
#' Method to extract EffConvexity from S4 class
#' @param object The name of the S4 object of type MortgageTermStructure
#' @exportMethod EffConvexity
setMethod("EffConvexity", signature("MortgageTermStructure"),
function(object){object@EffConvexity})
#' Method to get the KeyRateTenor from S4 class
#' @param object The name of the S4 object of type MortgageTermStructure
#' @exportMethod KeyRateTenor
setMethod("KeyRateTenor", signature("MortgageTermStructure"),
function(object){object@KeyRateTenor})
#' Method to extract the KeyRateDuration from S4 class
#' @param object The name of the S4 object of type MortgageTermStructure
#' @exportMethod KeyRateDuration
setMethod("KeyRateDuration", signature("MortgageTermStructure"),
function(object){object@KeyRateDuration})
#' Method to extract the KeyRateConvexity from S4 class
#' @param object The name of the S4 object of type MortgageTermStructure
#' @exportMethod KeyRateConvexity
setMethod("KeyRateConvexity", signature("MortgageTermStructure"),
function(object){object@KeyRateConvexity})
#' A function to calculate mortgage key rate duration and convexity
#'
#' This is a generic function used to construct the
#' MortgageTermStructure object
#' @param bond.id A character string referencing an object of type MBS details
#' @param original.bal A numeric value the original balance
#' @param Rate.Delta A numeric value the rate delta used to calculate KRDs.
#' Default value is 0.50. Do not change this unless you are sure you know what
#' you are doing.
#' @param TermStructure A character string referencing an object of the
#' type TermStructure
#' @param settlement.date a character string the settlement date
#' @param principal A numeric value the principal balance. The principal
#' balance is the original balance multiplied by the MBS factor
#' @param price A numeric value the price paid
#' @param cashflow A character string referencing an object of the
#' type MortgageCashFlow
#' @export MtgTermStructure
#' @importFrom stats uniroot
MtgTermStructure <- function(bond.id,
original.bal,
Rate.Delta = 0.50,
TermStructure,
settlement.date,
principal,
price,
cashflow){
# Open connection to the prepayment model tuning library
ModelTune <- ModelTune(bond.id = bond.id)
Burnout = BurnOut(bond.id)
# Open connection to the Mortgage Model function
MortgageRate <- ProjectMortgageRate(bond.id = bond.id,
term.structure = TermStructure)
#Call the bond frequency to adjust the spot spread to the payment
#frequency of the bond
frequency = Frequency(bond.id)
maturity = Maturity(bond.id)
accrued = Accrued(cashflow)
# create PriceTypes for mortgage cash flow call in key rate
Price <- PriceTypes(price = price)
# calcuate proceeds the order of operation is important
proceeds = (principal * PriceBasis(Price)) + accrued
#========== Set the functions that will be used ==========
# These functions are set as internal functions to key rates
# this insures that stored values will not be wrongly be passed to the
# function internal functions used to compute key rate duration and convexity
EffectiveMeasures <- function(rate.delta ,
cashflow,
cashflow.up,
cashflow.dwn,
discount.rates,
discount.rates.up,
discount.rates.dwn,
t.period,
proceeds,
type){
Price.NC = sum((1/((1+discount.rates)^t.period)) * cashflow)
Price.UP = sum((1/((1+discount.rates.up)^t.period)) * cashflow.up)
Price.DWN = sum((1/((1+discount.rates.dwn)^t.period)) * cashflow.dwn)
#print(c(Price.UP, Price.DWN, Price.NC))
switch(type,
duration = (Price.UP - Price.DWN)/(2*proceeds*rate.delta),
convexity = (Price.UP + Price.DWN - (2*proceeds))/(2 * proceeds * (rate.delta^2))
)}
# The spot spread function is used to solve for the spread to the spot
# curve to normalize discounting
Spot.Spread <- function(spread = numeric(),
cashflow = vector(),
discount.rates = vector(),
t.period = vector(),
proceeds = numeric()){
Present.Value <- sum((1/(1+(discount.rates + spread))^t.period) * cashflow)
return(proceeds - Present.Value)
}
# set up the index names for each array that will be used in the function
# Index names set names for columns in the KRIndex. This tables set the
# control strucutre for the loop that will compute key rate duration given
# rates in the key rate table
Index.Names <- c("Period",
"Time",
"Spot Curve",
"Disc Curve",
"KRDwn",
"KRUp")
# KR.Duration.Col set the column names
KR.Duration.Col <- c("Key Rate",
"Key Rate Duration",
"Key Rate Convexity")
#sets the tenor of the key rate that will report a duration
KR.Duration.Row <- c("0.25",
"1",
"2",
"3",
"5",
"7",
"10",
"15",
"20",
"25",
"30",
"40")
#Key Rate Calculation Starts Here
#set the arrays for key rate duration calculation
#key rate table holds data for the term structure and shifts in the key rates
#!! DIM TO LENGTH OF CASH FLOW ARRAY AND SET LAST KR TO LENGTH LINE 604 !!
#
Key.Rate.Table <- array(data = NA,
c(600,6),
dimnames = list(seq(c(1:600)), Index.Names))
#key rate duration array holds the key rates and the key rate duration
KR.Duration <- array(data = NA, c(12,3),
dimnames = list(seq(c(1:12)), KR.Duration.Col))
KR.Duration[,"Key Rate"] <- as.numeric(KR.Duration.Row)
# Create Index for Key Rate Table for interpolation of
# Key Rate Duration set outer knot points the outer points are the first and
# last elements in KR string
# This needs some logic to change the right knot point if the maturity or last
# payment of the bond is greater than 30-years should be adaptive
KR <- c("0.083",
"0.25",
"1",
"2",
"3",
"5",
"7",
"10",
"15",
"20",
"25",
"30",
"40",
"50")
# Key Rates
KRCount = length(KR)
KRIndex <- array(data = NA, c(KRCount, 6),
dimnames = list(seq(c(1:KRCount)), Index.Names))
# Initialize the cash flow array for discounting and spot rate caclulations
# this will be populated from class MortgageCashFlows
# !!! DIM CASHFLOW ARRAY TO SIZE OF CASHFLOW!!
# This will be the first pass at the cash flows before shocking the curve
# Dimension the cashflow array for key rate discounting
CashFlowArray <- array(data = NA, c(600,4),
dimnames = list(seq(1:600),
c("period",
"cashflow_nc",
"cashflow_dwn",
"cashflow_up")))
# Initialze the spot rate array for key rate duration calculations
# The spot rate must be passed from Term Strucuture object
SpotRate <- as.matrix(SpotRate(TermStructure))
# Populate Period, Time(t) and Spot Rate Curve of Key Rate Table using NS
# coefficients from Term Stucture and then populate and align the cashflow
# array for discounting and key rate computations
# !!! SET LOOP TO LENGTH OF CASHFLOW ARRAY !!!
for(x in 1:600){
#Period (n) in which the cashflow is received
Key.Rate.Table[x,"Period"] = x
# Time (t) at which the cashflow is received
# Time period in which the cashflow was received for discounting
Key.Rate.Table [x,"Time"] = x/months.in.year
#spot rates for discounting
Key.Rate.Table[x,"Spot Curve"] = as.numeric(SpotRate[x,1])/yield.basis
#Align Cash Flows and populated the CashFlowArray
#Step One: Make sure all cash flows are set to zero
CashFlowArray[x,"period"] = Key.Rate.Table[x,"Time"]
CashFlowArray[x,"cashflow_nc"] = 0
}
# Step Two: Initialize loop and set the cashflows in the array
# This loops through the time period and set the cashflows into the
# proper array location for discounts by indexing the cashflows to the array.
# The indexing is conditional on the integer of the first period less than or
# equal to 1
# This code populates the cashflows from the cashflow array object which
# is MortgageTermStructure via cashflows input
if(as.integer(cashflow@TimePeriod[1] *12) != 1)
CashFlowArray[as.integer(cashflow@TimePeriod * 12) + 1,"cashflow_nc"] =
cashflow@TotalCashFlow
if(as.integer(cashflow@TimePeriod[1] * 12) == 1)
CashFlowArray[as.integer(cashflow@TimePeriod * 12),"cashflow_nc"] =
cashflow@TotalCashFlow
# This code solves for the spread to spot curve to equal price
# This code can be replaced with the curve spreads class
spot.spread <- uniroot(Spot.Spread,
interval = c(-.75, .75),
tol = .0000000001,
CashFlowArray[,"cashflow_nc"],
discount.rates = Key.Rate.Table[,"Spot Curve"],
t.period = Key.Rate.Table[,"Time"] ,
proceeds)$root
# The spot spread does not need to be converted to semi-bond
# because time weights are used rather than period weights
# Step three add the spot spread to the spot curve
# This yields the discount rates that are need for the key rate duration
# calculation
# at a minimum the cash flow array should be 360 months
for(i in 1:600){
Key.Rate.Table[i,"Disc Curve"] =
Key.Rate.Table[i,"Spot Curve"] + spot.spread
}
#========= Populate KRIndex Table =========================
# The key rate index table will serve as the control table for the looping
# using this table allows for incremental looping of discontinous
# segments of the
# spot rate curve and is proprietary to bondlab
# Step 1 populate Period (n)
KRIndex[1:KRCount,"Period"] <- round(as.numeric(KR) * months.in.year,0)
# Step 2 populate time period (t)
KRIndex[1:KRCount,"Time"] <- as.numeric(KR)
# Step 3 Populate Index Table with the relevant points on the spot curve
# this is done by looping through the key rate table and allows for term
# structure implementation other than Nelson Siegel the key rate index table
# (KRIndex) is used to populate the key rate table (KRTable)
for (j in 1:KRCount){
for (i in 1:600){
if (Key.Rate.Table[i,"Period"] == round(KRIndex[j,"Time"] * 12,0)) {
KRIndex[j,"Spot Curve"] = Key.Rate.Table[i,"Spot Curve"]
} else {KRIndex[j,"Spot Curve"] = KRIndex[j,"Spot Curve"]}
}
}
# Step 4 Populate KRIndex Table with the appropriate Discount Curve values
# from the key rate table these will be the reference points for the
# appropriate key rate shifts
for (j in 1:KRCount){
for (i in 1:600){
if (Key.Rate.Table[i,"Period"] == round(KRIndex[j,"Time"] * 12,0)) {
KRIndex[j,"Disc Curve"] = Key.Rate.Table[i,"Disc Curve"]
} else {KRIndex[j,"Spot Curve"] = KRIndex[j,"Spot Curve"]}
}
}
# Step 5 Populated KRIndex Table with KR Shifts
for (j in 1:KRCount){
KRIndex[j,"KRDwn"] = KRIndex[j,"Disc Curve"] - (Rate.Delta/yield.basis)
KRIndex[j,"KRUp"] = KRIndex[j,"Disc Curve"] + (Rate.Delta/yield.basis)
}
#===== Implement Shift of Spot Rates =======================
# Once the KRIndex is populated implement the shift in the spot rates using
# the KRIndex table as the control
# w is the counter of the internal knot points used to compute key rate
# duration it ignores the boundary knots
# used for interpolation at the end points. x is the length of the array.
# Currently the analysis is limited
# to loans (bonds) with a maximum of 30-years to maturity. This can be made
# dynamic at some point in the future
# y is column counter used the key rate down and key rate up values
for (w in 2:(KRCount-1)){
for (x in 1:600){
#This allocates the up and down Key.Rate.Table index.
#col 5 is KR down and 6 is KR up
for(y in 5:6){
# step 1: populate the spot curve outside the key rate shift =========
if(Key.Rate.Table[x,"Time"] <= KRIndex[w-1,2] ||
Key.Rate.Table[x,"Time"] >= KRIndex[w+1,2])
{Key.Rate.Table[x,y] = Key.Rate.Table[x,"Disc Curve"]
} else {Key.Rate.Table[x,y] = 0}
}
}
#===== Begin Interpolation of Spot Curve =====================
# Maturity points on the spot rate curve to interpolate
KRx <- c(KRIndex[w-1,"Time"],
KRIndex[w,"Time"],
KRIndex[w+1,"Time"])
# Spot rates that correspond to the maturity points Down and Up
for(z in 1:2){
if (z == 1)
{KRy <- c(KRIndex[w-1,"Disc Curve"],
KRIndex[w,"KRDwn"],
KRIndex[w+1,"Disc Curve"])
} else {
KRy <- c(KRIndex[w-1,"Disc Curve"],
KRIndex[w,"KRUp"],
KRIndex[w+1,"Disc Curve"])}
a = KRIndex[w-1,"Period"] #+ Rate.Delta
b = KRIndex[w+1,"Period"] #- Rate.Delta
for(h in a : b){
Key.Rate.Table[h,(z+4)] <- approx(KRx,KRy, Key.Rate.Table[h,"Time"])$y
} # Loop through Key Rate Table and interpolation
} # Inner Loop to set interpolation points from KRIndex
# This line sets the end points for discounting when the 30-year is last point
# on the curve. It is possible to set the endpoints longer using row 12 of
# the KRIndex
#if (KRIndex[w,2] == 30) {
# (Key.Rate.Table[x,"KRDwn"] = KRIndex[12,"KRDwn"]) &
# (Key.Rate.Table[x,"KRUp"] = KRIndex[12,"KRUp"])}
# Derive Key Rate Up and Key Rate Down Cash Flows
# For MBS Cashflows two term strucutre objects are created the
# up and down term strucutres
# are used to drive the key rate scenario foward rates and the
# up and down MBS cashflows
# Initialize the TermStructure Up and Down objects
# Use the term structure object
# 24 is 2-year forward
# 120 is 10-year forward
# create variables and replace 24 and 120 in code
#Key.Rate.TS.Dwn <- TermStructure
#Key.Rate.TS.Up <- TermStructure
Key.Rate.TS.Dwn <- new("TermStructure",
TradeDate <- TradeDate(TermStructure),
Period <- Period(TermStructure),
Date <- ForwardDate(TermStructure),
TimePeriod <- TimePeriod(TermStructure),
SpotRate = numeric(),
DiscRate = numeric(),
ForwardRate = numeric(),
TwoYearFwd = numeric(),
TenYearFwd = numeric())
SpotRate(Key.Rate.TS.Dwn) <- c((unname(Key.Rate.Table[,"KRDwn"])-spot.spread) * 100,
((SpotRate(TermStructure)[361:492])))
DiscRate(Key.Rate.TS.Dwn) <- exp(SpotRate(Key.Rate.TS.Dwn)/yield.basis *
-TimePeriod(Key.Rate.TS.Dwn)[1:length(SpotRate(Key.Rate.TS.Dwn))])
TwoYearForward(Key.Rate.TS.Dwn) <- Forward.Rate(term.structure = Key.Rate.TS.Dwn,
forward.tenor = 24)* yield.basis
TenYearForward(Key.Rate.TS.Dwn) <- Forward.Rate(term.structure = Key.Rate.TS.Dwn,
forward.tenor = 120) * yield.basis
Key.Rate.TS.Up <- new("TermStructure",
TradeDate <- TradeDate(TermStructure),
Period <- Period(TermStructure),
Date <- ForwardDate(TermStructure),
TimePeriod <- TimePeriod(TermStructure),
SpotRate = numeric(),
DiscRate = numeric(),
ForwardRate = numeric(),
TwoYearFwd = numeric(),
TenYearFwd = numeric())
SpotRate(Key.Rate.TS.Up) <- c((unname(Key.Rate.Table[,"KRUp"])-spot.spread) * 100,
((SpotRate(TermStructure)[361:492])))
DiscRate(Key.Rate.TS.Up) <- exp(SpotRate(Key.Rate.TS.Up)/yield.basis *
-TimePeriod(Key.Rate.TS.Up)[1:length(SpotRate(Key.Rate.TS.Up))])
TwoYearForward(Key.Rate.TS.Up) <- Forward.Rate(term.structure = Key.Rate.TS.Up,
forward.tenor = 24) * yield.basis
TenYearForward(Key.Rate.TS.Up) <- Forward.Rate(term.structure = Key.Rate.TS.Up,
forward.tenor = 120) * yield.basis
#return(Key.Rate.TS.Up)
#TwoYearForward(Key.Rate.TS.Up) <- Forward.Rate(
# SpotRate.Curve = SpotRate(Key.Rate.TS.Up),
# FwdRate.Tenor = 24)
# TenYearForward(Key.Rate.TS.Up) <- Forward.Rate(
# SpotRate.Curve = SpotRate(Key.Rate.TS.Up),
# FwdRate.Tenor = 120)
# Run the prepayment model to derive the SMM vector given each Key Rate shift
# =======================================================================
# Key Rate Shift Down Prepayment Model and CashFlows
# ======================================================================
Prepayment.Dwn <- PrepaymentModel(
bond.id = bond.id,
MortgageRate = MortgageRate,
TermStructure = Key.Rate.TS.Dwn,
PrepaymentAssumption = "MODEL",
ModelTune = ModelTune,
Burnout = Burnout,
Severity = 0)
# Mortgage Cashflows call here requires that price as whole number passed
# Always use sprintf("%.8f", PriceDecimal(Price)) to convert back to string
# and preserve the trailing zeros that are needed for the PriceTypes function
# when price when the price tail is .000 or "-00"
MortgageCashFlows.Dwn <- MortgageCashFlow(
bond.id = bond.id,
original.bal = original.bal,
settlement.date = settlement.date,
price = sprintf("%.8f", PriceDecimal(Price)),
PrepaymentAssumption = Prepayment.Dwn)
# Assign CashFlows into the cash flow array. This has to be done in a loop
for(cfd in 1:600){
if(cfd > as.numeric(length(MortgageCashFlows.Dwn@TotalCashFlow))) {
CashFlowArray[cfd,"cashflow_dwn"] = 0
} else {
CashFlowArray[cfd,"cashflow_dwn"] =
MortgageCashFlows.Dwn@TotalCashFlow[cfd]}
}
# ============================================================
# Key Rate Shift Up Prepayment Model and CashFlows
# ==============================================================
Prepayment.Up <- PrepaymentModel(
bond.id = bond.id,
MortgageRate = MortgageRate,
TermStructure = Key.Rate.TS.Up,
PrepaymentAssumption = "MODEL",
ModelTune = ModelTune,
Burnout = Burnout,
Severity = 0)
# Mortgage Cashflows call here requires that price as
# a whole number passed
MortgageCashFlows.Up <- MortgageCashFlow(
bond.id = bond.id,
original.bal = original.bal,
settlement.date = settlement.date,
price = sprintf("%.8f", PriceDecimal(Price)), #price.mtg.cashflow,
PrepaymentAssumption = Prepayment.Up)
# Assign CashFlows into the cash flow array.
# This has to be done in a loop
for(cfu in 1:600){
if(cfu > as.numeric(length(MortgageCashFlows.Up@TotalCashFlow))) {
CashFlowArray[cfu,"cashflow_up"] = 0
} else {
CashFlowArray[cfu,"cashflow_up"] =
MortgageCashFlows.Up@TotalCashFlow[cfu]}
}
# Calculate Key Rate Duration
KR.Duration[w-1,2] <- -EffectiveMeasures(
rate.delta = Rate.Delta/yield.basis,
cashflow = CashFlowArray[,"cashflow_nc"],
cashflow.dwn = CashFlowArray[,"cashflow_dwn"],
cashflow.up = CashFlowArray[,"cashflow_up"],
discount.rates = Key.Rate.Table[,"Disc Curve"],
discount.rates.up = Key.Rate.Table[,"KRUp"],
discount.rates.dwn = Key.Rate.Table[,"KRDwn"],
t.period = Key.Rate.Table[,"Time"],
proceeds = proceeds,
type = "duration"
)
KR.Duration[w-1,3] <- EffectiveMeasures(
rate.delta = Rate.Delta/yield.basis,
cashflow = CashFlowArray[,"cashflow_nc"],
cashflow.dwn = CashFlowArray[,"cashflow_dwn"],
cashflow.up = CashFlowArray[,"cashflow_up"],
discount.rates = Key.Rate.Table[,"Disc Curve"],
discount.rates.up = Key.Rate.Table[,"KRUp"],
discount.rates.dwn = Key.Rate.Table[,"KRDwn"],
t.period = Key.Rate.Table[,"Time"],
proceeds = proceeds,
type = "convexity"
)
} # Outer Loop around KRIndex
new("MortgageTermStructure",
Cusip = Cusip(bond.id),
Issuer = Issuer(bond.id),
Coupon = Coupon(bond.id),
Term = AmortizationTerm(bond.id),
#ZeroVolSpread = spot.spread * 100,
EffDuration = sum(KR.Duration[,"Key Rate Duration"]),
EffConvexity = sum(unname(KR.Duration[,"Key Rate Convexity"]) * .5),
KeyRateTenor = unname(KR.Duration[,"Key Rate"]),
KeyRateDuration = unname(KR.Duration[,"Key Rate Duration"]),
KeyRateConvexity = unname(KR.Duration[,"Key Rate Convexity"])
)
} # End the function
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.