NameError: name 'S' is not defined

Question:

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:DocumentscodePythonHelloWorldgreeks.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!

Asked By: Jack

||

Answers:

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.

Answered By: DialFrost

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.

Answered By: Brandon Burkett

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
Answered By: Sabil
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.