|
| 1 | +SabrHagan2002 <- function( |
| 2 | + strike, spot, t.exp=1, sigma=0.01, vov=0, rho=0, beta=1, |
| 3 | + r = 0, div = 0, type="BlackScholes" |
| 4 | +){ |
| 5 | + |
| 6 | + forward = spot*exp((r-div)*t.exp) |
| 7 | + betac <- 1 - beta |
| 8 | + powFwdStrk <- (forward*strike)^(betac/2) |
| 9 | + logFwdStrk <- log(forward/strike) |
| 10 | + logFwdStrk2 <- logFwdStrk^2 |
| 11 | + |
| 12 | + pre1 = powFwdStrk*( 1 + betac^2/24 * logFwdStrk2*(1 + betac^2/80 * logFwdStrk2) ) |
| 13 | + |
| 14 | + pre2alp0 <- (2-3*rho^2)*vov^2/24 |
| 15 | + pre2alp1 <- vov*rho*beta/4/powFwdStrk |
| 16 | + pre2alp2 <- betac^2/24/powFwdStrk^2 |
| 17 | + |
| 18 | + pre2 <- 1 + t.exp*( pre2alp0 + sigma*(pre2alp1 + pre2alp2*sigma) ) |
| 19 | + |
| 20 | + zz <- powFwdStrk*logFwdStrk*vov/sigma # need to make sure sig > 0 |
| 21 | + yy <- sqrt(1 + zz*(zz-2*rho)) |
| 22 | + |
| 23 | + xx_zz <- rep(0, length(strike)) |
| 24 | + |
| 25 | + I <- (abs(zz) < 1e-5) |
| 26 | + xx_zz[I] = 1 + (rho/2)*zz[I] + (1/2*rho^2-1/6)*zz[I]^2 + 1/8*(5*rho^2-3)*rho*zz[I]^3 |
| 27 | + I <- (zz >= 1e-5) |
| 28 | + xx_zz[I] = log( (yy[I] + (zz[I]-rho))/(1-rho) ) / zz[I] |
| 29 | + I <- (zz <= -1e-5) |
| 30 | + xx_zz[I] = log( (1+rho)/(yy[I] - (zz[I]-rho)) ) / zz[I] |
| 31 | + |
| 32 | + volBlks = sigma*pre2/(pre1*xx_zz) # blks vol |
| 33 | + |
| 34 | + if(type=="BlackScholes"){ |
| 35 | + return(volBlks) |
| 36 | + } else if(type=="call" || type=="put") { |
| 37 | + p <- BlackScholesPrice( |
| 38 | + type=type, spot=spot, strike=strike, t.exp=t.exp, sigma=volBlks, |
| 39 | + r=r, div=div |
| 40 | + ) |
| 41 | + return(p) |
| 42 | + } |
| 43 | +} |
0 commit comments