4. Using Monoids to compute interest rate risk
p = sum(payment * exp(-rt))
... where r is the interest rate and t the time in years
dp/dr = sum(-t*payment * exp(-rt))
implicit val sensitivityMonoid: Monoid[Double] = new Monoid[Double] {
def empty: Double = 0.0
def combine(sensitivity1: Double, sensitivity2: Double): Double =
sensitivity1 + sensitivity2
}
def combineAll(sensitivities: List[Double]): Double =
sensitivities.foldLeft(Monoid[Double].empty)(Monoid[Double].combine)
case class Payment(date: LocalDate, amount: Double)
def periodInYears(from:LocalDate, to:LocalDate) : Double = {
from.until(to, ChronoUnit.DAYS)/365.0
}
def sensitivity(valuationDate: LocalDate, rate: Double, payment: Payment) = {
val time = periodInYears(valuationDate, payment.date)
payment.amount*time*Math.exp(-rate * time)
}
def sensitivity(payments:List[Payment], rate:Double, valuationDate:LocalDate) :
Double = {
val sensitivities = payments.map(cf => sensitivity(valuationDate, rate, cf))
combineAll(sensitivities)
}
def main(args: Array[String]) = {
val payments = List(
Payment(LocalDate.of(2025, 6, 7), 5),
Payment(LocalDate.of(2025, 12, 7), 105))
println(totalSensitivity(payments, 0.055, LocalDate.of(2024, 6, 7)))
}
Last updated