Intraday Gamma Flip Tracker: When the Flip Moves Mid-Session | FlashAlpha

Intraday Gamma Flip Tracker: When the Flip Moves Mid-Session

The morning gamma-flip print is anchored to settled open interest and can be wrong by midday once real flow lands. The FlashAlpha /v1/flow/levels endpoint returns effective-OI versions of the gamma flip, call wall, put wall, and max pain, and /v1/flow/dealer-risk returns a flow_direction classifier that flags a regime_flip the instant the model sees it. This guide shows how to diff settled versus live levels and build a flip poller.

T
Tomasz Dobrowolski Quant Engineer
May 15, 2026
30 min read
GammaFlip CallWall PutWall IntradayFlow API DeveloperGuide OptionsFlow

If you are searching for whether the gamma flip moved, a live gamma flip API, real-time gamma flip versus the morning print, or an intraday call wall and put wall API, this is the guide. The flip is not fixed at 9:30. It tracks the open interest and gamma that accumulate while the session runs.


Why the Morning Gamma-Flip Print Goes Stale

The settled gamma flip is computed from end-of-day OPRA open interest from the prior session. That is a reasonable anchor at the open and an increasingly poor one as the day progresses. Every contract opened or closed during the session shifts the net gamma profile, and the strike where net GEX crosses zero - the flip - moves with it. By midday the settled flip can sit a level or more away from where the live profile actually crosses zero. The call wall and put wall drift for the same reason.

FlashAlpha computes a simulation-aware effective open interest: settled OPRA OI plus an intraday simulator delta (model confidence 0.43). The /v1/flow/* family is computed independently of the settled /v1/exposure/* family, so it can show the flip moving before the next settled print exists. The full derivation is in the pillar article, Live GEX vs Settled GEX: Intraday Options Flow Explained - this article assumes it and focuses on tracking the flip live.

The Endpoints: Live Levels and Dealer-Risk Shift

Two Growth-plan endpoints cover this. The first returns the effective-OI levels; the second classifies the settled-versus-live shift.

EndpointPlanReturns
GET /v1/flow/levels/{symbol}Growth+live_gamma_flip, live_call_wall, live_put_wall, live_max_pain - effective-OI versions of the settled levels
GET /v1/flow/dealer-risk/{symbol}Growth+Settled-versus-live shift with a flow_direction classifier

Both accept an optional ?expiry=YYYY-MM-DD to scope to one expiry. An invalid expiry returns 400 {"error":"invalid_expiry"}; a valid date with no contracts returns 404.

The flow_direction field on the dealer-risk endpoint is the classifier you alert on:

flow_directionMeaning
no_flowZero per-contract movement everywhere. The live profile equals the settled profile.
neutralFlow exists, but the absolute shift is under 5%. Levels barely moved.
amplifyingNet GEX kept the same sign and its magnitude grew. The existing regime got stronger.
dampeningNet GEX kept the same sign and its magnitude shrank. The existing regime weakened.
regime_flipNet GEX changed sign (positive to negative gamma or the reverse), or a regime was created from a zero baseline. This is a classifier on the settled-versus-live net GEX shift, not a statement that spot crossed the flip - check that separately.

This is how each level maps between the settled and live worlds:

LevelSettled (anchored to prior OPRA OI)Live (effective OI)
Gamma flip/v1/exposure/levels gamma_flip/v1/flow/levels live_gamma_flip
Call wall/v1/exposure/levels call_wall/v1/flow/levels live_call_wall
Put wall/v1/exposure/levels put_wall/v1/flow/levels live_put_wall
Max pain/v1/exposure/levels max_pain/v1/flow/levels live_max_pain

Live gamma flip, call wall, put wall, and a regime-flip classifier for 6,000+ symbols

Two API calls. Diff settled versus live. Catch a regime_flip the instant the model sees it.

Get API Access

Quick Start: Live Levels and the Flow Classifier

from flashalpha import FlashAlpha

fa = FlashAlpha("YOUR_KEY")

# Settled levels (anchored to prior OPRA OI)
settled = fa.exposure_levels("SPY")["levels"]

# Live levels (effective OI = settled + intraday simulator delta)
live = fa.flow_levels("SPY")

# Settled vs live shift with the flow_direction classifier
risk = fa.flow_dealer_risk("SPY")

print(f"Gamma flip   settled {settled['gamma_flip']}  ->  live {live['live_gamma_flip']}")
print(f"Call wall    settled {settled['call_wall']}   ->  live {live['live_call_wall']}")
print(f"Put wall     settled {settled['put_wall']}    ->  live {live['live_put_wall']}")
print(f"Max pain     settled {settled['max_pain']}    ->  live {live['live_max_pain']}")
print(f"flow_direction: {risk['flow_direction']}")
import { FlashAlpha } from 'flashalpha';

const fa = new FlashAlpha('YOUR_KEY');

const settled = (await fa.exposureLevels('SPY')).levels;
const live = await fa.flowLevels('SPY');
const risk = await fa.flowDealerRisk('SPY');

console.log(`Gamma flip: ${settled.gamma_flip} -> ${live.live_gamma_flip}`);
console.log(`Call wall: ${settled.call_wall} -> ${live.live_call_wall}`);
console.log(`flow_direction: ${risk.flow_direction}`);
using FlashAlpha;

var fa = new FlashAlphaClient("YOUR_KEY");

var settled = (await fa.ExposureLevelsAsync("SPY")).Levels;
var live = await fa.FlowLevelsAsync("SPY");
var risk = await fa.FlowDealerRiskAsync("SPY");

Console.WriteLine($"Gamma flip: {settled.GammaFlip} -> {live.LiveGammaFlip}");
Console.WriteLine($"flow_direction: {risk.FlowDirection}");
package main

import (
    "context"
    "fmt"
    flashalpha "github.com/FlashAlpha-lab/flashalpha-go"
)

func main() {
    fa := flashalpha.NewClient("YOUR_KEY")
    ctx := context.Background()

    settled, _ := fa.ExposureLevels(ctx, "SPY")
    live, _ := fa.FlowLevels(ctx, "SPY")
    risk, _ := fa.FlowDealerRisk(ctx, "SPY")

    fmt.Printf("Gamma flip: %.2f -> %.2f\n",
        settled.Levels.GammaFlip, live.LiveGammaFlip)
    fmt.Printf("flow_direction: %s\n", risk.FlowDirection)
}
curl -H "X-Api-Key: YOUR_KEY" \
  "https://lab.flashalpha.com/v1/flow/levels/SPY"

curl -H "X-Api-Key: YOUR_KEY" \
  "https://lab.flashalpha.com/v1/flow/dealer-risk/SPY"
$ pip install flashalpha  |  npm install flashalpha  |  dotnet add package FlashAlpha  |  go get github.com/FlashAlpha-lab/flashalpha-go

Response Walkthrough

The live levels response for SPY mid-afternoon:

{
  "symbol": "SPY",
  "as_of": "2026-05-15T15:45:12Z",
  "underlying_price": 597.50,
  "expiry": "2026-05-15",
  "live_gamma_flip": 595.50,
  "live_call_wall": 600,
  "live_put_wall": 590,
  "live_max_pain": 595
}

Spot at 597.50 sits above the live gamma flip of 595.50, so the live profile is in positive-gamma territory with dealer hedging dampening moves. The live call wall at 600 is the ceiling and the live put wall at 590 the floor. To see whether any of this moved versus the open, diff each field against the matching /v1/exposure/levels value. If the settled gamma flip was 597.00 and the live flip is now 595.50, the flip dropped below spot during the session: the dampening band widened, and a settled-only chart would still show the flip sitting essentially at spot.

Diffing Settled vs Live to See if the Flip Moved

The settled-versus-live difference is the signal. The raw level diff tells you how far each level moved; the flow_direction field on /v1/flow/dealer-risk tells you what that move means for the regime. The two together answer the question traders actually ask: did the flip move, and did it move through spot.

settled = fa.exposure_levels("SPY")["levels"]
live = fa.flow_levels("SPY")
risk = fa.flow_dealer_risk("SPY")
spot = live['underlying_price']

flip_shift = live['live_gamma_flip'] - settled['gamma_flip']
print(f"Gamma flip moved {flip_shift:+.2f} "
      f"({settled['gamma_flip']} -> {live['live_gamma_flip']})")

# Spot relative to flip: did spot change sides?
settled_side = "above" if settled['gamma_flip'] < spot else "below"  # spot relative to flip
live_side = "above" if live['live_gamma_flip'] < spot else "below"   # spot relative to flip
if settled_side != live_side:
    print(f"SPOT CHANGED SIDES: spot was {settled_side} flip, now {live_side}")

print(f"flow_direction: {risk['flow_direction']}")
if risk['flow_direction'] == "regime_flip":
    print("Net GEX changed sign - dealer hedging behavior reversed")

A regime_flip from flow_direction means net GEX changed sign or a regime was created from a zero baseline. That is the event you want the instant it happens, not in tomorrow's settled print. The raw flip shift gives you the magnitude and whether the flip crossed spot; the classifier gives you the verdict.

A Live Gamma-Flip Poller

Poll the levels and dealer-risk endpoints, compare the live flip to spot, and fire on a regime_flip:

from flashalpha import FlashAlpha
import time

fa = FlashAlpha("YOUR_KEY")
symbol = "SPY"
last_side = None

while True:
    try:
        live = fa.flow_levels(symbol)
        risk = fa.flow_dealer_risk(symbol)

        spot = live['underlying_price']
        flip = live['live_gamma_flip']
        side = "above" if flip < spot else "below"  # spot relative to flip
        direction = risk['flow_direction']

        # Classifier-driven regime flip: act immediately
        if direction == "regime_flip":
            print(f"REGIME FLIP: flow_direction=regime_flip  "
                  f"spot {spot}, live flip {flip}")
            send_alert(symbol, "regime_flip", spot, flip)

        # Spot crossing the live flip the model recomputed
        if last_side is not None and side != last_side:
            print(f"SPOT CROSSED LIVE FLIP: spot now {side} flip "
                  f"(spot {spot}, flip {flip})")
            send_alert(symbol, "flip_cross", spot, flip)

        last_side = side
        time.sleep(120)  # poll every 2 minutes
    except Exception as e:
        print(f"Error: {e}")
        time.sleep(60)

The regime_flip classifier and the spot-crossing check answer different questions. The classifier catches the net-GEX sign change wherever it happens; the crossing check catches spot moving through the live flip the model just recomputed. Alert on both.

$ pip install flashalpha
>>> fa.flow_levels("SPY")
{"live_gamma_flip": 595.50, "live_call_wall": 600, ...}
View Growth+ Access
Live Flow Levels Require Growth+

API Access and Pricing

Both flow endpoints are on the Growth plan or higher. The /v1/flow/* family is computed independently of the settled /v1/exposure/* family.

PlanPriceFlow Levels + Dealer RiskRate Limit
Free$0No5 req/day
Basicfrom $63/moNo100 req/day
Growthfrom $239/moYes2,500 req/day
Alphafrom $1,199/moYesUnlimited

Test both endpoints in the interactive API playground with your own key before writing code. The per-stock dashboards visualize the same data the API returns.

Frequently Asked Questions

Yes. The gamma flip is the price where net dealer gamma exposure crosses zero, and that profile changes as contracts are opened and closed during the session. The settled flip is anchored to the prior day's OPRA open interest, so by midday it can sit a strike or more away from where the live profile actually crosses zero. The FlashAlpha /v1/flow/levels endpoint returns live_gamma_flip computed from effective open interest so you can see where the flip is now, not where it was at the open.
Poll GET /v1/flow/levels/{symbol} for live_gamma_flip and GET /v1/flow/dealer-risk/{symbol} for the flow_direction classifier. Compare live_gamma_flip to spot to see which side of the flip price sits on, and alert when flow_direction returns regime_flip. Both endpoints accept an optional ?expiry parameter to scope to a single expiry.
The settled gamma flip (gamma_flip on /v1/exposure/levels) is computed from the prior session's settled OPRA open interest and does not change until the next settled print. The live gamma flip (live_gamma_flip on /v1/flow/levels) is computed from effective open interest, which is settled OPRA OI plus an intraday simulator delta (model confidence 0.43), so it moves as the session's flow lands. Diff the two to see whether the flip moved during the day. The pillar article on live versus settled flow has the full derivation.
regime_flip is one of five flow_direction values. It means net GEX changed sign between the settled and live profiles - positive to negative gamma or the reverse - or a regime was created from a zero baseline. The other values are no_flow (zero per-contract movement), neutral (flow exists but the absolute shift is under 5%), amplifying (same-sign net GEX, magnitude grew), and dampening (same-sign, magnitude shrank). A regime_flip is the highest-signal value because it means dealer hedging behavior has reversed.
Yes. The call wall and put wall are strikes defined by where dealer gamma is concentrated, and that concentration shifts as flow lands during the session. The /v1/flow/levels endpoint returns live_call_wall and live_put_wall from effective open interest. Diff them against call_wall and put_wall on /v1/exposure/levels to see whether the walls moved versus the morning print.
GET /v1/flow/levels/{symbol} and GET /v1/flow/dealer-risk/{symbol} are both on the Growth plan (from $239/mo, 2,500 requests/day) or the Alpha plan (from $1,199/mo, unlimited). The Free and Basic tiers do not include the flow family. The /v1/flow/* endpoints are computed independently of the settled /v1/exposure/* endpoints.

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!