Как рассчитать подразумеваемую волатильность в R - PullRequest
5 голосов
/ 21 апреля 2019

Я пытаюсь создать свою собственную функцию в R на основе переменных черного Шоулза и решить «назад», я полагаю, для сигмы.

Я создал функцию для поиска цены звонка;однако теперь я должен найти сигма (подразумеваемую волатильность) оценки в R и затем проверить свою функцию, чтобы увидеть, работает ли она ... Я пробовал разные функции, но я не могу понять, что я делаю неправильно, частьЯ думаю, мне нужно знать сигму, чтобы найти сигму, но я не уверен, имеет ли это смысл.

Вот функция, которую я создал по цене европейского опциона в модели Блэка Шоулза:

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 <- 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)

Тот же формат, но я не могу понять это.Мне нужно включить диапазон или последовательность, чтобы найти сигму?

Я пробовал это, но я не верю, что мы должны включить '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 <- 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 ]

2 голосов
/ 21 апреля 2019

В библиотеке 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 = Обобщенная модель Блэка Шоулза

GBSVolatility(price, TypeFlag, S, X, Time, r, b, tol, maxiter)
BlackScholesOption(...)

См. Книгу Эспена Хауга 1997,2007 Полная оценка опционов; для алгоритмов в MS Excel VBA.

1 голос
/ 23 апреля 2019

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

Основано на финансовом моделировании Симона Бенинга в Excel, аналогично методам Пола Уилмота и Эспена Хауга в их соответствующих книгах, но они не полагаются на функции нормальной кривой Excel, но используют высокоэффективные и точные функции аппроксимации нормального распределения. В остальном почти так же. Espen Haug Полное руководство по опциям Ценообразование формул 2007 Пол Уилмот Введение в количественные финансы. Все три книги реализуют формулы в Excel, я думаю, на прикрепленном диске к Хаугу он также имеет реализацию на С ++. Это действительно простая задача для преобразования в R, извините, я этого не делал, я использую встроенные методы, упомянутые выше, fOptions или Rquantlib, вы должны проверить свою реализацию на соответствие выводу этих данных для точности и правильности.

1 голос
/ 21 апреля 2019

Вы можете использовать функцию 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, поэтому лучше не называть ваши переменные сигмой.

...