Put-Call Pararity and Box Spread Arbitrage
Put-call parity is the no-arbitrage relationship linking a call, a put, the underlying, and the risk-free rate at a single strike and expiry. Violations imply conversion or reversal arbitrage; combinations across strikes create box spreads — synthetic risk-free loans embedded in the options chain. These are among the cleanest arbitrages in quantitative finance, but they are fought over by professional market makers with microsecond latency. This article states the math precisely, shows how box spreads work, and explains when retail or slow quant capital can still harvest dislocations.
Put-call parity
For European options on a non-dividend-paying underlying:
C - P = S - K × exp(-rT)
| Symbol | Meaning |
|---|---|
| C | Call price |
| P | Put price |
| S | Spot price |
| K | Strike |
| r | Risk-free rate |
| T | Time to expiry |
Conversion: buy stock, buy put, sell call → locks in K at expiry. If the package costs less than K×e^{-rT}, arbitrage profit.
Reversal: sell stock (short), buy call, sell put → synthetic short stock. If the package credits more than K×e^{-rT}, arbitrage profit.
American options and dividends modify the bounds (early exercise premium on calls, dividend adjustments). See Black-Scholes for the continuous-time derivation and Greeks for how parity failures show up as delta-neutral packages with non-zero carry.
import numpy as np
def parity_violation_bps(call, put, spot, strike, rate, ttm_years):
"""Positive = call rich (sell call, buy put, buy stock)."""
synthetic_fwd = call - put + strike * np.exp(-rate * ttm_years)
return (synthetic_fwd - spot) / spot * 10_000
# violation_bps > +transaction_cost → reversal arb
# violation_bps < -transaction_cost → conversion arb
The box spread
A box is long a call spread and long a put spread at the same strikes:
Box(K1, K2) = Long Call(K1) + Short Call(K2) + Long Put(K2) + Short Put(K1)
Payoff at expiry is always K2 - K1 regardless of spot. By put-call parity, the box price should equal (K2 - K1) × exp(-rT). If the market box trades cheap, you buy a synthetic bond; if expensive, you sell one.
box_price ≈ (K2 - K1) × exp(-rT)
implied_rate = -ln(box_price / (K2 - K1)) / T
Box spreads are used by:
- Arbitrage desks — to earn implied repo rates when box implied rate ≠ funding rate
- Borrowers/lenders — synthetic financing without touching the stock loan market
- Market makers — to hedge pin risk around strikes into expiry
Where dislocations come from
Parity should hold exactly in theory. In practice, violations arise from:
| Source | Effect | Typical size |
|---|---|---|
| Bid-ask on four legs | Apparent violation within spread | 5-50 bps |
| Hard-to-borrow stock | Puts rich, calls cheap on reversals | 10-500+ bps |
| Dividend uncertainty | Forward price mis-estimated | Variable |
| Early exercise (American) | Call floor above parity | Pennies to dollars |
| Stale quotes | Phantom arb in backtests | Meaningless |
| Pin risk into expiry | Box prices distort near strikes | Last few days |
| Regulatory capital | Some legs capital-intensive | Structural |
The actionable arb is when violation exceeds four-leg transaction costs + borrow fee + margin cost and persists for long enough to execute. On liquid index options (SPX, SPY), violations inside the spread are noise. On single names with high borrow, reversals can persist for days.
Execution: why paper arb dies live
A four-leg options arb requires:
- Simultaneous fill on all legs — legging risk is the main killer
- Margin — short options and stock borrow tie up capital; ROE may be 2-5% annualized
on a "risk-free" trade
- Assignment risk — American exercise on short calls around ex-dividend dates
- Stock borrow — reversal requires short stock; hard-to-borrow names have fees that
eat the edge (see short selling mechanics)
Professional desks use combo orders (exchange-defined spreads) to guarantee all-or-nothing fills. Retail without combo access faces legging risk on every attempt.
Box spread as financing
In 2019-2021, retail traders famously used SPX box spreads via IBKR as synthetic high-yield loans when box implied rates exceeded T-bills. The trade:
- Buy box below par → receive K2-K1 at expiry, pay less now → implied borrowing
- ROE depends on margin treatment (portfolio margin vs Reg T)
Risks that ended some participants:
- Assignment on short calls before expiry
- Margin calls if SPX moves and short legs are margined incorrectly
- Broker policy changes — brokers can restrict box spread strategies
- Tax treatment — may differ from simple interest income
This is classical arbitrage in structure but operational risk in practice.
Monitoring parity in a quant stack
A systematic monitor scans the options chain for parity violations:
def scan_parity(chain: list[dict], spot: float, rate: float, ttm: float,
min_bps: float = 15) -> list[dict]:
"""chain: list of {strike, call_bid, call_ask, put_bid, put_ask}"""
opps = []
for row in chain:
K = row['strike']
# Conservative: use ask for long legs, bid for short
rev_profit = (row['call_bid'] - row['put_ask']
+ K * np.exp(-rate * ttm) - spot)
conv_profit = (spot - row['call_ask'] + row['put_bid']
- K * np.exp(-rate * ttm))
for side, p in [('reversal', rev_profit), ('conversion', conv_profit)]:
bps = p / spot * 10_000
if bps > min_bps:
opps.append({'strike': K, 'side': side, 'bps': bps})
return opps
Filter for conservative fill prices (bid/ask, not mid). Require persistence — snapshot violations that disappear in 100ms are not tradable. Log borrow fees for reversals.
Connection to volatility trading
Put-call parity links the volatility surface to forward prices. If calls and puts at the same strike imply different implied vols (vol skew), parity still holds on prices — but the skew tells you about tail demand. Volatility arbitrage desks use parity-consistent packages (straddles, risk reversals) rather than naked directional options.
A risk reversal (long call, short put, delta-hedged) is effectively a synthetic forward; its mispricing vs the stock forward is a parity-relative trade, not a vol bet.
Key takeaways
- Put-call parity: C - P = S - K×e^{-rT}; violations imply conversion/reversal arb
- Box spreads synthesize risk-free payoff K2-K1; price implies a financing rate
- Real arb requires four-leg execution, borrow availability, and margin ROE analysis
- Bid-ask noise creates phantom violations — use conservative prices and persistence filters
- Box spread financing trades carry assignment, margin, and broker-policy risks
