How PIN & Max Pain Are Calculated
The math behind every number in a symbol card's stat row: Spot, PIN, Max Pain, Call Wall, Put Wall, PCR and Conf.
1. Data inputs
Every 5 minutes during market hours (9:00–16:00 ET, Mon–Fri) the engine pulls the options chain for each symbol from yfinance. For each expiry it uses:
- Open interest (OI) per strike, for calls and puts separately. This is the green and red lines on the OI chart.
- Spot price of the underlying.
- ATM straddle price: the at-the-money call plus put premium. It's the market's implied expected move to expiry (shown as
ExpMvin the morning briefing).
yfinance data is delayed about 15 minutes, so every number on the dashboard reflects the market roughly 15 minutes ago.
2. Max Pain
Max pain is the strike where the most option value expires worthless. Equivalently, it's the settlement price at which option holders collectively get paid the least.
The formula
For each candidate settlement price K, add up what every open contract would be worth if the underlying settled exactly at K:
The × 100 is the contract multiplier. It scales every strike equally, so it doesn't change which one wins.
Worked example
Five strikes with spot at 7,445:
| Strike | Call OI | Put OI | Call payout | Put payout | Total pain |
|---|---|---|---|---|---|
| 7,400 | 500 | 3,000 | $0 | $19.8M | $19.8M |
| 7,420 | 800 | 2,600 | $1.0M | $8.8M | $9.8M |
| 7,440 ◀ | 1,500 | 1,800 | $3.6M | $3.0M | $6.6M |
| 7,460 | 2,500 | 700 | $9.2M | $0.8M | $10.0M |
| 7,480 | 3,000 | 400 | $19.8M | $0 | $19.8M |
Example: settling at 7,440 puts the 7,400 calls 40 points in the money (500 × 40 × 100 = $2.0M) and the 7,420 calls 20 points in the money (800 × 20 × 100 = $1.6M), for $3.6M in call payout. The 7,460 and 7,480 puts add $1.4M + $1.6M = $3.0M. No other strike has a lower total, so Max Pain = 7,440.
Local search window (v3 fix)
A search over every listed strike lets large deep out-of-the-money positions drag max pain to levels price can't realistically reach. On SPX that once put us about $90 away from optioncharts.io. The engine now only considers strikes inside a window around spot:
The window scales with implied volatility (a pricier straddle gives a wider window) and never shrinks below ±5%. This change cut the gap to optioncharts.io to about $20.
Stale fallback
If the resulting max pain is still more than 5% from spot, it's treated as stale and the engine anchors to spot instead.
3. Call Wall, Put Wall & PCR
- Call Wall
- The strike with the largest call open interest. Dealer hedging around heavy call OI tends to act as resistance. In the example above it's 7,480.
- Put Wall
- The strike with the largest put open interest, which tends to act as support. In the example above it's 7,400.
- PCR (Put/Call Ratio)
total put OI ÷ total call OIfor the expiry. Above 1 means more puts than calls are open (defensive positioning). Below 1 means calls dominate.
4. Zero Gamma, Major +Vol & Major −Vol
These three levels come from gamma exposure (GEX): an estimate of how much stock or futures market makers have to buy or sell to stay hedged as price moves. The standard convention assumes dealers are long the gamma on calls and short the gamma on puts. Calls therefore count as positive and puts as negative.
Gamma exposure per strike
Positive GEX: dealers sell into rallies and buy dips, which dampens moves and helps pinning. Negative GEX: dealers chase price in the same direction, which amplifies moves.
- Zero Gamma (gamma flip)
- The price where total dealer gamma changes sign. The engine reprices every option's gamma at a grid of hypothetical spot prices, sums GEX across all strikes at each one, and finds where the total crosses zero, interpolating between the two grid points on either side:
for each test price P near spot: Total(P) = Σ GEX(s) with Γ recomputed at spot = P Zero Gamma = P where Total(P) crosses 0 e.g. Total(7,710) = −$0.4B, Total(7,720) = +$0.4B → Zero Gamma ≈ 7,715Above zero gamma the market tends to be calmer and mean-reverting. Below it, moves tend to be faster and trend.
- Major +Vol (major positive volume level)
- The strike with the largest positive gamma from today's traded volume rather than open interest:
Major +Vol = strike with max of call_Γ(s) × call_volume(s) × 100 × spot² × 0.01Open interest only updates overnight, but volume updates intraday. This level shows where today's call activity is building a magnet or resistance.
- Major −Vol (major negative volume level)
- Same idea using puts. It's the strike with the largest negative volume-based gamma:
Major −Vol = strike with max of put_Γ(s) × put_volume(s) × 100 × spot² × 0.01This is where today's put activity is concentrated. It often acts as intraday support, or as an accelerant if price breaks through it.
5. PIN (engine v3)
PIN is the predicted settlement price at expiry. It starts from max pain and gives max pain more weight as expiry gets closer, because pinning pressure from dealer hedging is strongest in the final hours.
Step 1: Time fraction
Step 2: Smooth max pain weight
| Time (ET) | time_fraction | Max pain weight | Remaining weight |
|---|---|---|---|
| 9:30 open | 0.00 | 55% | 45% |
| 11:07 | 0.25 | 64% | 36% |
| 12:45 | 0.50 | 74% | 26% |
| 14:22 | 0.75 | 83% | 17% |
| 16:00 close | 1.00 | 92% | 8% |
The remaining weight goes to the live-market inputs (current spot and, when it's in range, the call wall). Earlier versions used hard phase buckets, so the PIN line stayed flat and then jumped. The continuous ramp gives a smooth line on the scan-history chart.
Step 3: Call wall filter
The call wall only counts if it's close to spot. The allowed distance tightens through the day:
A distant call wall can't be reached late in the session, so it shouldn't move the prediction.
Step 4: Structural distance cap
Finally, PIN is clamped so it can't sit further from spot than price can plausibly travel in the time left:
Near the close, time_left approaches zero, so PIN converges on spot unless max pain is already right next to it.
6. Confidence score (Conf)
Conf is a 0–100% score for how much to trust the PIN. It has three parts:
- Proximity: the closer max pain is to spot (in %), the higher the base score. If price is already near max pain, it doesn't have far to go.
- Time bonus: up to +15, growing toward the close as pinning forces strengthen.
- Data quality adjustment:
Quality Adjustment GOOD 0 PARTIAL −5 POOR −15
7. Reading a live card, step by step
Here's a real SPX 0DTE stat row and how each number was produced:
| Field | Value | How it's derived | What it tells you |
|---|---|---|---|
| Max Pain | $7,715 | Pain(K) computed for every strike in the local window. 7,715 had the lowest total payout. | The settlement that hurts option buyers most. |
| Call Wall | $7,730 | Strike with the highest call OI | Overhead resistance, $15 above max pain |
| Put Wall | $7,720 | Strike with the highest put OI | Support. Here it sits above max pain, so puts are packed right on top of the pin zone. |
| Zero Gamma | $7,715 | Total GEX at hypothetical prices crosses 0 at 7,715 | Dealer gamma flips exactly at max pain. Price is balanced on the line between calm and fast markets. |
| Major +Vol | $7,725 | Strike with the largest call volume × gamma today | Today's call activity is building a magnet just above. |
| Major −Vol | $7,710 | Strike with the largest put volume × gamma today | Today's put activity is building a magnet just below. |
| PCR | 1.003 | Total put OI ÷ total call OI | Almost perfectly balanced positioning, with no directional skew. |
| PIN | $7,715 | Max pain weighted 55–92% by time of day, call wall filter, then distance cap | All inputs agree, so PIN lands on max pain. |
| Conf | 95% | Proximity score + time bonus (≤ +15) + data quality (GOOD = 0) | Very high, because every level is inside a $20 band. |
Why PIN = $7,715 here
- Max pain = 7,715. This is the anchor, and it gets 55–92% of the weight depending on the time of day.
- Call wall check: |7,730 − 7,715| = 15 points ≈ 0.19% of spot. That's under even the tightest 0.8% end-of-day threshold, so the wall is considered. It only pulls slightly upward, and the result rounds back to the 7,715 strike.
- Distance cap: with spot near 7,715, the expected-move cap doesn't bind.
- Cross-check: zero gamma (7,715) and the volume magnets on either side (7,710 / 7,725) bracket the same strike. When max pain, zero gamma and the volume levels converge like this, pinning tends to be strongest.
Why Conf = 95%
The proximity/time split above is illustrative. The engine reports only the final total.
8. Limitations
- 15-minute delay. yfinance quotes and OI lag the market. Most of the remaining ~$20 max pain gap vs optioncharts.io comes from this delay.
- OI updates overnight. Exchanges publish open interest once per day, so intraday changes in positioning don't show in max pain until the next session. Only spot and time-based terms move during the day.
- GEX is an estimate. Zero Gamma and the volume levels assume dealers are long calls and short puts. Actual dealer positioning isn't public, so treat these as approximate zones rather than exact prices.
| Typical accuracy | Before v3 | After v3 |
|---|---|---|
| Max pain vs optioncharts.io | ~$90 off | ~$20 off |
| SPX daily PIN error (end of day) | ±$30–50 | ±$10–20 |
| Stock PIN error | ±$10–15 | ±$3–10 |
PIN is a statistical tendency, not a guarantee. News, macro events (FOMC, CPI) and large flows can override pinning pressure entirely.