Быстрый расчет подразумеваемой волатильности в Python - PullRequest
0 голосов
/ 18 апреля 2020

Я ищу библиотеку, которую можно использовать для более быстрого способа расчета подразумеваемой волатильности в python. У меня есть данные опций около 1+ миллионов строк, для которых я хочу рассчитать подразумеваемую волатильность. что было бы самым быстрым способом я могу рассчитать IV. Я пытался использовать py_vollib, но он не поддерживает векторизацию. Это займет около 5 минут. вычислять. Существуют ли другие библиотеки, которые могут помочь в более быстром вычислении. Что люди используют в расчетах волатильности в реальном времени, когда каждую секунду появляются миллионы строк?

1 Ответ

0 голосов
/ 22 апреля 2020

Вы должны понимать, что расчет подразумеваемой волатильности вычислительно дорог, если вам нужны числа в реальном времени, чем, возможно, python не лучшее решение.

Вот пример функций, которые вам могут понадобиться:

import numpy as np
from scipy.stats import norm
N = norm.cdf

def bs_call(S, K, T, r, vol):
    d1 = (np.log(S/K) + (r + 0.5*vol**2)*T) / (vol*np.sqrt(T))
    d2 = d1 - vol * np.sqrt(T)
    return S * norm.cdf(d1) - np.exp(-r * T) * K * norm.cdf(d2)

def bs_vega(S, K, T, r, sigma):
    d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
    return S * norm.pdf(d1) * np.sqrt(T)

def find_vol(target_value, S, K, T, r, *args):
    MAX_ITERATIONS = 200
    PRECISION = 1.0e-5
    sigma = 0.5
    for i in range(0, MAX_ITERATIONS):
        price = bs_call(S, K, T, r, sigma)
        vega = bs_vega(S, K, T, r, sigma)
        diff = target_value - price  # our root
        if (abs(diff) < PRECISION):
            return sigma
        sigma = sigma + diff/vega # f(x) / f'(x)
    return sigma # value wasn't found, return best guess so far

Достаточно быстро вычислить одно значение 1013 *

Но если вы попытаетесь вычислить много, вы поймете, что это займет некоторое время ...

%%time
size = 10000
S = np.random.randint(100, 200, size)
K = S * 1.25
T = np.ones(size)
R = np.random.randint(0, 3, size) / 100
vols = np.random.randint(15, 50, size) / 100
prices = bs_call(S, K, T, R, vols)

params = np.vstack((prices, S, K, T, R, vols))
vols = list(map(find_vol, *params))

Время стены: 10,5 с

...