# Why is my put intrinsic value greater than my actual put value in BSM? Python code

I have been creating a class for determining put/call values based on the Black Scholes Merton model and have run into a weird problem. For some reason my put values end up being less than the intrinsic value of the option which simply doesn't make sense to me. I've scoured my code, rewritten it, and tried using someone else's code for determining the value of a put using BSM. Is there and error in my code, or am I missing some logic in BSM?

I'm using the most up to date version of python, NumPy, and scipy for this.

from numpy import exp, log, sqrt
from scipy.stats import norm


### basic inputs

K = 40
T = 0.5 # 1/2 year
r = 0.1
sigma = 0.2
o_t = 'p' # type of option
std_T = sqrt(T)
pv_factor = exp(-r * T)
start = 1
stop = 50


### sample data generation

st = np.linspace(start, stop, stop - start).astype(int) # potential prices at maturity
intrinsic = np.maximum(K - st, 0)

d1 = (log(st / K) + (r + 0.5 * sigma ** 2) * 0.5) / (sigma * sqrt(T))
d2 = d1 - sigma * sqrt(T)
nd1 = norm.cdf(-d1, 0.0, 1.0)
nd2 = norm.cdf(-d2, 0.0, 1.0)

puts = K * exp(-r * T) * nd2 - st * nd1


### simple plotting of intrinsic and extrinsic value

plt.figure(figsize=(10, 6))
plt.plot(st, intrinsic, 'b-.', lw=2.5, label='intrinsic value')


### plot inner value at maturity

plt.plot(st, puts, 'r', lw=2.5, label='present value')


### plot option present value

plt.grid(True)
plt.legend(loc=0)
plt.xlabel('index level $$S_0$$')
plt.ylabel('present value $$C(t=0)$$')


The answer to your question: A European put option can be priced below intrinsic value in a high interest rate environment (such as r=0.1) when stock price is low enough. That is due to time value of money. The american put would be immediately exercised, but the european one cannot and you just have to wait patiently until maturity to get your payoff. Until then the market value will be approximately $$e^{-r T} (K-S)$$ rather than $$K-S$$ where $$S \ll K$$.

Two cosmetic comments about your code: (1) in d1 you hardwired the maturity 0.5 it would avoid later problems if you would use the variable T (2) you refer to st as the price at maturity, but the BS formula uses the current price of the stock usually written s0. No harm done, but confusing to the reader.

• In this figure you can see the relationship between the intrinsic value (straight line) and the european put option value (curve). The curve is below the straight line for very low S encrypted-tbn0.gstatic.com/… Jul 22 at 8:04
• Thank you both for the help. You both have been very insightful saving me time and head scratches! Jul 23 at 17:58