可以第三方免费python库(QuantLib/Mibian)计算实时计算期权的隐含波动率(implied volatility)及其希腊值,包括:
- iv
- delta
- gamma
- theta
- vega
- rpho
源代码见本文最后。
实时绘制损益曲线及希腊值曲线。
![]()
例如,再用plotly 可视化引擎,可以实时做出漂亮的波动率曲面。
![]()
参见:阿岛格:基于人工智能的量化投资系统(9)数据指标及可视化 的第3, 以及本文最后的视频。
演示视频
- (视频) 阿岛格:低门槛搭建你的个人量化平台-演示
- (视频) 阿岛格:打造个人的量化平台(期权)
专栏
- 阿岛格专栏:低门槛搭建个人量化平台
- 阿岛格专栏: 基于人工智能的量化投资
如有问题,请看个人主页扫码“ 知shi星球(阿岛格)”加入讨论。
源代码如下:
#coding=utf-8
'''
MibianLib - Options Pricing Open Source Library - http://code.mibian.net/
Copyright (C) 2011 Yassine Maaroufi - <yassinemaaroufi@mibian.net>
Distributed under GPLv3 - http://www.gnu.org/copyleft/gpl.html
&#39;&#39;&#39;
#from numba import jit,autojit
#from scipy.optimize import minimize.basinhopping,root,fsolve,rosen,
from scipy import optimize
#from scipy.optimize import fsolve
import numpy as np
from math import log, e
try:
from scipy.stats import norm
except ImportError:
print(&#39;Mibian requires scipy to work properly&#39;)
# WARNING: All numbers should be floats -> x = 1.0
#@autojit
#defined and improved by adog 20190613
def impliedVolatility(className, args, callPrice=None, putPrice=None, high=500.0, low=0.0):
def fun(x):
bs=BS(args, volatility=x, performance=True)
if callPrice:
if bs.callPrice:
return bs.callPrice-callPrice
else:
return 0.-callPrice
elif putPrice:
if bs.putPrice:
return bs.putPrice-putPrice
else:
return 0.-putPrice
iv=0.
try:
res = optimize.root(fun,[0.],method=&#39;df-sane&#39;)
if res.x and len(res.x)==1:
if res.x>0.:
iv=res.x[0]
except Exception,e:
print(e)
return iv
class GK:
&#39;&#39;&#39;Garman-Kohlhagen
Used for pricing European options on currencies
GK([underlyingPrice, strikePrice, domesticRate, foreignRate, \
daysToExpiration], volatility=x, callPrice=y, putPrice=z)
eg:
c = mibian.GK([1.4565, 1.45, 1, 2, 30], volatility=20)
c.callPrice # Returns the call price
c.putPrice # Returns the put price
c.callDelta # Returns the call delta
c.putDelta # Returns the put delta
c.callDelta2 # Returns the call dual delta
c.putDelta2 # Returns the put dual delta
c.callTheta # Returns the call theta
c.putTheta # Returns the put theta
c.callRhoD # Returns the call domestic rho
c.putRhoD # Returns the put domestic rho
c.callRhoF # Returns the call foreign rho
c.putRhoF # Returns the call foreign rho
c.vega # Returns the option vega
c.gamma # Returns the option gamma
c = mibian.GK([1.4565, 1.45, 1, 2, 30], callPrice=0.0359)
c.impliedVolatility # Returns the implied volatility from the call price
c = mibian.GK([1.4565, 1.45, 1, 2, 30], putPrice=0.03)
c.impliedVolatility # Returns the implied volatility from the put price
c = mibian.GK([1.4565, 1.45, 1, 2, 30], callPrice=0.0359, putPrice=0.03)
c.putCallParity # Returns the put-call parity
&#39;&#39;&#39;
def __init__(self, args, volatility=None, callPrice=None, putPrice=None, \
performance=None):
self.underlyingPrice = float(args[0])
self.strikePrice = float(args[1])
self.domesticRate = float(args[2]) / 100
self.foreignRate = float(args[3]) / 100
self.daysToExpiration = float(args[4]) / 365
for i in [&#39;callPrice&#39;, &#39;putPrice&#39;, &#39;callDelta&#39;, &#39;putDelta&#39;, \
&#39;callDelta2&#39;, &#39;putDelta2&#39;, &#39;callTheta&#39;, &#39;putTheta&#39;, \
&#39;callRhoD&#39;, &#39;putRhoD&#39;, &#39;callRhoF&#39;, &#39;callRhoF&#39;, &#39;vega&#39;, \
&#39;gamma&#39;, &#39;impliedVolatility&#39;, &#39;putCallParity&#39;]:
self.__dict__ = None
if volatility:
self.volatility = float(volatility) / 100
self._a_ = self.volatility
* self.daysToExpiration**0.5
self._d1_ = (log(self.underlyingPrice / self.strikePrice) + \
(self.domesticRate - self.foreignRate + \
(self.volatility**2)/2) * self.daysToExpiration) / self._a_
self._d2_ = self._d1_ - self._a_
# Reduces performance overhead when computing implied volatility
if performance:
[self.callPrice, self.putPrice] = self._price()
else:
[self.callPrice, self.putPrice] = self._price()
[self.callDelta, self.putDelta] = self._delta()
[self.callDelta2, self.putDelta2] = self._delta2()
[self.callTheta, self.putTheta] = self._theta()
[self.callRhoD, self.putRhoD] = self._rhod()
[self.callRhoF, self.putRhoF] = self._rhof()
self.vega = self._vega()
self.gamma = self._gamma()
self.exerciceProbability = norm.cdf(self._d2_)
if callPrice:
self.callPrice = round(float(callPrice), 6)
self.impliedVolatility = impliedVolatility(\
self.__class__.__name__, args, callPrice=self.callPrice)
if putPrice and not callPrice:
self.putPrice = round(float(putPrice), 6)
self.impliedVolatility = impliedVolatility(\
self.__class__.__name__, args, putPrice=self.putPrice)
if callPrice and putPrice:
self.callPrice = float(callPrice)
self.putPrice = float(putPrice)
self.putCallParity = self._parity()
def _price(self):
&#39;&#39;&#39;Returns the option price: [Call price, Put price]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = max(0.0, self.underlyingPrice - self.strikePrice)
put = max(0.0, self.strikePrice - self.underlyingPrice)
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
call = e**(-self.foreignRate * self.daysToExpiration) * \
self.underlyingPrice * norm.cdf(self._d1_) - \
e**(-self.domesticRate * self.daysToExpiration) * \
self.strikePrice * norm.cdf
(self._d2_)
put = e**(-self.domesticRate * self.daysToExpiration) * \
self.strikePrice * norm.cdf(-self._d2_) - \
e**(-self.foreignRate * self.daysToExpiration) * \
self.underlyingPrice * norm.cdf(-self._d1_)
return [call, put]
def _delta(self):
&#39;&#39;&#39;Returns the option delta: [Call delta, Put delta]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = 1.0 if self.underlyingPrice > self.strikePrice else 0.0
put = -1.0 if self.underlyingPrice < self.strikePrice else 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
_b_ = e**-(self.foreignRate * self.daysToExpiration)
call = norm.cdf(self._d1_) * _b_
put = -norm.cdf(-self._d1_) * _b_
return [call, put]
def _delta2(self):
&#39;&#39;&#39;Returns the dual delta: [Call dual delta, Put dual delta]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = -1.0 if self.underlyingPrice > self.strikePrice else 0.0
put = 1.0 if self.underlyingPrice < self.strikePrice else 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
_b_ = e**-(self.domesticRate * self.daysToExpiration)
call = -norm.cdf(self._d2_) * _b_
put = norm.cdf(-self._d2_) * _b_
return [call, put]
def _vega(self):
&#39;&#39;&#39;Returns the option vega&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
return 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
return self.underlyingPrice * e**-(self.foreignRate * \
self.daysToExpiration) * norm.pdf(self._d1_) * \
self.daysToExpiration**0.5
def _theta(self):
&#39;&#39;&#39;Returns the option theta: [Call theta, Put theta]&#39;&#39;&#39;
_b_ = e**-(self.foreignRate * self.daysToExpiration)
call = -self.underlyingPrice * _b_ * norm.pdf(self._d1_) * \
self.volatility / (2 * self.daysToExpiration**0.5) + \
self.foreignRate * self.underlyingPrice * _b_ * \
norm.cdf(self._d1_) - self.domesticRate * self.strikePrice * \
_b_ * norm.cdf(self._d2_)
put = -self.underlyingPrice * _b_ * norm.pdf(self._d1_) * \
self.volatility / (2 * self.daysToExpiration**0.5) - \
self.foreignRate * self.underlyingPrice * _b_ * \
norm.cdf(-self._d1_) + self.domesticRate * self.strikePrice * \
_b_ * norm.cdf(-self._d2_)
return [call / 365, put / 365]
def _rhod(self):
&#39;&#39;&#39;Returns the option domestic rho: [Call rho, Put rho]&#39;&#39;&#39;
call = self.strikePrice * self.daysToExpiration * \
e**(-self.domesticRate * self.daysToExpiration) * \
norm.cdf(self._d2_) / 100
put = -self.strikePrice * self.daysToExpiration * \
e**(-self.domesticRate * self.daysToExpiration) * \
norm.cdf(-self._d2_) / 100
return [call, put]
def _rhof(self):
&#39;&#39;&#39;Returns the option foreign rho: [Call rho, Put rho]&#39;&#39;&#39;
call = -self.underlyingPrice * self.daysToExpiration * \
e**(-self.foreignRate * self.daysToExpiration) * \
norm.cdf(self._d1_) / 100
put = self.underlyingPrice * self.daysToExpiration * \
e**(-self.foreignRate * self.daysToExpiration) * \
norm.cdf(-self._d1_) / 100
return [call, put]
def _gamma(self):
&#39;&#39;&#39;Returns the option gamma&#39;&#39;&#39;
return (norm.pdf(self._d1_) * e**-(self.foreignRate * \
self.daysToExpiration)) / (self.underlyingPrice * self._a_)
def _parity(self):
&#39;&#39;&#39;Returns the put-call parity&#39;&#39;&#39;
return self.callPrice - self.putPrice - (self.underlyingPrice / \
((1 + self.foreignRate)**self.daysToExpiration)) + \
(self.strikePrice / \
((1 + self.domesticRate)**self.daysToExpiration))
class BS:
&#39;&#39;&#39;Black-Scholes
Used for pricing European options on stocks without dividends
BS([underlyingPrice, strikePrice, interestRate, daysToExpiration], \
volatility=x, callPrice=y, putPrice=z)
eg:
c = mibian.BS([1.4565, 1.45, 1, 30], volatility=20)
c.callPrice # Returns the call price
c.putPrice # Returns the put price
c.callDelta # Returns the call delta
c.putDelta # Returns the put delta
c.callDelta2 # Returns the call dual delta
c.putDelta2 # Returns the put dual delta
c.callTheta # Returns the call theta
c.putTheta # Returns the put theta
c.callRho # Returns the call rho
c.putRho # Returns the put rho
c.vega # Returns the option vega
c.gamma # Returns the option gamma
c = mibian.BS([1.4565, 1.45, 1, 30], callPrice=0.0359)
c.impliedVolatility # Returns the implied volatility from the call price
c = mibian.BS([1.4565, 1.45, 1, 30], putPrice=0.0306)
c.impliedVolatility # Returns the implied volatility from the put price
c = mibian.BS([1.4565, 1.45, 1, 30], callPrice=0.0359, putPrice=0.0306)
c.putCallParity # Returns the put-call parity
&#39;&#39;&#39;
def __init__(self, args, volatility=None, callPrice=None, putPrice=None, \
performance=None):
self.underlyingPrice = float(args[0])
self.strikePrice = float(args[1])
self.interestRate = float(args[2]) / 100
self.daysToExpiration = float(args[3]) / 365
for i in [&#39;callPrice&#39;, &#39;putPrice&#39;, &#39;callDelta&#39;, &#39;putDelta&#39;, \
&#39;callDelta2&#39;, &#39;putDelta2&#39;, &#39;callTheta&#39;, &#39;putTheta&#39;, \
&#39;callRho&#39;, &#39;putRho&#39;, &#39;vega&#39;, &#39;gamma&#39;, &#39;impliedVolatility&#39;, \
&#39;putCallParity&#39;]:
self.__dict__ = None
if volatility:
self.volatility = float(volatility) / 100
self._a_ = self.volatility * self.daysToExpiration**0.5
self._d1_ = (log(self.underlyingPrice / self.strikePrice) + \
(self.interestRate + (self.volatility**2) / 2) * \
self.daysToExpiration) / self._a_
self._d2_ = self._d1_ - self._a_
if performance:
[self.callPrice, self.putPrice] = self._price()
else:
[self.callPrice, self.putPrice] = self._price()
[self.callDelta, self.putDelta] = self._delta()
[self.callDelta2, self.putDelta2] = self._delta2()
[self.callTheta, self.putTheta] = self._theta()
[self.callRho, self.putRho] = self._rho()
self.vega = self._vega()
self.gamma = self._gamma()
self.exerciceProbability = norm.cdf(self._d2_)
if callPrice:
self.callPrice = round(float(callPrice), 6)
self.impliedVolatility = impliedVolatility(\
self.__class__.__name__, args, callPrice=self.callPrice)
if putPrice and not callPrice:
self.putPrice = round(float(putPrice), 6)
self.impliedVolatility = impliedVolatility(\
self.__class__.__name__, args, putPrice=self.putPrice)
if callPrice and putPrice:
self.callPrice = float(callPrice)
self.putPrice = float(putPrice)
self.putCallParity = self._parity()
def _price(self):
&#39;&#39;&#39;Returns the option price: [Call price, Put price]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = max(0.0, self.underlyingPrice - self.strikePrice)
put = max(0.0, self.strikePrice - self.underlyingPrice)
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
call = self.underlyingPrice * norm.cdf(self._d1_) - \
self.strikePrice * e**(-self.interestRate * \
self.daysToExpiration) * norm.cdf(self._d2_)
put = self.strikePrice * e**(-self.interestRate * \
self.daysToExpiration) * norm.cdf(-self._d2_) - \
self.underlyingPrice * norm.cdf(-self._d1_)
return [call, put]
def _delta(self):
&#39;&#39;&#39;Returns the option delta: [Call delta, Put delta]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = 1.0 if self.underlyingPrice > self.strikePrice else 0.0
put = -1.0 if self.underlyingPrice < self.strikePrice else 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
call = norm.cdf(self._d1_)
put = -norm.cdf(-self._d1_)
return [call, put]
def _delta2(self):
&#39;&#39;&#39;Returns the dual delta: [Call dual delta, Put dual delta]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = -1.0 if self.underlyingPrice > self.strikePrice else 0.0
put = 1.0 if self.underlyingPrice < self.strikePrice else 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
_b_ = e**-(self.interestRate * self.daysToExpiration)
call = -norm.cdf(self._d2_) * _b_
put = norm.cdf(-self._d2_) * _b_
return [call, put]
def _vega(self):
&#39;&#39;&#39;Returns the option vega&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
return 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
return self.underlyingPrice * norm.pdf(self._d1_) * \
self.daysToExpiration**0.5 / 100
def _theta(self):
&#39;&#39;&#39;Returns the option theta: [Call theta, Put theta]&#39;&#39;&#39;
_b_ = e**-(self.interestRate * self.daysToExpiration)
call = -self.underlyingPrice * norm.pdf(self._d1_) * self.volatility / \
(2 * self.daysToExpiration**0.5) - self.interestRate * \
self.strikePrice * _b_ * norm.cdf(self._d2_)
put = -self.underlyingPrice * norm.pdf(self._d1_) * self.volatility / \
(2 * self.daysToExpiration**0.5) + self.interestRate * \
self.strikePrice * _b_ * norm.cdf(-self._d2_)
return [call / 365, put / 365]
def _rho(self):
&#39;&#39;&#39;Returns the option rho: [Call rho, Put rho]&#39;&#39;&#39;
_b_ = e**-(self.interestRate * self.daysToExpiration)
call = self.strikePrice * self.daysToExpiration * _b_ * \
norm.cdf(self._d2_) / 100
put = -self.strikePrice * self.daysToExpiration * _b_ * \
norm.cdf(-self._d2_) / 100
return [call, put]
def _gamma(self):
&#39;&#39;&#39;Returns the option gamma&#39;&#39;&#39;
return norm.pdf(self._d1_) / (self.underlyingPrice * self._a_)
def _parity(self):
&#39;&#39;&#39;Put-Call Parity&#39;&#39;&#39;
return self.callPrice - self.putPrice - self.underlyingPrice + \
(self.strikePrice / \
((1 + self.interestRate)**self.daysToExpiration))
class Me:
&#39;&#39;&#39;Merton
Used for pricing European options on stocks with dividends
Me([underlyingPrice, strikePrice, interestRate, annualDividends, \
daysToExpiration], volatility=x, callPrice=y, putPrice=z)
eg:
c = mibian.Me([52, 50, 1, 1, 30], volatility=20)
c.callPrice # Returns the call price
c.putPrice # Returns the put price
c.callDelta # Returns the call delta
c.putDelta # Returns the put delta
c.callDelta2 # Returns the call dual delta
c.putDelta2 # Returns the put dual delta
c.callTheta # Returns the call theta
c.putTheta # Returns the put theta
c.callRho # Returns the call rho
c.putRho # Returns the put rho
c.vega # Returns the option vega
c.gamma # Returns the option gamma
c = mibian.Me([52, 50, 1, 1, 30], callPrice=0.0359)
c.impliedVolatility # Returns the implied volatility from the call price
c = mibian.Me([52, 50, 1, 1, 30], putPrice=0.0306)
c.impliedVolatility # Returns the implied volatility from the put price
c = mibian.Me([52, 50, 1, 1, 30], callPrice=0.0359, putPrice=0.0306)
c.putCallParity # Returns the put-call parity
&#39;&#39;&#39;
def __init__(self, args, volatility=None, callPrice=None, putPrice=None, \
performance=None):
self.underlyingPrice = float(args[0])
self.strikePrice = float(args[1])
self.interestRate = float(args[2]) / 100
self.dividend = float(args[3])
self.dividendYield = self.dividend / self.underlyingPrice
self.daysToExpiration = float(args[4]) / 365
for i in [&#39;callPrice&#39;, &#39;putPrice&#39;, &#39;callDelta&#39;, &#39;putDelta&#39;, \
&#39;callDelta2&#39;, &#39;putDelta2&#39;, &#39;callTheta&#39;, &#39;putTheta&#39;, \
&#39;callRho&#39;, &#39;putRho&#39;, &#39;vega&#39;, &#39;gamma&#39;, &#39;impliedVolatility&#39;, \
&#39;putCallParity&#39;]:
self.__dict__ = None
if volatility:
self.volatility = float(volatility) / 100
self._a_ = self.volatility * self.daysToExpiration**0.5
self._d1_ = (log(self.underlyingPrice / self.strikePrice) + \
(self.interestRate - self.dividendYield + \
(self.volatility**2) / 2) * self.daysToExpiration) / \
self._a_
self._d2_ = self._d1_ - self._a_
if performance:
[self.callPrice, self.putPrice] = self._price()
else:
[self.callPrice, self.putPrice] = self._price()
[self.callDelta, self.putDelta] = self._delta()
[self.callDelta2, self.putDelta2] = self._delta2()
[self.callTheta, self.putTheta] = self._theta()
[self.callRho, self.putRho] = self._rho()
self.vega = self._vega()
self.gamma = self._gamma()
self.exerciceProbability = norm.cdf(self._d2_)
if callPrice:
self.callPrice = round(float(callPrice), 6)
self.impliedVolatility = impliedVolatility(\
self.__class__.__name__, args, self.callPrice)
if putPrice and not callPrice:
self.putPrice = round(float(putPrice), 6)
self.impliedVolatility = impliedVolatility(\
self.__class__.__name__, args, putPrice=self.putPrice)
if callPrice and putPrice:
self.callPrice = float(callPrice)
self.putPrice = float(putPrice)
self.putCallParity = self._parity()
def _price(self):
&#39;&#39;&#39;Returns the option price: [Call price, Put price]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = max(0.0, self.underlyingPrice - self.strikePrice)
put = max(0.0, self.strikePrice - self.underlyingPrice)
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
call = self.underlyingPrice * e**(-self.dividendYield * \
self.daysToExpiration) * norm.cdf(self._d1_) - \
self.strikePrice * e**(-self.interestRate * \
self.daysToExpiration) * norm.cdf(self._d2_)
put = self.strikePrice * e**(-self.interestRate * \
self.daysToExpiration) * norm.cdf(-self._d2_) - \
self.underlyingPrice * e**(-self.dividendYield * \
self.daysToExpiration) * norm.cdf(-self._d1_)
return [call, put]
def _delta(self):
&#39;&#39;&#39;Returns the option delta: [Call delta, Put delta]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = 1.0 if self.underlyingPrice > self.strikePrice else 0.0
put = -1.0 if self.underlyingPrice < self.strikePrice else 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
_b_ = e**(-self.dividendYield * self.daysToExpiration)
call = _b_ * norm.cdf(self._d1_)
put = _b_ * (norm.cdf(self._d1_) - 1)
return [call, put]
# Verify
def _delta2(self):
&#39;&#39;&#39;Returns the dual delta: [Call dual delta, Put dual delta]&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
call = -1.0 if self.underlyingPrice > self.strikePrice else 0.0
put = 1.0 if self.underlyingPrice < self.strikePrice else 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
_b_ = e**-(self.interestRate * self.daysToExpiration)
call = -norm.cdf(self._d2_) * _b_
put = norm.cdf(-self._d2_) * _b_
return [call, put]
def _vega(self):
&#39;&#39;&#39;Returns the option vega&#39;&#39;&#39;
if self.volatility == 0 or self.daysToExpiration == 0:
return 0.0
if self.strikePrice == 0:
raise ZeroDivisionError(&#39;The strike price cannot be zero&#39;)
else:
return self.underlyingPrice * e**(-self.dividendYield * \
self.daysToExpiration) * norm.pdf(self._d1_) * \
self.daysToExpiration**0.5 / 100
def _theta(self):
&#39;&#39;&#39;Returns the option theta: [Call theta, Put theta]&#39;&#39;&#39;
_b_ = e**-(self.interestRate * self.daysToExpiration)
_d_ = e**(-self.dividendYield * self.daysToExpiration)
call = -self.underlyingPrice * _d_ * norm.pdf(self._d1_) * \
self.volatility / (2 * self.daysToExpiration**0.5) + \
self.dividendYield * self.underlyingPrice * _d_ * \
norm.cdf(self._d1_) - self.interestRate * \
self.strikePrice * _b_ * norm.cdf(self._d2_)
put = -self.underlyingPrice * _d_ * norm.pdf(self._d1_) * \
self.volatility / (2 * self.daysToExpiration**0.5) - \
self.dividendYield * self.underlyingPrice * _d_ * \
norm.cdf(-self._d1_) + self.interestRate * \
self.strikePrice * _b_ * norm.cdf(-self._d2_)
return [call / 365, put / 365]
def _rho(self):
&#39;&#39;&#39;Returns the option rho: [Call rho, Put rho]&#39;&#39;&#39;
_b_ = e**-(self.interestRate * self.daysToExpiration)
call = self.strikePrice * self.daysToExpiration * _b_ * \
norm.cdf(self._d2_) / 100
put = -self.strikePrice * self.daysToExpiration * _b_ * \
norm.cdf(-self._d2_) / 100
return [call, put]
def _gamma(self):
&#39;&#39;&#39;Returns the option gamma&#39;&#39;&#39;
return e**(-self.dividendYield * self.daysToExpiration) * \
norm.pdf(self._d1_) / (self.underlyingPrice * self._a_)
# Verify
def _parity(self):
&#39;&#39;&#39;Put-Call Parity&#39;&#39;&#39;
return self.callPrice - self.putPrice - self.underlyingPrice + \
(self.strikePrice / \
((1 + self.interestRate)**self.daysToExpiration)) |