anatolyutkin
anatolyutkin личный блог
25 апреля 2014, 12:01

Некоторые быстрые методы работы с формулой Блэка-Шоулса

При торговле опционами весьма неплохо знать и понимать теорию Блэка и Шоулса. Можно, конечно, смотреть профили позиций и прочее на многочисленных специальных сервисах типа www.option.ru, но, как известно, хочешь сделать хорошо--сделай все сам. В применении к опционам это вполне правильная вещь--не стоит доверять сторонним сервисам. Не потому, что они плохи (они обычно вполне корректно все рассчитывают), а потому, что опционы надо чувствовать.

Краткая и лаконичная суть теории Блэка и Шоулса изложена здесь: http://anatoly-utkin.livejournal.com/2835.html . Ничего сложного в ней нет, это просто теория эффективного рынка в применении к опционам, не более. В настоящей заметке я хотел бы привести некоторые быстрые расчетные методы для работы с формулой Блэка-Шоулса, позволяющие быстро находить цены опционов и IV.


Итак, формула Блэка-Шоулса имеет вид: C=KN(d1)-SN(d2)  ( Wikipedia ). Первое, что тут есть из нетривиального--это функция N(x)--функция нормального распределения. В трейдерской тусовке модно аппроксимировать N(x) полиномом, однако мне это режет глаз, поскольку при этом не выполнено экспоненциальное стремление N(x) к единице на плюс бесконечности и к нулю на минус бесконечности. Поэтому такая метода мне абсолютно не нравится.



Вообще, N(x)--это интеграл от простой и имеющейся во всех приличных языках программирования экспоненциальной функции exp(-x^2). Однако, влобовую брать интегралы через интегральные суммы--дело накладное в плане вычислительных мощностей. Для нормального распределения существует множество асимптотических формул. Одну из них--так называемый T алгоритм--я и использую. Математическое описание T алгоритма: http://algolist.manual.ru/maths/matstat/NormalDF/NormalDF1.php
Код VBA:

Function FERT(x As Single) As Single
Dim i%, n%
Dim S!, T!, s1!, x2!, epsilon!
epsilon = 0.00001
s1 = 0
T = Abs(x)
s1 = T
x2 = x ^ 2
n = 3
For i = 0 To 100
   T = x ^ 2 * T / n
   S = s1
   s1 = S + T
   n = n + 2
   If Abs(S — s1) < epsilon Then GoTo 10
   Next i
10   If x >= 0 Then FERT = 0.5 + s1 * NORM(x)
If x < 0 Then FERT = 0.5 — s1 * NORM(x)
'FERT = FERT — 0.5
If x < -10 Then FERT = 0
If x > 10 Then FERT = 1
End Function

Здесь NORM(x)=1/sqrt(2pi)*exp(-x^2/2)--плотность единичного нормального распределения, ее код:

Function NORM(x As Single) As Single
NORM = Exp(-x ^ 2 / 2) / (2 * 3.1415926) ^ (0.5)
End Function


Вторая нетривиальная и часто нужная вещь в формуле БШ--это как найти волатильность при известной цене опциона. Иными словами, нужно обратить формулу Блэка-Шоулса и найти в ней величину z=sigma*sqrt(T) по известным C, K, S. Для этого я использую метод Ньютона ( Wikipedia ). Введем вспомогательную функцию g(z)=KN(d1)-SN(d2)-C. Тогда искомая величина z будет решением уравнения g(z)=0. g(z)--это хорошая, аналитическая, достаточно плавная функция своего аргумента. Поэтому метод Ньютона для нее будет работать хорошо. Суть метода Ньютона неплохо поясняет картинка ниже:
Некоторые быстрые методы работы с формулой Блэка-Шоулса















а его итерационная формула имеет простой вид: z_next=z-f(z)/(df/dz(z)).Особую прелесть именно методу Ньютона в применении к формуле Блэка-Шоулса придает тот факт, что производная от C по волатильности (так называемая вега) имеет простой вид S*NORM(d1)*sqrt(T). Код VBA:

Function IV_C(S As Single, K As Single, C As Single) As Single
Dim x!, x_next!, f!, df!, epsilon!
Dim i%, i_max%
epsilon = 0.00001
x = 0.5
i_max = 15
For i = 1 To i_max
   f = C — S * FERT((Log(S / K) + x ^ 2 / 2) / x) + K * FERT((Log(S / K) — x ^ 2 / 2) / x)
   df = -S * NORM((Log(S / K) + x ^ 2 / 2) / x)
   x_next = x — f / df
   If (Abs(x — x_next)) < epsilon Then GoTo 20
   x = x_next
   Next i
20 IV_C = x
End Function

Ну и напоследок общий финальный код VBA, объединяющий все эти вещи и позволяющий вертеть формулу Блэка-Шоулса во все стороны:

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function NORM(x As Single) As Single
NORM = Exp(-x ^ 2 / 2) / (2 * 3.1415926) ^ (0.5)
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FERT(x As Single) As Single
Dim i%, n%
Dim S!, T!, s1!, x2!, epsilon!
epsilon = 0.00001
s1 = 0
T = Abs(x)
s1 = T
x2 = x ^ 2
n = 3
For i = 0 To 100
   T = x ^ 2 * T / n
   S = s1
   s1 = S + T
   n = n + 2
   If Abs(S — s1) < epsilon Then GoTo 10
   Next i
10   If x >= 0 Then FERT = 0.5 + s1 * NORM(x)
If x < 0 Then FERT = 0.5 — s1 * NORM(x)
'FERT = FERT — 0.5
If x < -10 Then FERT = 0
If x > 10 Then FERT = 1
End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function BS_C(K As Single, S As Single, T As Single, V As Single) As Single
Dim x!
x = V * (T / 365) ^ (0.5)
BS_C = S * FERT((Log(S / K) + (x ^ 2) / 2) / x) — K * FERT((Log(S / K) — (x ^ 2) / 2) / x)
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function IV_C(S As Single, K As Single, C As Single) As Single
Dim x!, x_next!, f!, df!, epsilon!
Dim i%, i_max%
epsilon = 0.00001
x = 0.5
i_max = 10
For i = 1 To i_max
   f = C — S * FERT((Log(S / K) + x ^ 2 / 2) / x) + K * FERT((Log(S / K) — x ^ 2 / 2) / x)
   df = -S * NORM((Log(S / K) + x ^ 2 / 2) / x)
   x_next = x — f / df
   If (Abs(x — x_next)) < epsilon Then GoTo 20
   x = x_next
   Next i
20 IV_C = x
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub ggg()
MsgBox (BS_C(120000, 110000, 10, 0.76))
MsgBox (IV_C(110000, 120000, 2091.91) / (10 / 365) ^ (0.5))
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Функция BS_C  рассчитывает цену опциона по известным страйку K, ЦБА S, волатильности V и времени до экспирации T, волатильность измерена в 1/корень из года, время до экспирации в днях.

Функция IV_C  рассчитывает величину «волатильность*корень из времени до экспирации» по известным страйку K, ЦБА S и цене опциона C.

Все это написано для коллов, для путов обобщение тривиально.



37 Комментариев
  • jk555
    25 апреля 2014, 12:19
    отлично! только лучше файл с примером приложить, а все эти строки кода VBA убрать, т.к. они много места на экране занимают.
      • jk555
        25 апреля 2014, 13:17
        anatolyutkin, понятно ))
  • К.О'Тяра
    25 апреля 2014, 12:19
    пасиб за статью,
    давно хотел запрограммить свой опц.калькулятор в Экселе, но руки не доходили… может с твоей помощью и осилю…

    кстати, где-то читал, что более близкие результаты к реальности дает не нормальное а лог-нормальное распределение.
  • AlexeyTikhonov
    25 апреля 2014, 12:37
    Вызвать встроенную функцию Excel не судьба?
      • AlexeyTikhonov
        25 апреля 2014, 13:02
        anatolyutkin, я про нормальное распределение — normsdist
        понимание то может и появляется — только
        1. вместо 1 строки у Вас десятки
        2. у вас приближенные вычисления
        3. да и производительность у вас будет ниже
        -и что касается обращения, вместо быстрого точного! определения волатильности подбором, вы пользуетесь весьма приближенным методом Ньютона, который оказался лучше (исправлен комментарий после тестирования)
  • SAVas2005
    25 апреля 2014, 12:39
    Как человеку, начинающему изучение опционов, найти практическое применение Вашим выкладкам.Этот код нужно запрограммировать, связать с квиком ??? Хотелось бы подробного объяснения для чайников.Спасибо.
    • К.О'Тяра
      25 апреля 2014, 13:33
      SAVas2005, Квик все тупо экспортирует в Эксель по DDE, целиком — доску опционов…

      Собссна этим и привлекателен Эксель — там потом все допиливается с помощью VBA
  • Growex
    25 апреля 2014, 12:57
    Блек-шоулз не работает. К нему разве что приделать ручку покрасивше и на помойку отнести как старую ненужную рухлядь.

    www.ivolatility.com/calc/

    и нефиг силу проверять
      • Growex
        25 апреля 2014, 13:50
        anatolyutkin,
        1. Под этим я понимаю что в рамках этой модели нельзя получить представительные данные о риске

        2. Работает объективная оценка.
    • К.О'Тяра
      25 апреля 2014, 13:35
      growex, а мужики-то не знают… ;-)
  • Nikita Masyukov
    25 апреля 2014, 13:14
    А сравнивали производительность со стандартной функцией erf(double x) в c++ или Java?
      • Nikita Masyukov
        25 апреля 2014, 13:30
        anatolyutkin, вот и мне кажется, что erf должен работать по тем же принципам. А может где-то даже затабулирован.
      • AlexeyTikhonov
        25 апреля 2014, 14:06
        anatolyutkin, Проверил на VBA одной функции.
        Резюме:
        1. У вас некорректно выполняется если X>10 или -10, переполнение вызывается раньше, чем условие выполнится. Но это не важно.
        2. По точности, хорошо, разница лишь в 7 знаке.
        3. По скорости так себе, в абсолютных величинах конечно мелочь: 0.03 секунды на 10 000 итераций, но в процентном на 30-35% хуже.

        Итого, как я и декларировал имеем: худшую производительность, некорректную обработку некоторых значения и нерациональный рост кода в ущерб пониманию.

        По методу Ньютона (попозже проверю) отпишусь.
          • AlexeyTikhonov
            25 апреля 2014, 14:22
            anatolyutkin, уменьшал epsilon
            влияет только на точность, скорость не увеличивается, те же 0.03 секунды в среднем
              • AlexeyTikhonov
                25 апреля 2014, 14:50
                anatolyutkin, я уже изменил комментарий, на время не влияет, те же самые 0.03-0.04 секунды дельта
                  • AlexeyTikhonov
                    25 апреля 2014, 15:53
                    anatolyutkin, а вот с методом Ньютона я ошибся.
                    Во-первых точность у Вас сопоставимая, максимальное отклонение 0.1% в волатильностях, что вполне приемлимо. Я думал все будет гораздо хуже.
                    А вот со скоростью, вроде у Вас даже побыстрее, на некоторых 18 комбинаций скорость одинаковая — 0.003906 но это видимо мин. измеряемый квант времени, а если зациклить на 1000 и добавить случайное отклонение по фьючерсу, то у Вас даже побыстрее вроде, но у меня несопоставимые листы и может где-то я ошибаюсь, но перепроверять уже не буду.
                    Вердикт: метод Ньютона видимо быстрее подбора при сопоставимой точности, так что забираю свои слова назад про этот метод.
                      • AlexeyTikhonov
                        25 апреля 2014, 16:11
                        anatolyutkin, что метод Ньютона быстрее подбора согласен, а вот писать свою реализацию плотности распределения нет, разработчики Microsoft все лучше ее реализовали и быстрее. Ладно бы свое быстрее было, тогда еще может быть да (если это критично), имеет смысл, но если явных выгод нет, то резона нет. У меня и так хватает расчетов которые необходимо делать самому, еще и изобретать велосипед не рационально. Одно дело какие нибудь доп. пакеты, где действительно непонятно что и как считается, другое дело встроенной простой функцией, которой сто лет в обед, и все огрехи там точно убраны. Вы же извлечение корня, например, сами не раскладываете в ряд, так зачем и здесь усложнять.
                          • AlexeyTikhonov
                            25 апреля 2014, 16:38
                            anatolyutkin, про iv согласен, в Excel нет, но есть всякие пакеты, вот им то и я не доверяю, просто мне казалось что подбор iv будет более точен, а может и быстрее, чем считать через производные (ведь кривизна может сильно повлиять) метода Ньютона, оказалось что не так. Буду знать, только переделывать свое приложение не буду, разница в сотых-тысячных долях секунд, а риски что не так сделаю велики;), уж лучше оставлю как есть;)
                          • imitator
                            25 апреля 2014, 18:27
                            anatolyutkin, спасибо!
  • НеГрустин
    25 апреля 2014, 17:30
    «Длинно о Непонятном.»

    >>опционы надо чувствовать.

    Для меня весь смысл уместился в этой фразе))))
  • speculair
    03 ноября 2014, 10:26
    все равно не понимаю стремления велосипеды изобретать
    quantlib.org/index.shtml

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн