Free data

Free crypto GEX levels for your own charts

By Swiftedge · Published

The options levels Swiftedge draws on its own charts, gamma flip, call wall, put wall, the 0DTE levels and the strikes with the most gamma, as a free feed for TradingView, Sierra Chart, ATAS, Python, spreadsheets and bots. Bitcoin, Ethereum and Solana, from Deribit, OKX and Bybit, updated every minute. No account and no key.

Live now
loading… The current levels are also written out on the BTC, ETH and SOL GEX pages.

The endpoint

RequestReturns
GET /api/v1/gex-levels?coin=btcJSON: spot, gamma flip, call wall, put wall, 0DTE levels, net GEX, the ten largest strikes and the track record
&format=csvOne row per level: coin,time,type,price,net_gex_usd_per_1pct
&format=tvOne line to paste into the TradingView script below
&model=flowDeribit's dealer position from the trade flow instead of the long-calls/short-puts assumption
GET /api/gex/stats?coin=btcHow price reacted at past levels (see track record)

Base URL https://swiftedge.uk. Cross-origin requests are allowed, so the feed also works from a web page.

curl "https://swiftedge.uk/api/v1/gex-levels?coin=btc"
curl "https://swiftedge.uk/api/v1/gex-levels?coin=eth&format=csv"
curl "https://swiftedge.uk/api/v1/gex-levels?coin=sol&format=tv"

Example JSON (shortened):

{"coin":"BTC","time":"2026-10-25T12:00:00Z","spot":80550.1,"gamma_flip":79338.5,"call_wall":82000,"put_wall":78000,
 "zero_dte":{"gamma_flip":80556.7,"call_wall":81000,"put_wall":80000},"net_gex_usd_per_1pct":76740000,
 "top_strikes":[{"strike":80000,"net_gex_usd_per_1pct":-7331000}, ...],"track_record":{...},"source":"Swiftedge, https://swiftedge.uk/btc/gex"}

TradingView

  1. Open the Pine Editor in TradingView, paste the script below and click Add to chart.
  2. Open the BTC line (or ETH, SOL), or use the Copy TradingView line button above.
  3. In the indicator's settings, paste the line into Levels line. The gamma flip, call wall, put wall, 0DTE levels and largest strikes appear on any BTC chart, on any exchange and timeframe.
//@version=5
// Swiftedge GEX levels (crypto) - paste the line from swiftedge.uk/gex-api. Free with attribution: "Data: Swiftedge".
indicator("Swiftedge GEX levels (crypto)", shorttitle="SE GEX", overlay=true, max_lines_count=100, max_labels_count=100)

src = input.text_area("", "Levels line", tooltip="Open swiftedge.uk/api/v1/gex-levels?coin=btc&format=tv, copy the line and paste it here. The levels update every minute; paste again to refresh.")
showStrikes = input.bool(true, "Largest strikes")
showZero = input.bool(true, "0DTE levels")
colFlip = input.color(#ffd54f, "Gamma flip")
colCW = input.color(#ff5c8a, "Call wall")
colPW = input.color(#2ee6c8, "Put wall")
colPos = input.color(color.new(#4fc3f7, 35), "Positive strike")
colNeg = input.color(color.new(#ce93d8, 35), "Negative strike")
lineW = input.int(2, "Line width", minval=1, maxval=5)

var line[] lines = array.new_line()
var label[] labels = array.new_label()

drawLevel(float price, string txt, color c, int w, string st) =>
    l = line.new(bar_index - 1, price, bar_index, price, extend=extend.both, color=c, width=w, style=st)
    lb = label.new(bar_index + 3, price, txt + " " + str.tostring(price), style=label.style_label_left, color=color.new(c, 85), textcolor=c, size=size.small)
    [l, lb]

if barstate.islast
    for l in lines
        line.delete(l)
    for lb in labels
        label.delete(lb)
    array.clear(lines)
    array.clear(labels)
    for p in str.split(str.trim(src), "|")
        kv = str.split(p, "=")
        if array.size(kv) == 2
            k = array.get(kv, 0)
            v = array.get(kv, 1)
            if k == "S"
                if showStrikes
                    for s in str.split(v, ",")
                        sv = str.split(s, ":")
                        if array.size(sv) == 2
                            px = str.tonumber(array.get(sv, 0))
                            g = str.tonumber(array.get(sv, 1))
                            if not na(px) and not na(g)
                                [l1, lb1] = drawLevel(px, "GEX " + (g >= 0 ? "+" : "") + str.tostring(g / 1e6, "#.#") + "M", g >= 0 ? colPos : colNeg, 1, line.style_dotted)
                                array.push(lines, l1)
                                array.push(labels, lb1)
            else
                px = str.tonumber(v)
                isZero = str.endswith(k, "0")
                if not na(px) and (showZero or not isZero)
                    c = str.startswith(k, "FLIP") ? colFlip : str.startswith(k, "CW") ? colCW : colPW
                    nm = k == "FLIP" ? "Gamma flip" : k == "CW" ? "Call wall" : k == "PW" ? "Put wall" : k == "FLIP0" ? "0DTE flip" : k == "CW0" ? "0DTE call wall" : "0DTE put wall"
                    [l2, lb2] = drawLevel(px, nm, c, isZero ? 1 : lineW, isZero ? line.style_dashed : line.style_solid)
                    array.push(lines, l2)
                    array.push(labels, lb2)

Sierra Chart, ATAS, Python and spreadsheets

Track record: how price reacted at past levels

A level is touched when price comes within 0.15 % of it after being at least 0.4 % away. It held if price then moved 0.5 % back to the side it came from before closing a minute 0.3 % through it, and broke if it closed through first. Neither within two hours counts as undecided. The same rule on round numbers (BTC every $1,000, ETH $50, SOL $2) shows what any level does, so you can see whether the walls are different. Calculated every hour from our own minute-by-minute history.

loading… (also as JSON: /api/gex/stats?coin=btc)

Small samples swing a lot. This is a description of what happened, not a prediction.

Terms of use

Full terms. Questions or higher volumes: contact us.

Common questions

Is the GEX feed free?

Yes. You can use it in your own charts, bots, spreadsheets, Discord or Telegram bots and websites, free, as long as you credit "Data: Swiftedge (swiftedge.uk)" where the levels are shown. Do not resell the feed itself.

How often does it update?

Every minute, from Deribit, OKX and Bybit options. Polling once a minute per coin is plenty; please do not poll faster.

How is GEX calculated?

Gamma × open interest × price² × 1 %, summed per strike in USD. The sign assumes dealers are long calls and short puts; with model=flow, Deribit's dealer position comes from the trade flow instead. Nobody outside the dealers knows their real positions, so treat the levels as estimates.

Can TradingView load the levels automatically?

TradingView's Pine Script cannot fetch data from other websites, so the script reads a line you paste. Paste a fresh line when you want new levels; the call wall, put wall and flip usually move slowly within a day.

Do the levels work?

We publish how price reacted at past levels in the track record above, against round numbers as a comparison, with the sample size. The samples are still small. It is descriptive data, not a signal and not financial advice.

Which coins are covered?

Bitcoin, Ethereum and Solana (coin=btc, eth or sol).