The LAB vocabulary
Every column a rule can name: 105 of them, in 9 groups, with the unit, the range, the book it reads and one condition that uses it. The same dictionary the compiler is given, so what you read here is what it understands.
How a rule is written
A rule is one or two legs. A leg has a direction, up or down,
the way the trade profits, and a list of conditions on the columns in the groups on the
left, all of which must hold at the same minute. The engine then measures the move over the
next 5, 15 or 30 minutes of the same session, after a cost, against the core condition
alone, out of sample. Say it in words in the LAB chat and it is compiled into this shape;
send the shape itself through the API.
{"name": "FOMC last-hour fade",
"legs": [{"dir": "down", "when": [
{"col": "ev_fomc", "op": ">=", "value": 1, "core": true},
{"col": "min", "op": "between", "value": [330, 330]}]}],
"horizon": 30, "cost": 1.0, "good_move": 3.0}
Operators
| operator | meaning |
|---|---|
>= <= > < | compare with a number |
abs>= abs<= | compare the magnitude, sign ignored: distances, flows, changes |
between | inside [lo, hi], inclusive; [300, 300] is one exact minute |
top_pctl abs_top_pctl | in the top share of the column's own distribution over the whole store, 0.5 … 0.99; 0.9 is the top decile, signed or by magnitude |
Three things to know first
Distances are signed: spot minus the level, positive above it, so "at the wall" is
abs<= a few points and "above the flip" is flip_dist > 0.
Unqualified levels read the measured book; the _volcp and
_oi twins read the other two, and a rule should not mix books.
The last minutes have no outcome: a condition on min must leave
horizon minutes of session, so keep it at or below 384, 374 or 359 for the 5,
15 and 30-minute horizons.
The same reference as JSON, for scripts and assistants: /api/lab/vocabulary. Every column is computed per minute over every archived session by the Lab's feature-store builder; a new column reaches the compiler, this page and the API in the same deploy.
Time in the session
Where in the day the rule is read. Minute 0 is 09:30, 389 is 15:59; a rule that fires inside the last `horizon` minutes measures nothing, so keep min ≤ 389 − horizon.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
min | minutes since the 09:30 open (0-389) | minutes since 09:30 | 0 … 389 | min between [300, 330] | |
mins_left | minutes remaining to the close | minutes to 15:59 | 0 … 389 | mins_left <= 60 |
Price, VWAP and the move just made
The index itself, the session VWAP and its band, and the last few minutes of tape. Distances are signed index points, positive above.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
spot | SPX spot price | index points | the SPX level | spot >= 5000 | |
vwap | session VWAP | index points | the session VWAP | vwap > 0 | |
vwap_dist | spot - vwap, points | points, signed | negative below VWAP | vwap_dist >= 10 | |
vwap_sigma | one sigma of the VWAP band, points | points | one sigma of the band, > 0 | vwap_sigma <= 4 | |
vwap_z | spot distance from VWAP in sigmas (+3 = stretched 3 sigma above) | sigmas, signed | typically −4 … +4 | vwap_z >= 3 | |
b2u | upper 2-sigma VWAP band | index points | upper 2σ band | spot >= b2u is not allowed; use vwap_z >= 2 | |
b2l | lower 2-sigma VWAP band | index points | lower 2σ band | vwap_z <= -2 | |
candle_delta | 1-minute spot change, points | points, signed | one minute's change | candle_delta abs>= 5 | |
ret15 | spot now minus spot 15 minutes ago, index points (the move just made; positive = drifted up) | points, signed | spot now − 15 min ago | ret15 <= -3 | |
ret30 | spot now minus spot 30 minutes ago, index points | points, signed | spot now − 30 min ago | ret30 abs>= 10 | |
rv_1m | intra-minute realized vol, annualised -- directly comparable to atmiv (implied); a choppy vs smooth minute | annualised % | intra-minute realised vol | rv_1m >= 25 |
Dealer levels and distances
The zero-gamma flip, the hold band, the call wall and put support, as signed distances from spot. Unqualified names read the MEASURED book; the *_volcp and *_oi twins read the volume and open-interest books.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
flip | gamma flip level, price | index points | the zero-gamma strike | measured | flip_dist abs<= 5 (prefer the distance) |
flip_dist | spot - gamma flip, points (+ = above the flip / positive-gamma side, - = below) | points, signed | spot − flip; + above | measured | flip_dist abs<= 5 |
gamma_pos | positive-gamma regime flag: 1 above the flip (pin / mean-revert), 0 below (trend) | flag | 1 above the flip, 0 below | measured | gamma_pos >= 1 |
hold_lo | lower dealer hold level | index points | lower edge of the hold band | measured | hold_lo_dist abs<= 5 |
hold_hi | upper dealer hold level | index points | upper edge of the hold band | measured | hold_hi_dist abs<= 5 |
hold_lo_dist | spot - lower dealer hold, points (- = below it) | points, signed | spot − hold_lo | measured | hold_lo_dist <= 3 |
hold_hi_dist | spot - upper dealer hold, points (+ = above it) | points, signed | spot − hold_hi | measured | hold_hi_dist >= -3 |
cr0_dist | spot - the major positive-gamma strike (call-side wall / resistance), MEASURED book, points (+ = above it) | points, signed | spot − call wall; negative below it | measured | cr0_dist abs<= 5 |
ps0_dist | spot - the major negative-gamma strike (put-side support), MEASURED book, points (+ = above it) | points, signed | spot − put support; positive above it | measured | ps0_dist abs<= 5 |
cr0_strength | how much of the near-money book stands on the call-side wall's own strike, 0..1 (1 = the book's fattest strike; the terminal draws line width from this) | share | 0 … 1 of the near book on that strike | measured | cr0_strength >= 0.3 |
ps0_strength | same for the put-side support strike, 0..1 -- a thin level is drawn like any other but may behave like none | share | 0 … 1 | measured | ps0_strength >= 0.3 |
flip_volcp_dist | spot - the volume-book gamma flip, points -- an alternative flip construction | points, signed | spot − volume-book flip | volume | flip_volcp_dist abs<= 5 |
cr0_volcp_dist | spot - the call-side wall of the VOLUME book, points (+ = above it) | points, signed | spot − volume-book call wall | volume | cr0_volcp_dist abs<= 5 |
ps0_volcp_dist | spot - the put-side wall of the VOLUME book, points (+ = above it) | points, signed | spot − volume-book put support | volume | ps0_volcp_dist abs<= 5 |
cr0_oi_dist | spot - the call-side wall of the OPEN-INTEREST book at 0DTE, points (+ = above it) | points, signed | spot − OI-book call wall | open interest | cr0_oi_dist abs<= 5 |
ps0_oi_dist | spot - the put-side wall of the OPEN-INTEREST book at 0DTE, points (+ = above it) | points, signed | spot − OI-book put support | open interest | ps0_oi_dist abs<= 5 |
flip_struct_dist | spot - the open-interest (structural) gamma flip, points -- the third flip alongside flip_dist and flip_volcp_dist | points, signed | spot − OI-book (structural) flip | open interest | flip_struct_dist abs<= 10 |
cw_agree | how many of the three books name the SAME call-side wall, 1..3. Agreement is rare -- 22% of minutes -- so 3 is a genuinely unusual state, not a default | count | 1 … 3 books naming the same call wall | all three | cw_agree >= 2 |
pw_agree | same for the put-side wall; the books agree here in only 2% of minutes | count | 1 … 3 | all three | pw_agree >= 2 |
cw_agree_dist | points from spot to the call wall the books agree on (negative = it is above spot). Null when they name different strikes | points, signed | spot − the agreed call wall | all three | cw_agree_dist abs<= 5 |
pw_agree_dist | points from spot to the agreed put wall; positive = it is below spot | points, signed | spot − the agreed put support | all three | pw_agree_dist abs<= 5 |
The dealer book and its flow
Net exposures at spot and how fast they are changing. Level columns are the state; *_flow and mc* columns are what moved in the last minutes.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
dex | dealer delta exposure | $ of index delta | signed; + = dealers long delta | measured | dex <= 0 |
dealer_dex | dealer delta exposure (alias) | $ of index delta | alias of dex | measured | dealer_dex top_pctl 0.9 |
vex | vanna exposure | $ per vol point | signed | measured | vex abs_top_pctl 0.9 |
charm | charm exposure | $ delta per day | signed | measured | charm <= 0 |
vanna | vanna pressure (distinct from vex) | $ delta per vol point | signed | measured | vanna abs_top_pctl 0.9 |
gpct | gamma percentile vs history | percentile | 0 … 100 vs the last 20 sessions | measured | gpct <= 20 |
ngv_meas | net gamma value, measured | $M | net gamma at spot, signed | measured | ngv_meas <= 0 |
ngv_conv | net gamma value, conventional | $M | net gamma at spot, signed | open interest | ngv_conv >= 0 |
ngv_volcp | net gamma value, volume-cp book -- the third book alongside ngv_meas / ngv_conv | $M | net gamma at spot, signed | volume | ngv_volcp <= 0 |
meas_conv_div | ngv_meas - ngv_conv: the tape-signed book minus the call-minus-put OPEN-INTEREST book. Not a measured-vs-volume pair -- that is ngv_volcp | $M | ngv_meas − ngv_conv | measured vs OI | meas_conv_div abs>= 50 |
dgamma_flow | minute-over-minute change of net gamma (dGamma flow) | $M per minute | signed change of ngv_meas | measured | dgamma_flow abs_top_pctl 0.9 |
dex_flow | 1-minute change in dealer delta exposure | $ per minute | 1-minute change of dex | measured | dex_flow abs_top_pctl 0.9 |
vex_flow | 1-minute change in vanna exposure | $ per minute | 1-minute change of vex | measured | vex_flow >= 0 |
charm_flow | 1-minute change in charm | $ per minute | 1-minute change of charm | measured | charm_flow <= 0 |
mc5 | max-change GEX over 5 min -- flow velocity: how much the busiest strike's gamma just moved | $M | largest single-strike gamma change over 5 min | measured | mc5 top_pctl 0.9 |
mc15 | max-change GEX over 15 min (flow velocity) | $M | over 15 min | measured | mc15 top_pctl 0.9 |
mc30 | max-change GEX over 30 min (flow velocity) | $M | over 30 min | measured | mc30 top_pctl 0.9 |
concentration | Herfindahl of near-money gamma: high = the book sits in a few strikes and pins hard, low = spread out | Herfindahl | 0 … 1; high = a few strikes hold it | measured | concentration >= 0.3 |
The unsigned book (GROSS)
|gamma| × open interest per strike, calls and puts summed, no side assigned: how much convexity there is and where it sits. The two-sided measured book alongside it.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
gross_total | sum of |gamma| x open interest over the near-money window, $M per index point. Magnitude only | $M/pt | sum over the near-money window | unsigned | gross_total top_pctl 0.8 |
gross_at_spot | the unsigned book on the strike nearest spot, $M/pt | $M/pt | the strike nearest spot | unsigned | gross_at_spot >= 100 |
gross_up | the heaviest unsigned strike ABOVE spot, $M/pt | $M/pt | heaviest strike above spot | unsigned | gross_up >= 150 |
gross_dn | the heaviest unsigned strike BELOW spot, $M/pt | $M/pt | heaviest strike below spot | unsigned | gross_dn >= 150 |
gross_up_dist | points from spot up to that heaviest strike above, always positive | points, always positive | distance to gross_up | unsigned | gross_up_dist <= 5 |
gross_dn_dist | points from spot down to the heaviest strike below, always positive | points, always positive | distance to gross_dn | unsigned | gross_dn_dist <= 5 |
gross_near_share | share of the unsigned book within +-10 pt of spot, 0..1 -- how much convexity sits on top of price | share | 0 … 1 within ±10 pt of spot | unsigned | gross_near_share >= 0.5 |
gross_top3_share | share of the unsigned book on its three heaviest strikes, 0..1 -- concentration | share | 0 … 1 on the three heaviest strikes | unsigned | gross_top3_share >= 0.6 |
signed_over_gross | sum |measured gamma| / sum unsigned: how much of the convexity the tape-signed book accounts for. Low = the books cancel, the sign is thin | ratio | 0 … 1; low = the sides cancel | measured ÷ unsigned | signed_over_gross <= 0.15 |
meas_below | sum |measured gamma| on strikes within 30 pt BELOW spot, $M/pt | $M/pt | sum |measured γ| within 30 pt below spot | measured | meas_below >= 50 |
meas_above | same within 30 pt ABOVE spot, $M/pt | $M/pt | sum |measured γ| within 30 pt above spot | measured | meas_above >= 50 |
meas_below_chg15 | change of meas_below against the frame 15 min earlier (negative = the book below thinned) | $M/pt, signed | change of meas_below over 15 min | measured | meas_below_chg15 <= -20 |
meas_above_chg15 | change of meas_above over 15 min (positive = the book above thickened) | $M/pt, signed | change of meas_above over 15 min | measured | meas_above_chg15 >= 20 |
meas_below_chg30 | change of meas_below over 30 min | $M/pt, signed | over 30 min | measured | meas_below_chg30 <= -20 |
meas_above_chg30 | change of meas_above over 30 min | $M/pt, signed | over 30 min | measured | meas_above_chg30 >= 20 |
The expiry split
Today's 0DTE against everything that survives it, per book. Only sessions archived since the wide book carry it; earlier days are NaN and never match.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
gam_0dte | measured gamma, TODAY's expiry only ($M) | $M | today's expiry, net at spot | measured | gam_0dte <= 0 |
gam_next | measured gamma past today -- the book that survives the close ($M) | $M | the book that survives today | measured | gam_next >= 0 |
gam_next_share | share of the measured book that outlives today (0..1) | share | 0 … 1 | measured | gam_next_share >= 0.6 |
gam_vol_0dte | volume-book gamma, 0DTE only ($M) | $M | today's expiry | volume | gam_vol_0dte <= 0 |
gam_vol_next | volume-book gamma past today ($M) | $M | surviving book | volume | gam_vol_next >= 0 |
gam_vol_next_share | share of the volume book that outlives today (0..1) | share | 0 … 1 | volume | gam_vol_next_share >= 0.6 |
gam_oi_0dte | open-interest gamma, 0DTE only ($M) | $M | today's expiry | open interest | gam_oi_0dte <= 0 |
gam_oi_next | open-interest gamma past today ($M) | $M | surviving book | open interest | gam_oi_next >= 0 |
gam_oi_next_share | share of the OI book that outlives today (0..1) -- the OI book is roughly half next-expiry, so this one really moves | share | 0 … 1 | open interest | gam_oi_next_share >= 0.6 |
book_width | how many post-0DTE expiries the session was ARCHIVED with -- a provenance stamp, not a market state. ~21 on a batch-built day, 3 on a live one (a live payload's flow book really is narrow). Use it ONLY to keep a rule that touches the gam_* columns inside one definition of them; never as a market condition, and never in a rule that does not reference gam_* | count | 3 before 2026-08-17, ~21 after | book_width >= 10 |
Implied and realised volatility
The 0DTE ATM surface, the straddle, skew, and realised volatility over three windows, plus the ratios that make them comparable across days.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
atmiv | ATM implied-vol level (pair with top_pctl for an 'IV rank') | IV, % | 0DTE at-the-money | atmiv top_pctl 0.9 | |
atmiv_chg | 1-minute change in ATM implied vol | IV points per minute | signed | atmiv_chg >= 0.5 | |
straddle | ATM straddle price | index points | the 0DTE ATM straddle | straddle >= 30 | |
straddle_pct | ATM straddle as a % of spot -- the expected move, comparable across days | % of spot | the expected move | straddle_pct >= 0.6 | |
exp_range | expected range implied by the straddle | index points | the implied range for the session | exp_range >= 40 | |
range_used | |spot - vwap| / expected range -- how much of the day's implied range is spent | ratio | |vwap_dist| ÷ exp_range | range_used >= 1 | |
div30 | 30-min realized-minus-implied divergence -- the VRP proxy | vol points | realised − implied, 30 min | div30 >= 5 | |
vrp_ratio | realized/implied ratio (rvi30 / atmiv); >1 = realized outrunning what's priced | ratio | realised ÷ implied; > 1 = tape outrunning | vrp_ratio >= 1.2 | |
rvi15 | 15-min realized vol | ratio | realised ÷ implied, 15 min | rvi15 >= 1.5 | |
rvi30 | 30-min realized vol | ratio | 30 min | rvi30 <= 0.7 | |
rvi60 | 60-min realized vol | ratio | 60 min | rvi60 >= 1.2 | |
skew | put/call skew | vol points | 25Δ put − call IV | skew top_pctl 0.9 | |
skewpct | 25-delta skew as a RATIO: put IV over call IV minus one, in PERCENT (median ~10, 95th pctl ~25) -- NOT a 0-1 percentile; 'rich skew' is skewpct >= 15 or top_pctl on it | percent | put IV over call IV minus one; ≈ −2 … 25, median ≈ 10. NOT a 0…1 percentile | skewpct >= 15 | |
skew_chg | 1-minute change in put/call skew | vol points per minute | signed | skew_chg >= 0.2 |
Volume
Contracts printed across the whole 0DTE chain per minute, and its rank inside the session.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
vol | per-minute traded volume | contracts per minute | whole 0DTE chain | vol_pctl >= 0.9 (rank it, do not threshold contracts) | |
vol_pctl | traded-VOLUME percentile of this minute vs the same minute of the prior 20 sessions (0-1) -- 'heavy for this time of day'; volume, NOT implied vol | percentile | 0 … 1 against the same minute of the prior 20 sessions | vol_pctl >= 0.9 | |
vol_snap | volume as the snapshot carries it | contracts per minute | the snapshot's own series | vol_snap >= 1000 |
The market calendar
The scheduled-event context of the session, from the same calendar the terminal draws: day flags for FOMC, CPI, payrolls, PCE, ISM, earnings and opex, and two clocks to the nearest in-session event.
| column | what it is | unit | range | book | a condition that uses it |
|---|---|---|---|---|---|
ev_high | 1 on a day with a high-impact release: FOMC, CPI, payrolls or PCE; else 0 | flag | 1 on FOMC, CPI, payrolls or PCE days | ev_high >= 1 | |
ev_fomc | 1 on an FOMC decision day (statement 14:00, press conference 14:30) | flag | 1 on a decision day | ev_fomc >= 1 | |
ev_cpi | 1 on a CPI day (08:30, before the open) | flag | 1 on a CPI day | ev_cpi >= 1 | |
ev_nfp | 1 on a payrolls day (08:30, before the open) | flag | 1 on a payrolls day | ev_nfp >= 1 | |
ev_pce | 1 on a PCE inflation day (08:30, before the open) | flag | 1 on a PCE day | ev_pce >= 1 | |
ev_ism | 1 on an ISM day, manufacturing or services (10:00, inside the session) | flag | 1 on an ISM day | ev_ism >= 1 | |
ev_earn | 1 when a mega-cap (NVDA, AAPL, MSFT, ...) reports today, before the open or after the close | flag | 1 when a mega-cap reports | ev_earn >= 1 | |
ev_opex | 1 on a monthly or quarterly options expiration day | flag | 1 on monthly / quarterly expiration | ev_opex >= 1 | |
ev_pre_open | 1 if a high/medium release came out before 09:30, so the session already trades AFTER the number | flag | 1 if a release came out before 09:30 | ev_pre_open >= 1 | |
ev_mins_to | minutes until the next scheduled event inside the session (FOMC 14:00, ISM 10:00, FOMC minutes); NaN when none is ahead, so a condition on it selects event days by itself | minutes | to the next in-session event; NaN if none | ev_mins_to between [30, 90] | |
ev_mins_since | minutes since the last scheduled event inside the session; NaN before the first one | minutes | since the last in-session event; NaN before it | ev_mins_since <= 15 |