Methodology

This page exists so you can argue with us. Every figure quoted anywhere on this site is produced the way it is described here, and where a test failed, the failure is written down in the same detail as the successes.

Three rules everything follows

The same three rules get applied to things that are not price data. In the finance influencer audit we grade market commentary sources — newsletters, Substacks, X accounts — against their full posting history, benchmark-adjusted, failures published.

The day-type model

Status note: this model's read is served in the day_type block of GET /v1/brooks/{symbol}, alongside the rolling event read described in the section below. Because a day type is a property of a whole session, the block exists in the day session only; in the Asian and gap windows it returns available: false with the reason. The implementation was rewritten to run without a deep-learning runtime on the server, and the rewrite was checked against the original across the full history before it went live — same model, same weights, same numbers. The held-out results and the gating study below are unchanged and still power the QQQ strategy case study.

A day type is a coarse description of how a session behaved: did it trend one way all day, chop sideways, grind upward inside a channel, or reverse. Experienced chart readers name these on sight. The model does the same thing, in probabilities.

Results, on years the model never saw

Full session, top-1
66%
vs a 37% majority baseline
Full session, top-2
80%
truth is in the model's top two classes
At 90 minutes in
53.5%
18 five-minute bars; top-2 68.6%
Calibration error
<10%
stated probability vs observed frequency

The 90-minute number is the one that matters for live use, and it is the smaller one. Two hours into a session the market has not decided yet, and a model that claimed otherwise would be lying.

Single stocks are out of distribution. The model was fitted to index futures. Reads on single stocks, Hong Kong listings, A-shares and non-index futures were never validated and carry no accuracy claim — descriptive only. (The same boundary discipline carries over to the rolling event read that now lives at /v1/brooks: its response marks every symbol outside the measured set with a coverage_note.)

The rolling event read, and how it was measured

Since 2026-08-06, GET /v1/brooks/{symbol} detects classical price-action events — the day's first range breakout, breakout follow-through, closes in the top or bottom third of an established range, breakouts from long-lived ranges, climactic spikes — and attaches to each the outcome rate measured for that exact definition in that exact window. Three windows were measured separately on ES 5-minute bars, 2010–2026, under a pre-registered protocol with the definitions frozen before the confirmatory run: the US day session, the Asian session (09:00–16:00 Beijing), and the gap window (16:00–21:30 Beijing — between the Asian close and the US open).

Breakout failure rate within 5 bars within 10 bars within 20 bars
US day session (n≈3,900)52.1%62.6%70.6%
Gap window (n≈3,900)50.4%62.8%72.4%
Asian session (n≈3,900)46.7%58.7%69.4%

One event per day — the first breakout — so the live detection and these rates describe the same population. Two classical claims failed outright in this program and the endpoint says so where relevant: the 50/50 long-range-breakout direction claim reversed (57.8% upward in the US session, skewed in every window), and the sell-zone half of the range-position claim did not confirm in the US session or the gap window.

The per-event conditional estimate

Every breakout looks different, so beyond the base rates the endpoint fits a small gradient-boosted model over twelve rolling features of the event itself — range tightness, breakout-bar strength, how often the range had been tested, recent travel — and returns a calibrated probability that this particular breakout closes back through its level within 10 bars. The confirmatory protocol was pre-registered with one judged cell: NQ futures, 2023 and later — an instrument and a period the model never trained on. Result: AUC 0.646; the lowest predicted tercile of breakouts failed 54.2% of the time against 79.1% in the highest; calibration error 5.1% with the calibrator frozen before the run; n=2,637. A plain logistic regression passes the same gates, and the transfer repeats on QQQ (AUC 0.660, n=2,017). On symbols other than ES, NQ and QQQ the estimate is descriptive and the response carries a coverage_note saying so.

Full pre-registration documents, frozen definitions, the amendment record (including the switch of the volatility base to a 5-day average when the 20-day version proved unobtainable in production — verified to move every published figure by less than half a point), and the complete result tables including the failed cells are in the repository's research records. POST /v1/brooks/backtest runs the identical detectors over bars you supply, so the calibration table can be reproduced on your own data.

The price-action claims fact-check

Trading courses are full of confident probabilities. We took the ones that are specific enough to be testable, wrote each as an explicit rule before measuring anything, and ran it over 3,946 ES trading days of 5-minute data, 2010–2026.

ClaimTraditionally quotedMeasured
One of the day's two extremes is already set, 5 minutes in (1 bar) 20% 26.3%
One of the day's two extremes is already set, 35 minutes in (7 bars) 50% 58.3%
One of the day's two extremes is already set, 90 minutes in (18 bars) 90% 81.2%
On a bull day, the low of the day forms early in the session 90% 83.3%
On a bear day, the high of the day forms early in the session 90% 80.4%
After an opening-range (18-bar) breakout, the opposite extreme holds 90% 83.5%
Trading-range breakouts fail (the famous "80% rule") 80% 52.0% / 62.4% / 69.7%

The last row is measured within 5, 10 and 20 bars respectively — the claim's truth depends entirely on how long you are willing to wait, which the claim never says. Every row covers the same 3,946 days except two: the opening-range breakout can only be scored on the 3,578 days that produced a breakout at all, and the “80% rule” row counts range-breakout events rather than days — roughly 5,000 to 9,700 events depending on the bar window.

Meta-verdict: the direction is right every time. Where the teaching quotes a big round number — 90%, 80% — the measured rate comes in below it by roughly 7 to 10 percentage points, and by considerably more on the "80% rule". The two earliest checkpoints run the other way: an extreme is pinned slightly sooner than the courses say. A workable calibration for the rest of the genre: trust the direction, discount the round number by about a tenth. It is also, quietly, a compliment — these were people describing real market behaviour from memory, and they got the sign right in every case.

The seven rows above are the complete measured set, and this page is where they live: free to read, no key and no account. They are not the whole library — 15 more high-measurability claims are structured but not yet measured, and they will be added here when they are. The long-form write-up, including what happened when the framework was trained into a model and the three places it failed outright, is at Al Brooks price action, tested.

How to cite this

The table above is the measured rate for each claim, with the sample it was measured on. Free to read, no key and no account — link straight to it.

Plain text

Quant Data. "The price-action claims fact-check: seven classic claims measured against 3,946 ES trading days." quantdata.uk. https://quantdata.uk/methodology#claims

BibTeX

@misc{quantdata-claims-factcheck,
  author       = {Quant Data},
  title        = {The price-action claims fact-check: seven classic claims measured against 3,946 ES trading days},
  year         = {2026},
  howpublished = {\url{https://quantdata.uk/methodology#claims}},
}

Permanent link

https://quantdata.uk/methodology#claims

Quoting a figure from this page is fine without asking. If you want the underlying per-observation table for something we have not published, or you spot a number you think is wrong, mail quantdata@quantdata.uk — a corrected number is worth more to us than a cited one.

Weis Wave events

A Weis Wave chart throws away the time axis and groups price into up-waves and down-waves, labelling each with the total volume that traded inside it. The idea, from the Wyckoff tradition, is that a rally on shrinking volume and a sell-off on heavy volume mean different things.

Wave construction

The five events

How they were tested

Pre-registered before measurement: entry on the event bar, symmetric barriers at ±3 × ATR, and a win defined as reaching the barrier in the event's claimed direction first. Run over ES 5-minute data, 2010–2026, with multiple-comparison correction across the family of events.

EventWin ratenpVerdict
cib_long51.8%13,8671.6e-5Confirmed on ES
no_supply_long51.4%23,0773e-5Confirmed on ES
cib_short48.6%12,642Not confirmed
no_demand_short45.6%22,262Reversed
sot_short47.6%9,427Reversed

Two of the traditional short signals did not merely fail to work — they came out reliably below 50%, which on a symmetric test means the opposite side was winning. Read carefully: the inverse reading was not pre-registered, so we treat "no-demand is actually bullish information on ES" as a hypothesis produced by this data, not as a confirmed edge. It is in the API as a measured rate with that caveat attached, and nothing more.

A pattern worth noticing: every bearish event underperformed on an index that spent 2010–2026 mostly rising. Some of this is a genuine asymmetry in how index futures behave; some of it is a bull market. We cannot fully separate the two, and we are not going to pretend otherwise.

The one result that replicated: day type as a filter

The strongest finding on this site is not either read alone. It is the day-type read used as a gate on a Weis event — only taking the bullish counter-attack when the model reads the session as trending up.

MarketUnder TrendUpOpposite contextpStatus
ES · S&P 500 futures56.5%50.8%0.002Trained asset
NQ · Nasdaq futures56.1% n=1,53645.3% n=6892e-6Zero-shot
QQQ · Nasdaq ETF54.3% n=1,20044.3% n=5927e-5Zero-shot

Read the comparison column carefully: it is context versus context, not gated versus ungated. On ES, the 50.8% is the same event in the opposite day-type context — unconditionally, cib_long runs 51.8% on ES. On NQ and QQQ the comparison figure is the event in sessions the model read as TrendDown. The two contexts sit on opposite sides of the unconditional rate: the gate is sorting the same event into a stronger and a weaker population, not merely skimming the top off an average.

Zero-shot means no retraining, no refitting, no per-market threshold tuning: the ES-calibrated model and the ES-calibrated wave threshold pointed at a market they had never seen. That is the test that most published trading research quietly skips, and it is the reason we put more weight on a 54.3% here than on an 80% from a backtest fitted in place.

Where it fails

Gold, Bitcoin and Ethereum share an anti-signature. Run under the same frozen test protocol, the same events do not merely weaken on these markets, they invert — on BTC, zero of eight pre-registered signals confirmed, and no_supply runs the wrong way (measured 48.3%, n=8,899). Whatever the ES/NQ/QQQ signature is measuring, it is a property of index-type equity markets, not a law of markets.

Classical chart patterns did not survive. We ran Bulkowski-style detectors over 16 years of intraday index-futures data, producing more than 121,000 detections, then trained a model to predict each detection's outcome. AUC 0.54 — barely distinguishable from a coin flip. Pattern shape alone, in this data, carries almost no outcome information.

The Asian session is a pre-registered NO_GO. We tested whether the day-type gate carries into the Asian overnight session on 24-hour futures. It was registered in advance, it did not meet the threshold, and the verdict stands as NO_GO. The API defaults to the US day session for exactly this reason.

Max Pain and the options metrics

The permanently free Max Pain and GEX pages are computed, not scraped from anyone's dashboard — and the paid endpoints /v1/maxpain and /v1/gamma serve the same two figures. These options endpoints sit in the $149 full API product alongside Brooks and Weis; they are not standalone add-ons, and the $9.90 Brooks-only product does not unlock them. There is exactly one implementation of this arithmetic, a single module that the free pages, the API responses and our own research scripts all import. That is a mechanical guarantee, not a promise: with no second copy of the formula to drift, the number you can check for free on this site is the number a key holder's agent receives, and anything we publish about how these figures behave was measured on the code that produced yours. Here is precisely what each number is.

The two figures are not equally reliable, which is why each gets its own endpoint rather than sharing one response. Max pain is pure arithmetic on open interest: no pricing model, no volatility assumption, so anyone holding the same chain gets the same number. Gamma exposure is a Black-Scholes estimate — implied volatility is solved with r = 0 and q = 0 — and the solve can fail on thin or inconsistent chains. On the 2026-07-23 snapshot, when this site covered 25 tickers, all 25 produced a max pain figure while a zero gamma flip resolved on 22 of them. The coverage has grown since; in the 2026-09-03 files behind the free pages, max pain resolves on 43 of 43 tickers and a zero gamma flip on 37. The gap between those two counts is the point, and it moves night to night as chains change. Splitting the endpoints keeps a gamma degradation from ever dragging down a max pain answer, and stops the two numbers from reading as equally hard.

Why r = 0 and q = 0, stated properly. Setting both to zero is a choice, not an oversight, and the reason is that we would rather be visibly approximate than invisibly wrong. On options inside about 45 days, the discounting term moves the solved implied volatility by a small fraction of the width of the bid-ask spread the price came from, and gamma moves less than that. Putting a specific rate in its place would require picking one — which curve, which tenor, borrow costs, and a dividend forecast per ticker — and every one of those is a guess that would arrive dressed as precision. A zero is legible: anyone can reproduce our number exactly, and anyone who needs the discounted version knows precisely what to add. The same principle governs everything on this page. Where an input is genuinely unknown we would rather say so in the formula than smuggle an assumption into a decimal place.

Max pain

Max pain is the settlement price at which the largest amount of open option value expires worthless — equivalently, the price that minimises the total payout option sellers owe option buyers.

If the notation below is unfamiliar, start with the plain-English guide, What is max pain? — the formula is that guide said compactly, nothing more.

For every candidate settlement price K:

  payout(K) = 100 * [ SUM over call strikes X of  max(K - X, 0) * call_OI(X)
                    + SUM over put  strikes X of  max(X - K, 0) * put_OI(X) ]

  max_pain = the K that minimises payout(K)

100 is the contract multiplier. Computed per expiration, over the strikes
that actually have open interest.

What it is not: a forecast. It is an arithmetic property of today's open interest, it moves as open interest moves, and the well-known tendency of price to sit near it into expiration is a weak statistical regularity with a contested explanation — not something to trade off on its own.

Put/call ratio and the walls

The put/call ratio here is open-interest based: total put open interest divided by total call open interest for that expiration. The call wall is the strike carrying the most call open interest, the put wall the strike carrying the most put open interest. They are where positioning is concentrated, which is worth seeing, and nothing more than that.

Gamma exposure (GEX)

Gamma measures how fast an option's directional exposure changes as the underlying moves. Gamma exposure aggregates that across every open contract to estimate how much hedging flow a 1% move would mechanically generate.

If the Greek letters are new to you, read What is gamma exposure? and What is zero gamma? first — the formula reads much more easily on the way back.

Per contract i, at end of day, with spot S:

  1. solve Black-Scholes for the implied volatility that reproduces the
     contract's end-of-day price
  2. take gamma at that implied volatility
  3. GEX_i = gamma_i * OI_i * 100 * S^2 * 0.01   (positive for calls,
                                                  negative for puts)

Net GEX = sum of GEX_i. Contracts whose open interest and quote disagree,
or where the IV solve does not converge, are dropped rather than guessed.
Gamma flip = the price level where net GEX(x) crosses zero, searched on a
grid from 0.9*S to 1.1*S, taking the crossing nearest spot.

Sign convention: calls positive, puts negative, which is the common dealer-long-calls convention. Net GEX above zero is usually described as a dampening regime and below zero as an amplifying one. Treat that as a widely used heuristic, not as something we have independently verified — we publish the computation, not a claim about what it predicts.

Cross-check. The pipeline was validated against optioncharts.io on SPY and matched on 15 of 15 expirations before any of this went live. We compute gamma ourselves rather than reading an upstream field, so this check is what stands between the formula and a silent error.

What none of this tells you

It does not tell you what to buy, when to enter, how much to size, or where to stop. It has no view on your account, your horizon, or your risk tolerance, and it never will — that is the line between analytics and advice, and it is not a formality.

It also does not tell you that a 56% base rate is profitable. Costs, slippage, the distribution of winners against losers, and your own behaviour all sit between a base rate and a result. A real edge of a few percentage points is a starting point for research, not a conclusion.

If you find an error in anything on this page, email quantdata@quantdata.uk. Corrections get published.

Convinced by the method?

If the numbers above are the size you expected from an honest test, Brooks-only is $9.90 a month with no trial; every endpoint is $149 a month, with the first 3 days free.

Get free API key Buy full API access

Paid access starts with 3 days free after a card is added. The Max Pain and GEX pages stay free and need no key at all.

See pricing →

Questions first? quantdata@quantdata.uk — a person reads it.