Can You Filter GEX by Moneyness, Trade Intent, or Strip Out Spreads? What Actually Helps | FlashAlpha

Can You Filter GEX by Moneyness, Trade Intent, or Strip Out Spreads? What Actually Helps

Traders regularly ask to filter the exposure calculations - OTM only, opening vs closing, exclude multi-leg spreads. Two of the three are already doable today and one is a conceptual trap. Moneyness is a few lines client-side because /v1/exposure/gex returns call_gex and put_gex split per strike. Opening vs closing is already baked into the flow surface via effective OI. Excluding spreads from the walls fights the dealer-hedging model - keep them in, and isolate intent on the flow side instead.

T
Tomasz Dobrowolski Quant Engineer
Jun 2, 2026
20 min read
GammaExposure API OptionsFlow DealerPositioning DeveloperGuide

Here is the request, near-verbatim, the way it usually lands in our inbox - a thoughtful options trader building a dashboard on the exposure endpoints:

"The exposure endpoints (GEX, DEX, VEX, CHEX by strike) are central to my decisions. I'd love to filter the calculations like some other platforms offer:

- Moneyness - OTM only, ATM only, or ITM only. OTM positioning tends to carry more directional signal.

- Opening vs closing - new directional intent vs position management are very different signals.

- Exclude complex/multi-leg trades - spreads and hedges dilute the directional read of walls and flip levels."

It is a sharp request, and the instinct behind it is good. Let's take the three asks in the order of how useful - and how feasible - they actually are.


1. Moneyness filtering - you can do this today

This is the most feasible of the three, and the good news is you don't have to wait for us: the data to do it is already in the response you're pulling. The /v1/exposure/gex endpoint returns, for every strike, call_gex and put_gex split out separately, plus the underlying_price. That split is the whole game.

There is one subtlety that trips people up, and it's the reason "OTM only" is not the same as "strikes above spot." Moneyness is a per-leg property, not a per-strike property. At any given strike, the call and the put have opposite moneyness:

  • A call is out-of-the-money when its strike is above spot.
  • A put is out-of-the-money when its strike is below spot.

So an OTM-only gamma reading keeps the call contribution from the upper half of the chain and the put contribution from the lower half:

otm_net_gex = Σ call_gex[K]  for K > spot
            + Σ put_gex[K]   for K < spot

itm_net_gex = Σ call_gex[K]  for K < spot
            + Σ put_gex[K]   for K > spot

atm_net_gex = Σ net_gex[K]   for |K - spot| / spot ≤ band   (e.g. band = 0.02)

In Python, against the live response, that is a few lines:

r    = client.get("/v1/exposure/gex/SPY").json()
spot = r["underlying_price"]

otm_gex = sum(s["call_gex"] for s in r["strikes"] if s["strike"] > spot) \
        + sum(s["put_gex"]  for s in r["strikes"] if s["strike"] < spot)

# call wall / put wall on the OTM-only set are just argmax/argmin:
otm = [s for s in r["strikes"]
       if (s["strike"] > spot and s["call_gex"]) or (s["strike"] < spot and s["put_gex"])]

What is trivial client-side: a moneyness-filtered net GEX/DEX (one filtered sum), the call wall / put wall (argmax over the filtered strikes), and the regime sign. The one part that takes an extra step is the gamma flip - it's the zero-crossing of the cumulative net-GEX curve against spot, so it's a small loop rather than a one-liner, but it's fully derivable from the same per-strike data.

Because /v1/exposure/gex is available from the Free tier up, this OTM read is open to essentially every user right now. A native moneyness= parameter is on our radar mainly so you don't have to re-derive the flip each time - and, more importantly, so the same filter can be applied to the live flow GEX, where reconstructing it by hand is much harder.

2. Opening vs closing - already baked into the flow surface

This one sounds like it requires a brand-new feature, but it's largely already shipped - just on a different surface than the settled exposure endpoints. The key is that open interest alone cannot tell you opening from closing - settled OI is a static net count with no provenance. What can tell you is the trade tape, and that's exactly what our effective-OI methodology is built on.

The /v1/flow/* suite recomputes GEX, DEX, walls, gamma flip, and max pain off effective OI: the morning's settled open interest plus an intraday simulator that side-classifies every print. A buy that opens new positioning builds OI; closing flow works it back down. That distinction - new directional intent versus position management - is precisely the "opening vs closing" signal, and it updates through the session rather than sitting frozen at the morning print.

Concretely:

  • /v1/flow/summary/{symbol} returns flow_direction, intraday_oi_delta, live_gex, and flow_gex_pct_shift - the headline "how far has today's flow moved positioning" read. (Growth+)
  • /v1/flow/levels/{symbol} gives the live flip and walls after the intraday flow is folded in. (Growth+)
  • The scored flow-signals tape goes further, tagging each print with an explicit opening/closing bias, aggressor, and conviction score. (Alpha+)

So if the goal is "show me where today's new directional flow is concentrated," the answer is to read the flow surface, not to ask the settled exposure endpoint to do something its input data can't support.

3. Excluding multi-leg spreads - the trap

This is the ask we'd gently push back on, because the intuition - "spreads and hedges dilute the directional read" - quietly assumes GEX walls are a sentiment gauge. They aren't. Walls and flip levels are a map of dealer hedging mechanics.

A dealer has to hedge their net gamma regardless of how the customer assembled the position. A short-gamma exposure that came from a vertical spread produces exactly the same hedging flow as one from an outright. So stripping spread legs out of the walls would not "clean up" the signal - it would understate the real hedging pressure and move your levels away from where the market actually reacts.

It's worse than neutral on index and ETF names, which is where most GEX dashboards point. There, a large share of the most important strikes - the big collar, overwrite, and calendar levels - are structured positions. "Exclude spreads" risks deleting precisely the walls that matter most, handing you a cleaner-looking but less predictive chart. (For why decomposing put and call structure is its own can of worms, see our piece on directional VRP and put/call decomposition.)

And mechanically, it isn't even recoverable from the settled data: open interest carries no spread provenance. The only place you could attempt it is the trade tape, where complex orders can sometimes be detected - and even there, real multi-leg leg-by-leg decomposition is genuinely hard.

The instinct is right - the layer is wrong

What this trader actually wants is directional conviction, separated from hedges and management. That's a real and valuable cut - it just lives on the flow/intent layer, not the exposure walls. The flow-signals feed already classifies each trade's structure and intent, so the right version of the request is "show me the GEX impact from naked directional prints only" - tape-native and additive - rather than "subtract spreads from the settled-OI walls," which fights the model.

The three asks at a glance

RequestStatusHow
Moneyness (OTM/ATM/ITM) Do it today /v1/exposure/gex already splits call_gex/put_gex per strike; filter per-leg against underlying_price. Native moneyness= param on the roadmap.
Opening vs closing Already shipped (flow surface) /v1/flow/summary + /v1/flow/levels via effective OI; scored open/close bias on the flow-signals tape.
Exclude multi-leg spreads Reframe, don't build Spreads create real dealer hedging - keep them in the walls. Isolate directional intent on the flow side instead.

Per-strike GEX with the call/put split, plus the live flow surface

Everything you need to build moneyness and intent filters yourself.

Get API Access

Frequently Asked Questions

Yes, today, client-side. /v1/exposure/gex returns call_gex and put_gex separately for each strike plus underlying_price. OTM is a per-leg filter: sum call_gex where the strike is above spot and put_gex where the strike is below spot. Net GEX, call/put walls, and regime fall straight out; gamma flip needs one extra step (zero-crossing of the cumulative curve). A native moneyness= parameter is on the roadmap.
Because moneyness is a property of the contract, not the strike. At a single strike, the call and the put have opposite moneyness - a call is OTM above spot, a put is OTM below spot. So an OTM-only read keeps the call leg from the upper half of the chain and the put leg from the lower half. That's exactly why the API returns call_gex and put_gex split out: it lets you filter each leg independently.
Settled open interest can't - it's a static net count with no opening/closing provenance. The /v1/flow/* surface can, because it's built on effective OI: settled OI plus an intraday simulator that side-classifies the tape, so opening flow builds OI and closing flow reduces it. Call /v1/flow/summary for flow_direction and flow_gex_pct_shift, or the flow-signals tape for per-trade opening/closing bias.
No. GEX walls measure dealer hedging mechanics, and a dealer must hedge their net gamma no matter how the customer built the position - a spread creates just as much real hedging flow as an outright. Excluding spreads would move the walls away from where the market actually reacts, and on index names it can delete the most important structured levels. If you want to isolate directional conviction, do it on the flow-intent layer, not by subtracting spreads from the walls.
Not automatically. The published net_gex, gamma_flip, and walls are computed over the full chain. If you filter to a subset (say OTM only), the per-strike values are still correct, but you re-aggregate the totals yourself: net GEX is a filtered sum, the walls are argmax/argmin over the filtered strikes, and the flip is the zero-crossing of the filtered cumulative curve. All of it derives from the per-strike call_gex/put_gex the endpoint already returns.

Live Market Pulse

Get tick-by-tick visibility into market shifts with full-chain analytics streaming in real time.

Intelligent Screening

Screen millions of option pairs per second using your custom EV rules, filters, and setups.

Execution-Ready

Instantly send structured orders to Interactive Brokers right from your scan results.

Join the Community

Discord

Engage in real time conversations with us!

Twitter / X

Follow us for real-time updates and insights!

GitHub

Explore our open-source SDK, examples, and analytics resources!