如何计算R中的隐含波动率

时间:2019-04-21 01:45:03

标签: r finance quantitative-finance

我正在尝试基于黑色scholes变量在R中创建自己的函数,并解决sigma的“后退”问题。

我创建了一个函数来查找通话价格;但是,现在我必须在R中找到sigma(隐含波动率)估计值,然后测试我的函数以查看它是否有效...我尝试了不同的函数,但似乎无法弄清楚我做错了什么,这是我认为我需要了解sigma才能找到sigma,但我不确定这是否有意义。

这是我为Black Scholes模型中的欧式看涨期权的价格创建的函数:

call <- function(s0, K, r, T, sigma) {
  d1 <- (log(s0/K) + (r + sigma^2/2)*T) / (sigma*sqrt(T))
  d2 <- d1 - sigma*sqrt(T
  c <- s0*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
  c
}

我测试了我的函数,看它是否可以与不同的代码一起正常工作:

call(100, 70, 0.05, 1, 0.16)
[1] 33.43686

call(300, 280, 0.03, 3, 0.18)
[1] 60.81694

call(400, 350, 0.04, 5, 0.20)
[1] 133.1626

现在,我需要使用以下函数来找到sigma:

    sigma <- function(call, s0, K, r, T) {

???
    }

创建函数后,需要使用以下命令对其进行测试:

sigma(33.43686, 100, 70, 0.05, 1)

sigma(60.81694, 300, 280, 0.03, 3)

sigma(133.1626, 400, 350, 0.04, 5)

相同的格式,但我无法弄清楚。我需要包含一个范围或序列才能找到sigma吗?

我已经尝试过了,但是我不认为我们应该在函数中包含'v'

sigma <- function(call, s0, K, r, T, v) {
  d1 <- (log(s0/K) + (r + v^2/2)*T) / (v*sqrt(T))
  d2 <- d1 - v*sqrt(T)
  c <- s0*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
  sigma_value <- d1 - d2 / sqrt(T)
  sigma_value
}

sigma(33.43686, 100, 70, 0.05, 1, 0.16) 
[1] 0.16
sigma(60.81694, 300, 280, 0.03, 3, 0.18)
[1] 0.4614232
sigma(133.1626, 400, 350, 0.04, 5, 0.20)
[1] 0.7358743

0.16是“ sigma”,我正在尝试通过创建自己的函数来找到接近于此的估算值。

我也觉得我的sigma离我们很远

我也尝试过:

sigma <- function(call, s0, K, r, T) {
  v = seq(from = 0.1, to = .2, by = .01)
  k.range = floor(seq(from = 100, to = 400, length.out = length(v)))
  for (i in 1:length(v)) {
    d1 <- (log(s0/K[i]) + (r + (v^2)/2) * T) / (v * sqrt(T))
    d2 <- d1 - v * sqrt(T)
    C  <- s0 * pnorm(d1) - K[i] * exp(-r*T) * pnorm(d2) - call[i]
  }
  v
}

在功能方面的任何帮助都将非常有用。谢谢

3 个答案:

答案 0 :(得分:1)

RQuant库中有一个内置的隐含波动率函数 例如。

AmericanOptionImpliedVolatility(type="call", value=11.10, underlying=100,
    strike=100, dividendYield=0.01, riskFreeRate=0.03,
    maturity=0.5, volatility=0.4)

它也是fOptions软件包中的一个函数, GBS波动率 返回给定价格的GBS期权隐含波动率。 GBS =广义Black Scholes模型

GBSVolatility(price, TypeFlag, S, X, Time, r, b, tol, maxiter)
BlackScholesOption(...)
参见Espen Haug的书1997,2007,完整的期权定价;用于MS excel VBA中的算法。

答案 1 :(得分:0)

您可以使用uniroot函数查找隐含波动率。 uniroot查找函数的根。 这是使用方法。

call_fun <- function(s0, K, r, TT, sig) {
  d1 <- (log(s0/K) + (r + sig^2/2)*TT) / (sig*sqrt(TT))
  d2 <- d1 - sig*sqrt(TT)
  s0*pnorm(d1) - K*exp(-r*TT)*pnorm(d2)

}

sig_impl <- function(s0, K, r, TT, .c) {
  root_fun <- function(sig){
    call_fun(s0, K, r, TT, sig) - .c
  }

  uniroot(root_fun, c(0, 1))$root
}
call_fun(100, 70, 0.05, 1, 0.16)
[1] 33.43686
sig_impl(100, 70, 0.05, 1, 33.43686)
[1] 0.1599868

请注意,我更改了一些变量名称:T通常是为TRUE保留的,因此您不应命名变量T。此外,还有一个名为sigma的函数,因此最好不要将变量sigma命名。

希望这会有所帮助。

答案 2 :(得分:0)

Uniroot是一种可能的传统求解方程式的方法是牛顿梯度法或更简单的二分搜索法,这是行业标准,我将为标准方法发布伪代码

 function ImpliedCallVolatility(UnderlyingPrice, ExercisePrice, Time, Interest, Target, Dividend)
High = 5
LOW = 0
Do While (High - LOW) > 0.0001
If CallOption(UnderlyingPrice, ExercisePrice, Time, Interest, (High + LOW) / 2, Dividend) > Target Then
High = (High + LOW) / 2
Else: LOW = (High + LOW) / 2
End If
Loop
ImpliedCallVolatility = (High + LOW) / 2
End Function

Function ImpliedPutVolatility(UnderlyingPrice, ExercisePrice, Time, Interest, Target, Dividend)
High = 5
LOW = 0
Do While (High - LOW) > 0.0001
If PutOption(UnderlyingPrice, ExercisePrice, Time, Interest, (High + LOW) / 2, Dividend) > Target Then
High = (High + LOW) / 2
Else: LOW = (High + LOW) / 2
End If
Loop
ImpliedPutVolatility = (High + LOW) / 2
End Function

基于Simon Beninga的Excel财务建模,类似于各自书中的Paul Willmot和Espen Haugs方法,但是它们不依赖Excel的正态曲线函数,而是使用高效且准确的正态分布近似函数。否则大体相同。 Espen Haug期权定价公式的完整指南2007 Paul Willmot量化金融概论。 所有三本书都在excel中实现了公式,我相信在Haug附带的磁盘中,他也具有c ++实现。 转换为R确实是一个简单的任务,对不起,我还没有做,我使用上面提到的内置方法fOptions或Rquantlib,您应该针对这些输出的准确性和正确性来测试实现。