Max Pain Analysis API
Max pain analysis for any US equity or ETF. Pain curve, OI breakdown, dealer alignment overlay (gamma flip, call/put walls), pin probability scoring, expected move context, and multi-expiry calendar.
ES=F or NQ=F and URL-encode the = as %3D - e.g. /v1/maxpain/ES%3DF. Options-on-futures are priced with Black-76 using the CME multiplier ($50/pt ES, $20/pt NQ); CME index futures are Growth-tier. See the futures hub.
Endpoint
X-Api-Key)
Rate Limited: Yes
Basic+
Parameters
| Name | In | Required | Default | Description |
|---|---|---|---|---|
symbol |
path | yes | - | Underlying symbol (e.g. SPY, QQQ, AAPL) |
expiration |
query | no | nearest | Expiration date in yyyy-MM-dd format. Omit for full-chain analysis plus per-expiry breakdown. |
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://lab.flashalpha.com/v1/maxpain/SPY"
import requests
resp = requests.get(
"https://lab.flashalpha.com/v1/maxpain/SPY",
headers={"X-Api-Key": "YOUR_API_KEY"}
)
data = resp.json()
print(f"Max Pain Strike: {data['max_pain_strike']}")
print(f"Pin Probability: {data['pin_probability']}/100")
print(f"Distance: {data['distance']['percent']}% {data['distance']['direction']}")
print(f"Signal: {data['signal']}")
print(f"Dealer Alignment: {data['dealer_alignment']['alignment']}")
const resp = await fetch(
"https://lab.flashalpha.com/v1/maxpain/SPY",
{ headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const data = await resp.json();
console.log(`Max Pain Strike: ${data.max_pain_strike}`);
console.log(`Pin Probability: ${data.pin_probability}/100`);
console.log(`Distance: ${data.distance.percent}% ${data.distance.direction}`);
console.log(`Signal: ${data.signal}`);
console.log(`Dealer Alignment: ${data.dealer_alignment.alignment}`);
Response
{
"symbol": "SPY",
"underlying_price": 548.32,
"as_of": "2026-04-09T15:12:34Z",
"max_pain_strike": 545,
"expiration": "2026-04-09",
"distance": { "absolute": 3.32, "percent": 0.61, "direction": "above" },
"signal": "neutral",
"put_call_oi_ratio": 1.82,
"regime": "positive_gamma",
"pin_probability": 74,
"pain_curve": [
{ "strike": 540, "call_pain": 8200000, "put_pain": 34600000, "total_pain": 42800000 },
{ "strike": 542, "call_pain": 10500000, "put_pain": 27600000, "total_pain": 38100000 },
{ "strike": 545, "call_pain": 14200000, "put_pain": 14250000, "total_pain": 28450000 },
{ "strike": 548, "call_pain": 21800000, "put_pain": 10800000, "total_pain": 32600000 },
{ "strike": 550, "call_pain": 28400000, "put_pain": 10800000, "total_pain": 39200000 }
],
"oi_by_strike": [
{ "strike": 540, "call_oi": 12400, "put_oi": 38200, "total_oi": 50600, "call_volume": 320, "put_volume": 1480 },
{ "strike": 545, "call_oi": 45200, "put_oi": 41800, "total_oi": 87000, "call_volume": 2100, "put_volume": 3200 },
{ "strike": 550, "call_oi": 52800, "put_oi": 18400, "total_oi": 71200, "call_volume": 4800, "put_volume": 980 }
],
"max_pain_by_expiration": [
{ "expiration": "2026-04-09", "max_pain_strike": 545, "dte": 0, "total_oi": 1240000 },
{ "expiration": "2026-04-11", "max_pain_strike": 547, "dte": 2, "total_oi": 890000 },
{ "expiration": "2026-04-16", "max_pain_strike": 550, "dte": 7, "total_oi": 1520000 },
{ "expiration": "2026-04-23", "max_pain_strike": 552, "dte": 14, "total_oi": 680000 }
],
"dealer_alignment": {
"alignment": "converging",
"description": "Max pain at 545 sits below spot (548.32). Gamma flip at 546.50 near max pain. Call wall at 550 acts as resistance, put wall at 540 as support.",
"gamma_flip": 546.50,
"call_wall": 550,
"put_wall": 540
},
"expected_move": {
"straddle_price": 4.85,
"atm_iv": 18.2,
"max_pain_within_expected_range": true
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
underlying_price | number | Current spot price of the underlying |
max_pain_strike | number | Strike where total option holder pain (intrinsic value) is minimized. See max pain |
distance | object | absolute (dollars), percent, and direction (above or below) from spot to max pain |
signal | string | Composite signal: strong_pin, moderate_pin, neutral, weak_pin |
put_call_oi_ratio | number | Total put OI divided by total call OI across the chain. See put/call OI ratio |
regime | string | positive_gamma, negative_gamma, or undetermined. See gamma regime |
pin_probability | number | 0-100 composite score: OI concentration, proximity to max pain, time to expiry, gamma magnitude. See pin risk |
pain_curve[] | array | Pain at each strike: call_pain, put_pain, total_pain (USD). See pain curve |
oi_by_strike[] | array | Per-strike breakdown: call_oi, put_oi, total_oi, call_volume, put_volume. See highest OI strike |
max_pain_by_expiration[] | array | Max pain strike for each available expiration with dte and total_oi |
dealer_alignment.alignment | string | converging, moderate, or diverging - how well max pain aligns with GEX levels. See dealer alignment |
dealer_alignment.description | string | Human-readable summary of dealer alignment context |
dealer_alignment.gamma_flip | number | Price level where dealer gamma flips from positive to negative. See gamma flip |
dealer_alignment.call_wall | number | Strike with highest call GEX - acts as resistance. See call wall |
dealer_alignment.put_wall | number | Strike with highest put GEX - acts as support. See put wall |
expected_move.straddle_price | number | ATM straddle price in dollars. See expected move |
expected_move.atm_iv | number | At-the-money implied volatility (annualized %) |
expected_move.max_pain_within_expected_range | boolean | Whether max pain strike falls within the expected move range |
What Is Max Pain?
Max pain is the strike price where the total intrinsic value of all outstanding options (both calls and puts) is minimized at expiration. In theory, this is the price at which option writers (predominantly dealers and market makers) lose the least money, creating a gravitational pull on the underlying as expiration approaches.
This endpoint combines the classic max pain calculation with GEX dealer alignment data - gamma flip, call/put walls, and net gamma exposure - to give you a complete picture of where dealer positioning and option holder pain intersect. When the max pain strike aligns with key GEX levels, the pin probability increases significantly.
Common Use Cases
- Gauge pin conviction - read
pin_probability(0-100) to decide whether to fade moves towardmax_pain_strikeor stand aside into expiration - Anchor credit spreads - center iron condors on
max_pain_strikeand set wings atdealer_alignment.call_wall/put_wallfor high-probability structures - Time the pin entry - use
distance.percentanddistance.directionto know how far spot must travel to reach max pain and which way to lean - Confirm with dealer alignment - act only when
dealer_alignment.alignmentreadsconvergingandgamma_flipsits near max pain, raising pin odds - Plan roll timing - compare
max_pain_by_expiration[]across expiries to roll positions where max pain and OI concentrate - Filter by expected move - gate setups on
expected_move.max_pain_within_expected_rangeso you only pin-trade when max pain is reachable inside the straddle - Map the pain landscape - plot
pain_curve[]andoi_by_strike[]to visualize where holder pain bottoms and OI clusters
Related
Related reading
- Max pain options explained - theory, math, dealer mechanics, and when it works
- Max pain trading strategies & pin risk - iron condors, 0DTE pin fades, and expiration setups
- SPY max pain history by date - a worked historical look at how SPY tracked max pain
Complementary endpoints
- Key Levels - gamma flip and call/put walls to cross-check the pin setup
- Gamma Exposure (GEX) - per-strike gamma the dealer-alignment block is derived from
- Flow Pin Risk - real-time flow-based pin-risk score alongside the OI-based pin probability
- 0DTE Analytics - same-day pin risk, expected move, and gamma acceleration
Ready to build?
Get your free API key and start pulling live options data in 30 seconds.