|
1 | | -#' Hagan approximation for the SABR model |
| 1 | +#' Calculate the equivalent BS volatility (Hagan et al. 2002) for |
| 2 | +#' the Stochatic-Alpha-Beta-Rho (SABR) model |
2 | 3 | #' |
3 | 4 | #' @param strike (vector of) strike price |
4 | 5 | #' @param spot (vector of) spot price |
5 | 6 | #' @param texp (vector of) time to expiry |
6 | 7 | #' @param sigma (vector of) volatility |
7 | | -#' @param vov vol-of-vol |
8 | | -#' @param rho correlation |
9 | | -#' @param beta beta |
| 8 | +#' @param vov (vector of) vol-of-vol |
| 9 | +#' @param rho (vector of) correlation |
| 10 | +#' @param beta (vector of) beta |
10 | 11 | #' @param intr interest rate |
11 | 12 | #' @param divr dividend rate |
12 | | -#' @param cpsign call/put sign. NULL for BS vol (default), 1 for call price, -1 for put price. |
| 13 | +#' @param cp call/put sign. \code{NULL} for BS vol (default), \code{1} for call price, \code{-1} for put price. |
13 | 14 | #' @param forward forward price. If given, \code{forward} overrides \code{spot} |
14 | 15 | #' @param df discount factor. If given, \code{df} overrides \code{intr} |
15 | | -#' @return BS volatility or option price based on cpsign |
| 16 | +#' @return BS volatility or option price based on \code{cp} |
16 | 17 | #' |
17 | | -#' @references Hagan, P. S., Kumar, D., Lesniewski, A. S., & Woodward, D. E. (2002). Managing Smile Risk. Wilmott, September, 84–108. |
| 18 | +#' @references Hagan, P. S., Kumar, D., Lesniewski, A. S., & Woodward, D. E. (2002). |
| 19 | +#' Managing Smile Risk. Wilmott, September, 84-108. |
18 | 20 | #' |
19 | 21 | #' @export |
20 | 22 | #' |
|
26 | 28 | #' texp <- 10 |
27 | 29 | #' strike <- seq(0.1, 2, 0.1) |
28 | 30 | #' FER::SabrHagan2002(strike, 1, texp, sigma, vov, rho, beta) |
| 31 | +#' FER::SabrHagan2002(strike, 1, texp, sigma, vov, rho, beta, cp=1) |
29 | 32 | #' |
30 | 33 | SabrHagan2002 <- function( |
31 | | - strike = forward, spot, texp = 1, sigma, vov=0, rho=0, beta=1, |
32 | | - intr = 0, divr = 0, cpsign = NULL, |
33 | | - forward = spot*exp(-divr*texp)/df, |
34 | | - df = exp(-intr*texp) |
| 34 | + strike=forward, spot, texp=1, sigma, vov=0, rho=0, beta=1, |
| 35 | + intr=0, divr=0, cp=NULL, |
| 36 | + forward=spot*exp(-divr*texp)/df, df=exp(-intr*texp) |
35 | 37 | ){ |
36 | 38 | betac <- 1 - beta |
| 39 | + betac2 <- betac*betac |
| 40 | + rho2 <- rho*rho |
| 41 | + |
37 | 42 | powFwdStrk <- (forward*strike)^(betac/2) |
38 | 43 | logFwdStrk <- log(forward/strike) |
39 | 44 | logFwdStrk2 <- logFwdStrk^2 |
40 | 45 |
|
41 | | - pre1 = powFwdStrk*( 1 + betac^2/24 * logFwdStrk2*(1 + betac^2/80 * logFwdStrk2) ) |
| 46 | + pre1 <- powFwdStrk*( 1 + betac2/24 * logFwdStrk2*(1 + betac2/80 * logFwdStrk2) ) |
42 | 47 |
|
43 | | - pre2alp0 <- (2-3*rho^2)*vov^2/24 |
| 48 | + pre2alp0 <- (2-3*rho2)*vov^2/24 |
44 | 49 | pre2alp1 <- vov*rho*beta/4/powFwdStrk |
45 | | - pre2alp2 <- betac^2/24/powFwdStrk^2 |
| 50 | + pre2alp2 <- betac2/24/powFwdStrk^2 |
46 | 51 |
|
47 | 52 | pre2 <- 1 + texp*( pre2alp0 + sigma*(pre2alp1 + pre2alp2*sigma) ) |
48 | 53 |
|
49 | 54 | zz <- powFwdStrk*logFwdStrk*vov/sigma # need to make sure sig > 0 |
50 | 55 | yy <- sqrt(1 + zz*(zz-2*rho)) |
51 | 56 |
|
52 | | - rho2 <- rho*rho |
53 | | - xx_zz = 1 + (zz/2)*(rho + zz*((rho2-1/3) + (5*rho2-3)/4*rho*zz)) |
| 57 | + xx_zz <- 1 + (zz/2)*(rho + zz*((rho2-1/3) + (5*rho2-3)/4*rho*zz)) |
54 | 58 |
|
55 | 59 | I <- (zz >= 1e-5) |
56 | | - xx_zz[I] = log( (yy[I] + (zz[I]-rho))/(1-rho) ) / zz[I] |
| 60 | + xx_zz[I] <- log( (yy[I] + (zz[I]-rho))/(1-rho) ) / zz[I] |
57 | 61 | I <- (zz <= -1e-5) |
58 | | - xx_zz[I] = log( (1+rho)/(yy[I] - (zz[I]-rho)) ) / zz[I] |
| 62 | + xx_zz[I] <- log( (1+rho)/(yy[I] - (zz[I]-rho)) ) / zz[I] |
59 | 63 |
|
60 | | - vol.bs = sigma*pre2/(pre1*xx_zz) # blks vol |
| 64 | + vol.bs <- sigma*pre2/(pre1*xx_zz) # BS volatility |
61 | 65 |
|
62 | | - if(is.null(cpsign)){ |
| 66 | + if(is.null(cp)){ |
63 | 67 | return(vol.bs) |
64 | 68 | } else { |
65 | | - p <- BlackScholesPrice(strike, forward, texp, vol.bs, cpsign=cpsign) |
66 | | - return(df*p) |
| 69 | + # if cp is specified, calculate option price |
| 70 | + p <- df * BlackScholesPrice(strike, forward, texp, sigma=vol.bs, cp=cp) |
| 71 | + return(p) |
67 | 72 | } |
68 | 73 | } |
0 commit comments