# Why do I see differences in put-call parity on longer dated options?

The put-call parity equation says that `call - put = spot - discount*strike`. When I fit a line to mid-market `call - put` and `strike` (of SPX options) the spot price (the x-intercept) that I get from this is slightly lower than the real spot price, and it gets lower the longer dated the option is. A two year LEAP gives me a spot price about 3-5% below the actual one.

It doesn't seem to be noise; I've tried refreshing the data several times today and I reliably get the same result. What does it mean?

Here is my code:

``````import scipy, yfinance
import matplotlib.pyplot as plt

def opt_after(ticker, days):
min_date = (date.today() + timedelta(days=days)).strftime('%Y-%m-%d')
return ticker.option_chain(next(d for d in ticker.options if d >= min_date))

t = yfinance.Ticker("^SPX")
mo2, y2 = opt_after(t, 61), opt_after(t, 365*2)

print('actual', t.history().Close[0])

c, p = mo2.calls.set_index('strike'), mo2.puts.set_index('strike')
# Use an outlier-robust fit
riskfree, spot, *_ = scipy.stats.theilslopes(par, par.index)
print('2 month', spot)

plt.scatter(par.index, par)
plt.plot([0, 5000], [spot, 5000*riskfree + spot], label='2 month')

c, p = y2.calls.set_index('strike'), y2.puts.set_index('strike')
riskfree, spot, *_ = scipy.stats.theilslopes(par, par.index)
print('2 year', spot)

plt.scatter(par.index, par)
plt.plot([0, 5000], [spot, 5000*riskfree + spot], label='2 year')
plt.legend()
plt.xlabel('strike')
plt.ylabel('call - put')
``````
• Is your Python code missing something? I tired to run it, but to get it work, I had to add the following two lines: from datetime import date from datetime import timedelta
– Bob
Dec 11, 2023 at 2:43