Блог им. anatolyutkin

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

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

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



★67
37 комментариев
отлично! только лучше файл с примером приложить, а все эти строки кода VBA убрать, т.к. они много места на экране занимают.
avatar
jk555, Спасибо!

Код на экране усиливает ощущение заумности и значимости написанного :)
avatar
anatolyutkin, понятно ))
avatar
пасиб за статью,
давно хотел запрограммить свой опц.калькулятор в Экселе, но руки не доходили… может с твоей помощью и осилю…

кстати, где-то читал, что более близкие результаты к реальности дает не нормальное а лог-нормальное распределение.
avatar
cosmichorror, Так там логнормальное и есть. Теория БШ--это теория, в которой цена базового актива распределена логнормально anatoly-utkin.livejournal.com/2835.html. Логарифм в d1=(ln(S/K)+z^2/2)/z--это след именно логнормальности.
avatar
Вызвать встроенную функцию Excel не судьба?
avatar
AlexeyT,
а) Предпочитаю сам все сделать--оно как-то душевней. Понимание появляется.
б) Какая встроенная в эксель функция обращает формулу Блэка-Шоулса?
avatar
anatolyutkin, я про нормальное распределение — normsdist
понимание то может и появляется — только
1. вместо 1 строки у Вас десятки
2. у вас приближенные вычисления
3. да и производительность у вас будет ниже
-и что касается обращения, вместо быстрого точного! определения волатильности подбором, вы пользуетесь весьма приближенным методом Ньютона, который оказался лучше (исправлен комментарий после тестирования)
avatar
AlexeyT,
1. Десятки строк кода--это само по себе не является проблемой. Тем более, что коды и алгоритмы простые.
2. Численные расчеты всегда приближенные, не только у меня.
3. «быстрого точного! определения волатильности подбором». Метод Ньютона, как и любой численный метод решения уравнений, основан на подборе. Все дело в том, как перебирать значения. Метод Ньютона автоматизировано находит решение подобных задач за три-пять итераций с точностью знака 4.

Скопируйте общий финальный код в VBA редактор и запускайте макрос ggg. Возможно, при копировании минусы в формулах заменятся на тире--это надо подправить.
avatar
Как человеку, начинающему изучение опционов, найти практическое применение Вашим выкладкам.Этот код нужно запрограммировать, связать с квиком ??? Хотелось бы подробного объяснения для чайников.Спасибо.
avatar
SAVas2005, Не знаю. Эта статья--бесплатный опцион. Хотите--применяйте, не хотите--не применяйте. Думаю, на определенном уровне сами увидите, где и как можно что-то отсюда применить.
avatar
SAVas2005, Квик все тупо экспортирует в Эксель по DDE, целиком — доску опционов…

Собссна этим и привлекателен Эксель — там потом все допиливается с помощью VBA
avatar
Блек-шоулз не работает. К нему разве что приделать ручку покрасивше и на помойку отнести как старую ненужную рухлядь.

www.ivolatility.com/calc/

и нефиг силу проверять
avatar
growex,
1) Что вы понимаете под фразой «Блек-шоулз не работает»? В рамках этой модели нельзя заработать денег, или что?
2) Что же тогда работает?
avatar
anatolyutkin,
1. Под этим я понимаю что в рамках этой модели нельзя получить представительные данные о риске

2. Работает объективная оценка.
avatar
growex,
1) Если речь про тяжелые хвосты, то согласен.
2) Какая оценка является объективной?
avatar
growex, а мужики-то не знают… ;-)
avatar
Вова Буравлёв, Пятница--это мило :)
avatar
А сравнивали производительность со стандартной функцией erf(double x) в c++ или Java?
avatar
Nikita Masyukov, Нет. Если честно, то я действовал тупым методом последовательного приближения к тому, что хочется. На заре всего этого вообще считал N(x) (страшно сказать) методом прямоугольников. Быстро выяснилось, что это как топором бриться. Стал изучать матчасть, нашел эти асимптотические вещи. Поскольку они считают ответ за три итерации не используя ничего кроме экспоненты, то я решил, что это мило. И мне для использования на нашем полуликвидном опционном рынке, в общем, хватает. Хотя я не hft ни разу.

Думаю, erf использует похожие вещи--ибо ничего принципиально более быстрого просто нет. Поэтому наиболее вероятный ответ на ваш вопрос таков: стандартный erf наверняка чуть-чуть быстрее, может, в разы--ибо создатели наверняка там использовали похожие асимптотические разложения, но наверняка все вылизали, в отличие от меня :)
avatar
anatolyutkin, вот и мне кажется, что erf должен работать по тем же принципам. А может где-то даже затабулирован.
avatar
Nikita Masyukov, Ну конечно, а как еще?

Про затабулированность не могу знать. Не имею нужного уровня владения материалом :) Мне кажется, особого смысла в этом нет--ибо неизвестно еще, что быстрее--три итерации провернуть или по таблице искать. А спросить про это у кого-нибудь из создателей этих функций нельзя?
avatar
anatolyutkin, Проверил на VBA одной функции.
Резюме:
1. У вас некорректно выполняется если X>10 или -10, переполнение вызывается раньше, чем условие выполнится. Но это не важно.
2. По точности, хорошо, разница лишь в 7 знаке.
3. По скорости так себе, в абсолютных величинах конечно мелочь: 0.03 секунды на 10 000 итераций, но в процентном на 30-35% хуже.

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

По методу Ньютона (попозже проверю) отпишусь.
avatar
AlexeyT,
1. Согласен, может, так и есть. Кому надо--вылижут этот момент, я и так много сказал и показал.
2. Гут
3. Этот код еще есть куда вылизать. Там немало написано неоптимально. Я подробно описал, как я делал этот код, в комментарии к вопросу Никиты Масюкова.

Еще одно. Поиграйтесь с epsilon. Она регулирует точность расчета и влияет на скорость. Думаю, точность в 0.00001 не нужна.

По поводу общей философии. Нравится вам erf или normdist--да ради бога. Мне не нравится и я привел алтернативный, более гибкий и гораздо менее «черноящечный» метод.
avatar
anatolyutkin, уменьшал epsilon
влияет только на точность, скорость не увеличивается, те же 0.03 секунды в среднем
avatar
AlexeyT, В 10 раз--это слабо для этого алгоритма, он очень быстро сходится.

Подставьте epsilon=0.01. В этом случае точность будет до 3го знака. Интересно, что будет со временем расчета.
avatar
anatolyutkin, я уже изменил комментарий, на время не влияет, те же самые 0.03-0.04 секунды дельта
avatar
AlexeyT, Ну мне тут сказать нечего. Я так понимаю, вы программист, если интересно, почитайте про этот T алгоритм. Думаю, сами увидите, что там и как. А после этого свой normdist напишете, да еще и получше экселевского :)
avatar
anatolyutkin, а вот с методом Ньютона я ошибся.
Во-первых точность у Вас сопоставимая, максимальное отклонение 0.1% в волатильностях, что вполне приемлимо. Я думал все будет гораздо хуже.
А вот со скоростью, вроде у Вас даже побыстрее, на некоторых 18 комбинаций скорость одинаковая — 0.003906 но это видимо мин. измеряемый квант времени, а если зациклить на 1000 и добавить случайное отклонение по фьючерсу, то у Вас даже побыстрее вроде, но у меня несопоставимые листы и может где-то я ошибаюсь, но перепроверять уже не буду.
Вердикт: метод Ньютона видимо быстрее подбора при сопоставимой точности, так что забираю свои слова назад про этот метод.
avatar
AlexeyT, Ну вот видите. Мы ведь в Академии Наук не зря хлеб едим, разбираемся кое в чем :)

А вообще, общефилософски, я советую поменьше использовать встроенные функции, особенно в эксель, а побольше писать все самому. Вначале это долго, но зато потом будете писать любые вещи быстро и правильно, не тратя время на разборки в хитросплетениях мозга разработчиков.
avatar
anatolyutkin, что метод Ньютона быстрее подбора согласен, а вот писать свою реализацию плотности распределения нет, разработчики Microsoft все лучше ее реализовали и быстрее. Ладно бы свое быстрее было, тогда еще может быть да (если это критично), имеет смысл, но если явных выгод нет, то резона нет. У меня и так хватает расчетов которые необходимо делать самому, еще и изобретать велосипед не рационально. Одно дело какие нибудь доп. пакеты, где действительно непонятно что и как считается, другое дело встроенной простой функцией, которой сто лет в обед, и все огрехи там точно убраны. Вы же извлечение корня, например, сами не раскладываете в ряд, так зачем и здесь усложнять.
avatar
AlexeyT, Ну тут спорить не о чем--это ж философия :) У меня есть причины считать некоторые встроенные вещи проблемными. Например, генератор случайных чисел в эксель--убогий. Подробнее здесь: www.2stocks.ru/utkin/?p=113, обратите внимание на комменты (до седьмого, дальше спам). Из-за подобных примеров я уже давно для себя решил, что если функция сложна (что такое сложна--это отдельный вопрос), то мне удобней написать все самому.

В любом случае, ваша критика качается лишь normdist. А для поиска, например, IV никаких встроенных в эксель функций в природе нет. Мне такую функцию написать пять минут, также, как и многие другие--normdist, Блэк-Шоулс, греки всякие, да вообще что угодно. При этом я буду понимать и смогу менять их точность, их границы применения, итд. Но, повторюсь, это мой выбор, я его не навязываю, эта статья--это бесплатный опцион. Можно использовать, можно не использовать.
avatar
anatolyutkin, про iv согласен, в Excel нет, но есть всякие пакеты, вот им то и я не доверяю, просто мне казалось что подбор iv будет более точен, а может и быстрее, чем считать через производные (ведь кривизна может сильно повлиять) метода Ньютона, оказалось что не так. Буду знать, только переделывать свое приложение не буду, разница в сотых-тысячных долях секунд, а риски что не так сделаю велики;), уж лучше оставлю как есть;)
avatar
anatolyutkin, спасибо!
avatar
«Длинно о Непонятном.»

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

Для меня весь смысл уместился в этой фразе))))
avatar
все равно не понимаю стремления велосипеды изобретать
quantlib.org/index.shtml
avatar

теги блога anatolyutkin

....все тэги



UPDONW
Новый дизайн