Skip to content

Commit

Permalink
Issue #17, increase test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
hudde committed Nov 3, 2023
1 parent 5d2641a commit 119e3ab
Showing 1 changed file with 79 additions and 15 deletions.
94 changes: 79 additions & 15 deletions tests/testthat/test-BS_Malliavin_Asian_Greeks.R
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
test_that("BS_Malliavin_Asian_Greeks is correct", {

# We check the Greeks by also computing the derivative with finite difference
# and comparing the results

number_of_runs <- 2

definition_of_greeks <-
data.frame(greek = "delta", start = "fair_value", param = "initial_price") %>%
add_row(greek = "rho", start = "fair_value", param = "r") %>%
add_row(greek = "vega", start = "fair_value", param = "volatility")

# We check the Greeks by also computing the derivative with finite difference
# and comparing the results

# We start with checking delta

number_of_runs <- 10

error <- numeric(number_of_runs)

set.seed(42)
Expand All @@ -20,12 +22,79 @@ test_that("BS_Malliavin_Asian_Greeks is correct", {
initial_price <- runif(1, 90, 110)
exercise_price <- runif(1, 90, 110)
r <- runif(1, -0.01, 0.1)
time_to_maturity <- runif(1, 0.2, 6)
time_to_maturity <- runif(1, 0.2, 2)
dividend_yield <- runif(1, 0, 0.1)
volatility <- runif(1, 0.01, 1)
model <- "Black_Scholes"
payoff <- rep(c("call", "put"), 3)[i]
greek <- rep(c("delta"), 2)[i]
payoff <- rep(c("call", "put"), number_of_runs)[i]
greek <- "delta"
param <- "initial_price"
start <- "fair_value"

Vals <-
BS_Malliavin_Asian_Greeks(
initial_price = initial_price,
exercise_price = exercise_price,
r = r,
time_to_maturity = time_to_maturity,
volatility = volatility,
dividend_yield = dividend_yield,
payoff = payoff,
greek = greek
)

F <- function(epsilon) {
assign(param,
c(get(param) + 2*epsilon, get(param) + epsilon,
get(param) - 2*epsilon, get(param) - epsilon))
BS_Malliavin_Asian_Greeks(
initial_price = initial_price,
exercise_price = exercise_price,
r = r,
time_to_maturity = time_to_maturity,
volatility = volatility,
dividend_yield = dividend_yield,
payoff = payoff,
greek = start
)
}

epsilon <- initial_price * 0.1

F_eps <- F(epsilon)

# We compute the derivative by Richardsons' extrapolation

Vals_fd <- (-F_eps[1] + 8*F_eps[2] - 8*F_eps[3] + F_eps[4]) / (12 * epsilon)

error[i] <-
min(abs(Vals - Vals_fd)/(abs(Vals + epsilon)),
abs(Vals - Vals_fd))

}

expect(max(error) < 0.1, "BS_Malliavin_Asian_Greeks: Delta error too high")

# Now, we check rho and vega

number_of_runs <- 4

set.seed(42)

error <- numeric(number_of_runs)

for(i in 1:number_of_runs) {

# the parameters are chosen at random
initial_price <- runif(1, 90, 110)
exercise_price <- runif(1, 90, 110)
r <- runif(1, 0.01, 0.1)
time_to_maturity <- runif(1, 0.2, 2)
dividend_yield <- 0
volatility <- runif(1, 0.01, 1)
model <- "Black_Scholes"
payoff <- rep(c("call", "put"), number_of_runs)[i]
greek <- c("rho", "rho", "vega", "vega")[i]
param <-
definition_of_greeks[definition_of_greeks$greek == greek, "param"] %>%
as.character()
Expand All @@ -47,11 +116,6 @@ test_that("BS_Malliavin_Asian_Greeks is correct", {
steps = 12
)

## theta is minus the derivative of fair_value w.r.t. time_to_maturity
if (greek == "theta") {
Vals = -Vals
}

F <- function(epsilon) {
assign(param, get(param) + epsilon)
BS_Malliavin_Asian_Greeks(
Expand All @@ -72,13 +136,13 @@ test_that("BS_Malliavin_Asian_Greeks is correct", {

Vals_fd <- (F(epsilon) - F(-epsilon)) / (2 * epsilon)


error[i] <-
min(abs(Vals - Vals_fd)/(abs(Vals + epsilon)),
abs(Vals - Vals_fd))

}

expect(max(error) < 0.1)
expect(max(error) < 0.01,
paste0("BS_Malliavin_Asian_Greeks: ", greek, " error too high"))

})

0 comments on commit 119e3ab

Please sign in to comment.