[英]How to calculate implied volatility in R
我试图在R中基于黑色scholes变量创建我自己的函数并解决“向后”我想为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”我试图通过创建自己的函数来找到接近此的估计值。
我也觉得我的sigmas离他们应该是
我也尝试过:
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
}
任何关于功能方面的帮助都会很棒。 谢谢
RQuant库中有一个内置的隐含波动率函数,例如。
AmericanOptionImpliedVolatility(type="call", value=11.10, underlying=100,
strike=100, dividendYield=0.01, riskFreeRate=0.03,
maturity=0.5, volatility=0.4)
它也是fOptions包中的一个函数,GBSVolatility返回给定价格的GBS期权隐含波动率。 GBS =广义Black Scholes模型
GBSVolatility(price, TypeFlag, S, X, Time, r, b, tol, maxiter)
BlackScholesOption(...)
见Espen Haug书籍1997,2007完整期权定价; 用于MS excel VBA中的算法。
您可以使用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。
Uniroot是一种可能性,解决方程的传统方法是使用牛顿梯度法或更简单的双截面搜索,这是行业标准我会发布psuedocode用于标准方法
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中实现了公式,我相信在附加的磁盘中他还有一个c ++实现。 转换为R真的是一个简单的任务,对不起我没有这样做,我使用上面提到的内置方法,fOptions或Rquantlib,你应该根据这些的输出测试你的实现的准确性和正确性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.