简体   繁体   English

Python 中的快速隐含波动率计算

[英]Fast Implied Volatility Calculation in Python

I am looking for a library which i can use for faster way to calculate implied volatility in python.我正在寻找一个库,我可以用它来更快地计算 python 中的隐含波动率。 I have options data about 1+ million rows for which i want to calculate implied volatility.我有大约 1+ 百万行的期权数据,我想为其计算隐含波动率。 what would be the fastest way i can calculate IV's.我可以计算IV的最快方法是什么。 I have tried using py_vollib but it doesnt support vectorization.我尝试过使用 py_vollib,但它不支持矢量化。 It takes about 5 mins approx.大约需要5分钟。 to calculate.计算。 Are there any other libraries which can help in faster calculation.是否有任何其他库可以帮助加快计算速度。 What do people use in real time volatility calculations where there are millions of rows coming in every second?人们在每秒有数百万行进入的实时波动率计算中使用什么?

You have to realize that the implied volatility calculation is computationally expensive and if you want realtime numbers maybe python is not the best solution.您必须意识到隐含波动率计算的计算成本很高,如果您想要实时数字,python 可能不是最佳解决方案。

Here is an example of the functions you would need:以下是您需要的功能示例:

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

Computing a single value is quick enough计算单个值足够快

S = 100
K = 100
T = 11
r = 0.01
vol = 0.25

V_market = bs_call(S, K, T, r, vol)
implied_vol = find_vol(V_market, S, K, T, r)

print ('Implied vol: %.2f%%' % (implied_vol * 100))
print ('Market price = %.2f' % V_market)
print ('Model price = %.2f' % bs_call(S, K, T, r, implied_vol))

Implied vol: 25.00%隐含成交量:25.00%

Market price = 35.94市场价格 = 35.94

Model price = 35.94 Model 价格 = 35.94

But if you try to compute many, you will realize that it takes some time...但是如果你尝试计算很多,你会意识到这需要一些时间......

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

Wall time: 10.5 s挂壁时间:10.5 秒

If you change all calls to norm.cdf() -method into ndtr() , you will get a 2.4 time performance increase.如果将所有对norm.cdf() -方法的调用更改为ndtr() ,您将获得 2.4 倍的性能提升。

And if you change norm.pdf() -method into norm._pdf() , you will get another (huge) increase.如果您将norm.pdf() -方法更改为norm._pdf() ,您将获得另一个(巨大的)增长。

With both changes implemented, the example above dropped from 17.7 s down to 0.99 s on my machine.实施这两项更改后,上面的示例在我的机器上从 17.7 秒下降到 0.99 秒。

You will lose error checking etc. but in this case you probably don't need all that.您将丢失错误检查等,但在这种情况下,您可能不需要所有这些。

See: https://github.com/scipy/scipy/issues/1914见: https://github.com/scipy/scipy/issues/1914

ndtr() is in scipy.special ndtr()scipy.special

As of recent, there is a vectorized version of py_vollib available at py_vollib_vectorized , which is built on top of the py_vollib and makes pricing thousands of options contracts and calculating greeks much faster.最近, py_vollib提供了py_vollib的矢量化版本,它建立在py_vollib ,可以更快地为数千种期权合约定价和计算希腊字母。

!pip install py_vollib

This will return greeks along with black_scholes price and iv这将返回希腊人以及 black_scholes price 和 iv

import py_vollib 
from py_vollib.black_scholes  import black_scholes as bs
from py_vollib.black_scholes.implied_volatility import implied_volatility as iv
from py_vollib.black_scholes.greeks.analytical import delta 
from py_vollib.black_scholes.greeks.analytical import gamma
from py_vollib.black_scholes.greeks.analytical import rho
from py_vollib.black_scholes.greeks.analytical import theta
from py_vollib.black_scholes.greeks.analytical import vega
import numpy as np

#py_vollib.black_scholes.implied_volatility(price, S, K, t, r, flag)

"""
price (float) – the Black-Scholes option price
S (float) – underlying asset price
sigma (float) – annualized standard deviation, or volatility
K (float) – strike price
t (float) – time to expiration in years
r (float) – risk-free interest rate
flag (str) – ‘c’ or ‘p’ for call or put.
"""
def greek_val(flag, S, K, t, r, sigma):
    price = bs(flag, S, K, t, r, sigma)
    imp_v = iv(price, S, K, t, r, flag)
    delta_calc = delta(flag, S, K, t, r, sigma)
    gamma_calc = gamma(flag, S, K, t, r, sigma)
    rho_calc = rho(flag, S, K, t, r, sigma)
    theta_calc = theta(flag, S, K, t, r, sigma)
    vega_calc = vega(flag, S, K, t, r, sigma)
    return np.array([ price, imp_v ,theta_calc, delta_calc ,rho_calc ,vega_calc ,gamma_calc])

S = 8400
K = 8600
sigma = 16
r = 0.07
t = 1

call=greek_val('c', S, K, t, r, sigma)

put=greek_val('p', S, K, t, r, sigma)

You could use a binary search to find the implied vol quickly您可以使用二进制搜索快速找到隐含的 vol

def goalseek(spot_price: float,
             strike_price: float,
             time_to_maturity: float,
             option_type: str,
             option_price: float):
    volatility = 2.5
    upper_range = 5.0
    lower_range = 0
    MOE = 0.0001 # Minimum margin of error
    max_iters = 100
    iter = 0

    while iter < max_iters: # Don't iterate too much
        price = proposedPrice(spot_price=spot_price,
                               strike_price=strike_price,
                               time_to_maturity=time_to_maturity,
                               volatility=volatility,
                               option_type=option_type) # BS Model Pricing
        if abs((price - option_price)/option_price) < MOE:
            return volatility

        if price > option_price:
            tmp = volatility
            volatility = (volatility + lower_range)/2
            upper_range = tmp
        elif price < option_price:
            tmp = volatility
            volatility = (volatility + upper_range)/2
            lower_range = tmp
        iter += 1
    return volatility

please use py_vollib.black_scholes.greeks.numerical instead of analytical for back testing purpose.请使用 py_vollib.black_scholes.greeks.numerical 而不是分析用于回测目的。 Analytical throwing errors when option strike prices are deep out or in the money as well as illiquid contract, for this case use historical volatility instead of implied volatility to calculate option greeks.当期权执行价格在价内或价内以及非流动性合约时的分析抛出错误,在这种情况下,使用历史波动率而不是隐含波动率来计算期权希腊。 try: with iv and except: with hv尝试:使用 iv 和 except:使用 hv

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM