tests/testthat/test-forward.R

test_that("yc_forward computes instantaneous forwards", {
  d <- make_us_yields()
  fit <- yc_nelson_siegel(d$maturities, d$rates)
  fwd <- yc_forward(fit)
  expect_equal(nrow(fwd), length(d$maturities))
  expect_true(all(c("maturity", "forward_rate") %in% names(fwd)))
  # Forward rates should be in a reasonable range
  expect_true(all(fwd$forward_rate > 0 & fwd$forward_rate < 0.10))
})

test_that("yc_forward computes forward-forward rates", {
  d <- make_us_yields()
  fit <- yc_nelson_siegel(d$maturities, d$rates)
  fwd <- yc_forward(fit, maturities = c(1, 2, 5), horizon = 1)
  expect_equal(nrow(fwd), 3)
})

test_that("yc_forward at custom maturities", {
  d <- make_us_yields()
  fit <- yc_nelson_siegel(d$maturities, d$rates)
  fwd <- yc_forward(fit, maturities = c(1, 5, 10))
  expect_equal(fwd$maturity, c(1, 5, 10))
})

test_that("yc_forward NS analytical matches numerical", {
  d <- make_us_yields()
  fit <- yc_nelson_siegel(d$maturities, d$rates)

  # Analytical forward at specific maturities
  fwd_analytical <- yc_forward(fit, maturities = c(2, 5, 10))

  # Numerical forward via finite difference on spot * maturity
  m <- c(2, 5, 10)
  dm <- 1e-6
  r <- yc_predict(fit, m)$rate
  r_plus <- yc_predict(fit, m + dm)$rate
  fwd_numerical <- (r_plus * (m + dm) - r * m) / dm

  expect_equal(fwd_analytical$forward_rate, fwd_numerical, tolerance = 1e-4)
})

test_that("yc_forward works with observed curve", {
  d <- make_simple_yields()
  curve <- yc_curve(d$maturities, d$rates)
  fwd <- yc_forward(curve)
  expect_equal(nrow(fwd), length(d$maturities))
})

test_that("yc_forward Svensson analytical matches numerical", {
  d <- make_us_yields()
  fit <- yc_svensson(d$maturities, d$rates)

  fwd_analytical <- yc_forward(fit, maturities = c(2, 5, 10))

  m <- c(2, 5, 10)
  dm <- 1e-6
  r <- yc_predict(fit, m)$rate
  r_plus <- yc_predict(fit, m + dm)$rate
  fwd_numerical <- (r_plus * (m + dm) - r * m) / dm

  expect_equal(fwd_analytical$forward_rate, fwd_numerical, tolerance = 1e-4)
})

test_that("yc_forward rejects non-curve", {
  expect_error(yc_forward(list()), "yc_curve")
})

Try the yieldcurves package in your browser

Any scripts or data that you put into this service are public.

yieldcurves documentation built on March 26, 2026, 5:06 p.m.