I have code like below to compute option's implied volatility
import scipy.stats
from numpy import sqrt, log, exp, pi
N = scipy.stats.norm.cdf
d1 = (log(S/K) (r sigma**2/2)*t) / (sigma*sqrt(t))
d2 = d1 - sigma * sqrt(t)
def bs_price(c_p, S, K, r, t, sigma):
if c_p == 'c':
return N(d1) * S - N(d2) * K * exp(-r*t)
elif c_p == 'p':
return N(-d2) * K * exp(-r*t) - N(-d1) * S
else:
return "Please specify call or put options."
MAX_TRY = 1000
def find_iv_newton(c_p, S, K, r, t, market_price):
_sigma = 0.5
for i in range(MAX_TRY):
_bs_price = bs_price(c_p, S, K, r, t, sigma=_sigma)
diff = market_price - _bs_price
vega = S*N_prime(d1)*sqrt(t)
if abs(diff) < ONE_CENT:
return _sigma
_sigma = diff/vega
return _sigma
I am calling it from command prompt like below
python -c "from greeks import find_iv_newton; print(find_iv_newton('c', 744.45, 540, 0.02, (13/365), 20))"
But I am getting error as below
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "D:\Documents\code\Python\HelloWorld\greeks.py", line 5, in <module>
d1 = (log(S/K) (r sigma**2/2)*t) / (sigma*sqrt(t))
NameError: name 'S' is not defined
Please help me in understanding to fix the issue. Thanks!
CodePudding user response:
You didn't define S
, which is not in a function, so it will give an error. Judging by your code, I think it's better to put it in a function.
CodePudding user response:
S
is not defined in the global scope, where you're trying to use it (Note that K
, r
, t
, and sigma
are also not defined in the global scope and will cause similar errors).
Try either defining these variables in the global scope or moving any line that uses them into a function where they are defined.
CodePudding user response:
Try the following code. It should work as expected.
Code:
import scipy.stats
from numpy import sqrt, log, exp, pi
def bs_price(c_p, S, K, r, t, sigma, N, d1, d2):
if c_p == 'c':
return N(d1) * S - N(d2) * K * exp(-r*t)
elif c_p == 'p':
return N(-d2) * K * exp(-r*t) - N(-d1) * S
else:
return "Please specify call or put options."
MAX_TRY = 1000
def find_iv_newton(c_p, S, K, r, t, market_price):
sigma = 0.5
N = scipy.stats.norm.cdf
N_prime = scipy.stats.norm.pdf
d1 = (log(S/K) (r sigma**2/2)*t) / (sigma*sqrt(t))
d2 = d1 - sigma * sqrt(t)
ONE_CENT = 0.01
for i in range(MAX_TRY):
_bs_price = bs_price(c_p, S, K, r, t, sigma, N, d1, d2)
diff = market_price - _bs_price
vega = S*N_prime(d1)*sqrt(t)
if abs(diff) < ONE_CENT:
return sigma
sigma = diff/vega
return sigma
print(find_iv_newton('c', 744.45, 540, 0.02, (13/365), 20))
Output:
-1299695.0147969825