I have the following script called test.R where I input variable values and then I call functions I wrote in SABR.R to calculate certain values.
However, when I run the code, I keep on getting errors such as Error: could not find function SABR.BSIV Error: could not find function SABR.calibration
What am I doing wrong here? It also says "object k not found" even though I very clearly declared it in my test.R code.
library(testthat)
source("SABR.R")
test_that("SABR Model Test", {
iv <- c(0.346, 0.280, 0.243, 0.208, 0.203, 0.192, 0.192, 0.201, 0.205, 0.223, 0.228, 0.247, 0.252, 0.271, 0.275, 0.293, 0.313)
k <- c(12.0, 15.0, 17.0, 19.5, 20.0, 22.0, 22.5, 24.5, 25.0, 27.0, 27.5, 29.5, 30.0, 32.0, 32.5, 34.5, 37.0)
f <- 22.724
t <- 0.583
a <- 0.317
b <- 0.823
r <- 0.111
n <- 1.050
iv.model <- SABR.BSIV(t, f, k, a, b, r, n)
params <- SABR.calibration(t, f, k, iv)
iv.calibrated <- SABR.BSIV(t, f, k, params[1], params[2], params[3], params[4])
# Check whether initial model can produce market IV or not
for(i in length(k)){expect_equal(iv.model[i], iv[i], tolerance = 0.01*iv[i])}
# Check whether calibrated parameter can produce market IV or not
for(i in length(k)){expect_equal(iv.calibrated, iv[i], tolerance = 0.01*iv[i])}
})
Here is the SABR.R code:
EPS <- 10^(-8)
# Sub function for SABR BS-IV (Black-Scholes IV?)
.x <- function(z, r){log((sqrt(1-2*r*z+z^2)+z-r)/(1-r))}
.z <- function(f, k, a, b, nu){nu/a*(f*k)^(0.5*(1-b))*log(f/k)}
# Variable transformation function
.t1 <- function(x){1/(1+exp(x))}
.t2 <- function(x){2/(1+exp(x)) -1}
# Black-Scholes IV apporoximation formula by Hagan
SABR.BSIV <- function(t, f, k, a, b, r, n)
{
z <- .z(f, k, a, b, n)
x <- .x(z, r)
numerator <- 1 + ((1-b)^2/24*a^2/(f*k)^(1-b) + 0.25*r*b*n*a/(f*k)^(0.5*(1-b)) + (2-3*r^2)*n^2/24)*t
denominator <- x*(f*k)^(0.5*(1-b))*(1 + (1-b)^2/24*(log(f/k))^2 + (1-b)^4/1920*(log(f/k))^4)
ifelse(abs((f-k)/f) < EPS, a*numerator/f^(1-b), z*a*numerator/denominator)
}
# Parameter calibration function for SABR
SABR.calibration <- function(t, f, k, iv)
{
# Objective function for optimization, variables are transformed because of satisfing the constraint conditions
objective <- function(x){sum( (iv - SABR.BSIV(t, f, k, exp(x[1]), .t1(x[2]), .t2(x[3]), exp(x[4])))^2) }
x <- nlm(objective, c(0.25, 0.5, 0.5, 0.5))
# Return optimized parameters
parameter <- x$estimate
parameter <- c(exp(parameter[1]), .t1(parameter[2]), .t2(parameter[3]), exp(parameter[4]))
names(parameter) <- c("Alpha", "Beta", "Rho", "Nu")
parameter
}