This is a hands-on guide to using SOAP2's GEX / VEX output to form a view on what forces are acting on the market, where it might be drawn or pushed, and which levels deserve attention, with particular attention to what changed since the previous snapshot. It needs no mathematics and no knowledge of the Greeks. Where a term is needed it is explained in plain words the first time.
It is written for two readers: a trader at the screen, and an AI assistant answering a trader's question through the SOAP2 AI bridge. The last section (§9) is the playbook for the second reader; every field name it uses is the real one.
Read this first. Everything below rests on one assumption: that dealers (market makers) are, on average, positioned a certain way, and hedge accordingly. SOAP2 estimates that position from open interest; it cannot see it. The levels you will derive are zones where a hedging effect is plausible, not barriers and not predictions. Nothing here is a trade signal. If you want the "why" behind the numbers, the theory primer explains it from first principles.
Related: GEX / VEX user guide (buttons and filters) · Theory primer · Dealer-positioning tutorial · AI assistant guide
When you buy an option, the firm that sold it to you usually does not want to bet on direction. It protects itself by trading the underlying (futures, ETF or shares) in the opposite direction, and it has to adjust that protection as the market moves. Those adjustments are real orders. SOAP2 estimates, from the open interest on every strike, how big they are and which way they point. Two effects matter:
Put together: GEX tells you how the market is likely to behave when it moves; VEX tells you what a change in volatility alone could do; the strike-by-strike map tells you where.
The same quantities appear in the OA GEX/VEX tabs, the CBOE GEX/VEX window and the AI bridge. Field names in
code are those the AI bridge returns.
| Output | Plain meaning | Trader's question it answers |
|---|---|---|
Net GEX (net_gex_bn, net_gex_sign) | The total brake-or-accelerator strength of the whole scope, in billions of dollars per 1% move. Positive = brake, negative = accelerator (under the standard dealer convention). | Which regime am I in, and how strong is it? |
Flip (flip, from_spot_now.flip) | The price level where the total changes sign when SOAP2 re-computes the picture at other prices. null means no sign change inside the range: the whole range is one regime. | How far am I from the regime boundary? |
Flip gradient (flip_gradient) | How steeply the total changes through the Flip. Steep = a clean boundary; shallow = a blurry one. | Is the boundary decisive or vague? |
Max / Min GEX level (max_gex_level, min_gex_level) | The prices at which the total is highest and lowest when swept. If the high point is positive it marks the strongest braking zone; if the low point is negative, the strongest accelerating zone. | Where is the braking (or accelerating) zone centred? |
Top strikes (top_strikes) | The strikes carrying the largest absolute net exposure, with call and put parts and open interest. | Which strikes are the "walls"? |
Call peak / put peak (call_peak_strike, put_peak_strike) | The strike with the most call-side exposure, and the strike with the most put-side exposure. | Where is the heaviest call positioning? The heaviest put positioning? |
Net VEX (net_vex_mm, net_vex_sign) | The total volatility-sensitivity of the hedge, in millions. A relative gauge, not a dollar flow (see the primer). | Is a volatility move likely to add to or fight the GEX picture? |
Distance from spot (from_spot_now, from_spot_at_compute) | Each level minus the current price, in index points. | How many points away is each level? |
Change since previous (change) | Net GEX/VEX change, spot change, Flip change, whether the Flip appeared or disappeared, and why the two runs may not be comparable. | What moved since the last snapshot, and is the comparison fair? |
Index points, not futures points. Levels are for the cash index (SPX, RUT, NDX). If you trade the futures (ES, RTY, NQ), add the current futures-to-cash difference to every level before using it.
Always work in this order. Skipping step 1 is how people trade yesterday's picture.
data_as_of (the newest trade inside the CBOE file),
not by computed_at or the file timestamp. The CBOE feed is about 15 minutes delayed and its open
interest is the previous session's.spot_source). A stale spot shifts every distance.| Situation | Reading |
|---|---|
| Net GEX positive, spot well above the Flip | Brake regime with a cushion. Expect smaller, mean-reverting ranges and pinning toward large strikes. Breakouts tend to fade unless something outside the options market drives them. |
| Spot close to the Flip (within roughly a typical day's move) | The regime is fragile. A small move can change how the market behaves. Treat the Flip as a trigger line, not a target. |
| Net GEX negative, spot below the Flip | Accelerator regime. Expect wider ranges, trending moves and faster reactions. Levels are places where speed can pick up, not places where price is likely to stall. |
Flip is null | The whole swept range is one regime (the sign of Net GEX). Use the distance to Max/Min GEX level and the top strikes instead. |
"Close" has no calibrated threshold in SOAP2. A practical yardstick is the day's expected move (for example from the market read's expected-move block, or the option-implied range on your own chain).
List the top strikes and mark the call peak and put peak. Note which are above and which below spot, and their size relative to the others. One dominant strike matters far more than a flat cluster. (How to turn this into levels is in §5.)
This is the most informative step, and the easiest to misread. See §4.
Where it comes from:
get_cboe_gex): every scope keeps a Latest and a
Previous run. Previous is only kept when it is a distinct earlier run, that is, 30 or more minutes
before the latest. A second call within half an hour overwrites Latest and keeps the older Previous. The
change block gives the net changes, spot_change, flip_change,
flip_appeared / flip_disappeared, elapsed_s, same_session and
the list changes_in_evidence.get_market_read returns stored GEX per expiry
(positioning.gex) plus a short gex_history of reduced snapshots (net GEX, Flip, Max/Min level over time).Open interest, the count of contracts outstanding, is only updated once per session. So:
Always read same_session and changes_in_evidence first. If both runs used the same CBOE
timestamp, the evidence list says so: nothing new came from the market, only the spot or settings differ.
| You see | Possible reading | Check before concluding |
|---|---|---|
| Net GEX more positive, spot flat | Brake strengthening: ranges likely to narrow, pinning gets more plausible. | Same session? Then it is mechanical (time or volatility), most often near expiry when gamma concentrates. |
Net GEX less positive or turning negative (net_gex_sign_changed true) | Cushion eroding or regime switched. Expect behaviour to become less self-stabilising. | Did spot just cross the Flip? A sign change after a big price move is the Flip being crossed, not a story about positioning. |
Flip moved up toward spot (flip_change positive, spot flat) | The safety zone is shrinking from below: the regime boundary is getting closer. | Compare with spot_change. If both moved together, distance may be unchanged. |
| Flip moved down, away from spot | The cushion is widening. | Same check. |
flip_appeared or flip_disappeared | The picture lost or gained its regime boundary within the range: the whole range is now (or no longer) one regime. | Strike range or interval changed? That alone can do it (see changes_in_evidence). |
| A new dominant strike appears among the top strikes | A new wall: a candidate pin or a new acceleration zone, depending on its sign (§5). | Different session or expiry? Rolled expiries make walls appear and vanish by definition. |
| A wall shrinks or vanishes | Positioning there was reduced, or the expiry holding it has aged out of the scope. | Different expiry set (changes_in_evidence)? |
| Net VEX shifts sign or grows, while volatility is falling or rising | The volatility-driven hedge changed: a volatility drop with positive VEX is the "volatility crush supports the market" set-up; a rise can push the other way. | VEX sign is the less settled of the two, so confirm with the GEX tab and with price action. |
| Almost nothing changed | A stable picture is information too: the levels from earlier remain the working map. | Was Previous really a different time? Under 30 minutes, you may be seeing the same pair. |
Rule of thumb: decompose any change into price moved (spot change), time and volatility moved (same session) and positions changed (new session). Only the last is a genuine change in who holds what.
A level's role depends on the regime. The same strike can attract price in one regime and speed it up in another.
| Level | In a brake regime (positive GEX) | In an accelerator regime (negative GEX) |
|---|---|---|
| Large positive-exposure strike (call-heavy) | Magnet / pin. Price tends to gravitate toward it and stall near it. Often where a range is bounded. | Less reliable: negative regime overrides. Treat as a possible slowing point only. |
| Large negative-exposure strike (put-heavy) | Inside a brake regime these are weaker; they mark where the brake thins out. | Acceleration zone: if price enters it, expect speed rather than a stall. Common folklore calls a put-heavy strike "support"; SOAP2 does not verify that, so test it (below). |
| Flip | The line below which the brake gives way. A breakdown through it is the signal that behaviour changes. | The line above which stability returns. A recovery through it is where acceleration should ease. |
| Max GEX level (positive peak) | Centre of the strongest braking zone: a likely pin area for the session. | Where the brake is still strongest, probably far from spot. |
| Min GEX level (negative trough) | Weaker than usual: the deepest accelerant lies outside the comfortable range. | Where acceleration should be strongest: a downside (or upside) "air pocket" if reached. |
SOAP2 stores the results (Results\{Symbol}\, and with Auto-Recompute the GEX history file) so you can
check how price behaved around your levels on past days before you put money on them. Do this for your instrument
and your scope; do not assume that a pattern seen on SPX 0DTE holds for monthly RUT.
Read the nearest large positive strikes as magnets and the Flip as the line you do not want to be on the wrong side of. Expect compression; premium-selling and fade styles have the wind behind them in this regime, and breakout styles do not. Risk: the cushion is only as good as the open interest behind it; read the change panel for erosion.
Expect larger and faster moves in both directions. Do not use big strikes as places to take profit blindly; they may be where speed picks up. Smaller size, wider stops, and respect for the Flip as the level that would bring stability back.
The regime itself is in doubt. Prefer to wait for a decisive move through the Flip, or trade with explicit invalidation on the Flip. A shallow gradient makes this more ambiguous: both regimes are weak near the boundary.
Gamma concentrates near the strike on the last day, so single-day scopes (0DTE) and the monthly-OPEX scope matter
most, and large strikes become the likeliest pins. Compare 0dte with opex: if a big strike
coincides in both, it deserves the most weight. After an OPEX, a lot of exposure disappears at once; the next
session's picture can look very different (same_session false), and that is normal.
Look at VEX before and after the event. A volatility drop with positive VEX is the textbook support for the market after an event; a volatility rise with the same sign works the other way. Whether the effect shows up depends on the size of the volatility move and on GEX at the time. Treat VEX as a supporting argument, not a lead.
These numbers are made up to show the method. They are not a forecast and not from a real session.
| Previous (10:00, same session) | Latest (11:00) | |
|---|---|---|
| Spot | 5,012 | 5,000 |
| Net GEX | +3.1 bn | +2.4 bn |
| Flip | 4,955 | 4,968 |
| Largest strikes | 5,050 (large +), 4,900 (large −) | 5,050 (large +), 4,900 (large −) |
| Net VEX | +120 mm | +95 mm |
Note the sentence "weakening as price slides toward the Flip" describes the geometry, not a belief that price will fall.
get_cboe_gex cover SPX, RUT and NDX.This section is the knowledge base for an assistant answering "what is the market doing, and where to?" from SOAP2 data. Follow it; it also encodes the bridge's rules (facts, not verdicts; a null is never 0).
| Question | Call | Notes |
|---|---|---|
| Index-wide dealer picture, any expiry scope, with change since previous | get_cboe_gex (symbol: SPX | RUT | NDX; mode: 0dte, 1dte, eom, opex, opex+1, aggregate or all; refresh default true; top_strikes 1 to 25) | Whole CBOE delayed chain. Fixed inputs: rate 4.15%, no dividend yield. Previous exists only if the earlier run is 30+ minutes old. |
| Picture from the user's own IB feed for an OA expiry | run_analysis with name="ib_gex" (optional symbol), then poll get_market_read and read positioning.gex and gex_history | Starts the OA's GEX/VEX pass in the background for its selected expiry. Answers started / blocked (with reason) / no_option_analysis. If the user is looking at an exclusive-data tool, the start is held back. |
| How is the dealer picture building into expiry? | get_trace | Separate dataset; never compare IB TRACE and CDN TRACE. |
| A volatility-context question | get_market_read (volatility blocks), get_skew_read, run_analysis | For the VEX argument. |
| The user's own trade versus the levels | get_trade_review, get_trade_probs | Compare breakevens with Flip and walls. |
Live-state calls need a Premium (or trial) licence and the AI bridge enabled; a denied call answers
NOT_LICENSED. Say so rather than guessing.
refresh=true (the default) for a current picture. If the user asked
for a comparison, make sure Previous exists; if not, report CBOE_GEX_NO_PREVIOUS and say that a diff
needs a run 30+ minutes after the last.data_as_of and its age, cboe_timestamp,
spot used and spot_source. After the close, data_as_of sits near 20:15 UTC for the
index options; say so.net_gex_sign, net_gex_bn, and the Flip versus spot using
from_spot_now.flip (fall back to from_spot_at_compute and say so). If flip
is null, say the range contains no sign change.top_strikes (sort by distance from spot), call_peak_strike,
put_peak_strike, max_gex_level, min_gex_level. Give each level's role in the
current regime (§5), not a fixed "support" or "resistance" label.change only with elapsed_s, same_session
and every item of changes_in_evidence. Decompose into spot move, time/volatility and (only if a new
session) positioning (§4). Never present an intraday change as new positioning.net_vex_sign and whether it reinforces or opposes GEX. Say the
VEX sign convention is the less settled one.refresh=true repeatedly to "get a diff": a second call inside 30 minutes does not
create a Previous.CBOE_FETCH_FAILED, CBOE_REFRESH_BUSY) and say that the
stored state is not fresh.Data: SPX, scope 0dte, CBOE chain as of 15:44 UTC (age 2 min), spot 5,000 (watchlist price).
Regime: Net GEX +2.4 bn (positive: brake under the usual convention). Spot is 32 points above the Flip (4,968), gradient moderate.
Map: Largest strikes: 5,050 (+), 4,900 (−). Max GEX level 5,040, min GEX level 4,880.
Change vs previous (60 min, same session): Net GEX −0.7 bn, Flip +13, spot −12. Mechanical: same open interest, so this is price and time, not new positioning.
VEX: positive (+95 mm), fading with GEX; no scheduled volatility event noted.
Reading (derived): brake regime weakening toward the Flip. Trigger 4,968; if lost, next large strike down is 4,900 (acceleration zone). While the brake holds, 5,050 is the pin/fade target. Invalidation: acceptance below 4,968.
Caveats: dealer positions are assumed, data ~15 min delayed, levels are zones, not a recommendation.
data_as_of), sensible spot.changes_in_evidence? price move, time/volatility, or positioning?Go back to the main help page: SOAP2 Help Guide