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')
par = ((c.bid + c.ask)/2. - (p.bid + p.ask)/2.).dropna()
# 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')
par = ((c.bid + c.ask)/2. - (p.bid + p.ask)/2.).dropna()
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.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

1 Answer 1


This paper tries to explain the exact problem you're facing. They're essentially saying that LEAP puts are overpriced relative to calls 80% of the time (makes sense if you consider widespread hedging of institutional equity portfolios using index put options). To expand on what they're saying, you should consider the prices you're putting into your calculations and how they're derived.

If you're using settles, they'll be based on much wider bid-ask spreads for LEAPs when compared to your nearer expiry options. If you're using actual bid/ask prices, the impact would be even more noticeable. This drift away from a tight market consensus on what price/vol should be (one way to interpret bid-ask), represents uncertainty in model inputs over longer and longer periods of time.

In my opinion, given the above uncertainty and transaction costs, whatever difference you're seeing is what the market has priced in as the arbitrageur's risk in trying to profit from long term put/call disparity.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .