A QQQ trading strategy, backtested for eight years and run live in public

This is a mechanical day-trading rule for QQQ — average hold 2.3 hours, some positions carry overnight. /v1/weis/QQQ — the same endpoint every API key gets — supplies the trigger; a day-type model read supplies the gate. That read is the day_type block of /v1/brooks, served for the day session, and the study behind it is published on the methodology page. Below are the full backtest results: what that rule did to $10,000 across eight years of QQQ five-minute data, every trade and every skipped trigger. Further down, the same rule runs live in a simulated brokerage account, published nightly. Historical statistics, not investment advice.

$10,000 became
$16,130
+61.3% · May 2018 – Jul 2026
Worst drawdown
-12.4%
buy & hold QQQ: -35.6%
Trades
784
436 wins · 348 losses
Win rate
55.6%
±3×ATR symmetric brackets
Time in market
13.4%
avg hold ≈ 2.3 hours
$9k $10k $11k $12k $13k $14k $15k $16k $17k 2018 2019 2020 2021 2022 2023 2024 2025 2026 $10,000 $16,130 · +61.3% worst drawdown -12.4%

Equity curve of the backtest: full-equity whole-share positions, compounding, no commissions or slippage modeled — treat the level as an upper bound and the shape as the signal. The live executor trades a fixed 10 shares instead; both sizings are stated wherever numbers appear.

Text version — equity at each year end
PointEquity
start (May 2018)$10,000
end of 2018 $9,643
end of 2019 $10,279
end of 2020 $11,029
end of 2021 $11,020
end of 2022 $13,140
end of 2023 $14,319
end of 2024 $14,427
end of 2025 $16,204
latest (Jul 2026) $16,130

Backtest results on the chart — the last 20 sessions

2026-06-18: end-of-session read TrendUp — Range 0.038, Reversal 0.052, TrendDown 0.019, TrendUp 0.83, TrendingRange 0.06 TRENDUP 2026-06-22: end-of-session read Range — Range 0.33, Reversal 0.273, TrendDown 0.221, TrendUp 0.017, TrendingRange 0.159 RANGE 2026-06-23: end-of-session read Reversal — Range 0.263, Reversal 0.4, TrendDown 0.09, TrendUp 0.059, TrendingRange 0.188 REVERSAL 2026-06-24: end-of-session read Reversal — Range 0.161, Reversal 0.382, TrendDown 0.311, TrendUp 0.02, TrendingRange 0.126 REVERSAL 2026-06-25: end-of-session read Range — Range 0.441, Reversal 0.139, TrendDown 0.274, TrendUp 0.029, TrendingRange 0.117 RANGE 2026-06-26: end-of-session read TrendUp — Range 0.23, Reversal 0.138, TrendDown 0.022, TrendUp 0.375, TrendingRange 0.235 TRENDUP 2026-06-29: end-of-session read TrendUp — Range 0.027, Reversal 0.067, TrendDown 0.015, TrendUp 0.842, TrendingRange 0.048 TRENDUP 2026-06-30: end-of-session read TrendUp — Range 0.004, Reversal 0.019, TrendDown 0.003, TrendUp 0.954, TrendingRange 0.02 TRENDUP 2026-07-01: end-of-session read Range — Range 0.432, Reversal 0.323, TrendDown 0.021, TrendUp 0.055, TrendingRange 0.168 RANGE 2026-07-02: end-of-session read TrendDown — Range 0.006, Reversal 0.127, TrendDown 0.841, TrendUp 0.004, TrendingRange 0.022 TRENDDOWN 2026-07-06: end-of-session read TrendUp — Range 0.241, Reversal 0.13, TrendDown 0.038, TrendUp 0.424, TrendingRange 0.168 TRENDUP 2026-07-07: end-of-session read Reversal — Range 0.289, Reversal 0.394, TrendDown 0.145, TrendUp 0.03, TrendingRange 0.142 REVERSAL 2026-07-08: end-of-session read Range — Range 0.541, Reversal 0.141, TrendDown 0.031, TrendUp 0.076, TrendingRange 0.212 RANGE 2026-07-09: end-of-session read TrendUp — Range 0.105, Reversal 0.103, TrendDown 0.01, TrendUp 0.678, TrendingRange 0.105 TRENDUP 2026-07-10: end-of-session read Range — Range 0.389, Reversal 0.143, TrendDown 0.01, TrendUp 0.231, TrendingRange 0.227 RANGE 2026-07-13: end-of-session read Reversal — Range 0.215, Reversal 0.433, TrendDown 0.163, TrendUp 0.014, TrendingRange 0.175 REVERSAL 2026-07-14: end-of-session read TrendUp — Range 0.159, Reversal 0.09, TrendDown 0.029, TrendUp 0.591, TrendingRange 0.131 TRENDUP 2026-07-15: end-of-session read TrendDown — Range 0.025, Reversal 0.119, TrendDown 0.805, TrendUp 0.007, TrendingRange 0.045 TRENDDOWN 2026-07-16: end-of-session read TrendDown — Range 0.148, Reversal 0.308, TrendDown 0.35, TrendUp 0.016, TrendingRange 0.177 TRENDDOWN 2026-07-17: end-of-session read TrendUp — Range 0.203, Reversal 0.206, TrendDown 0.025, TrendUp 0.324, TrendingRange 0.242 TRENDUP 685 690 695 700 705 710 715 720 725 730 735 740 745 06/18 06/23 06/25 06/29 07/01 07/06 07/08 07/10 07/14 07/16 Entry 2026-06-18 14:45 ET @ 739.77 → exit 2026-06-22 09:30 ET @ 742.92 (target). 21 shares, P&L +$66. Entry 2026-06-18 14:45 ET @ 739.77 → exit 2026-06-22 09:30 ET @ 742.92 (target). 21 shares, P&L +$66. +$66 Entry 2026-06-29 12:40 ET @ 720.51 → exit 2026-06-30 09:30 ET @ 726.12 (target). 22 shares, P&L +$123. Entry 2026-06-29 12:40 ET @ 720.51 → exit 2026-06-30 09:30 ET @ 726.12 (target). 22 shares, P&L +$123. +$123 Entry 2026-06-30 10:10 ET @ 731.60 → exit 2026-06-30 11:55 ET @ 734.55 (target). 22 shares, P&L +$65. Entry 2026-06-30 10:10 ET @ 731.60 → exit 2026-06-30 11:55 ET @ 734.55 (target). 22 shares, P&L +$65. +$65 Entry 2026-07-01 10:05 ET @ 730.58 → exit 2026-07-01 10:45 ET @ 728.02 (stop). 22 shares, P&L −$56. Entry 2026-07-01 10:05 ET @ 730.58 → exit 2026-07-01 10:45 ET @ 728.02 (stop). 22 shares, P&L −$56. −$56 Entry 2026-07-02 10:10 ET @ 728.90 → exit 2026-07-02 10:20 ET @ 725.68 (stop). 22 shares, P&L −$71. Entry 2026-07-02 10:10 ET @ 728.90 → exit 2026-07-02 10:20 ET @ 725.68 (stop). 22 shares, P&L −$71. −$71 Entry 2026-07-14 13:50 ET @ 721.46 → exit 2026-07-15 10:20 ET @ 717.41 (stop). 22 shares, P&L −$89. Entry 2026-07-14 13:50 ET @ 721.46 → exit 2026-07-15 10:20 ET @ 717.41 (stop). 22 shares, P&L −$89. −$89 Entry 2026-07-17 10:35 ET @ 698.52 → exit 2026-07-17 11:00 ET @ 693.88 (stop). 23 shares, P&L −$107. Entry 2026-07-17 10:35 ET @ 698.52 → exit 2026-07-17 11:00 ET @ 693.88 (stop). 23 shares, P&L −$107. −$107

Blue = the trade won, orange = it lost; triangle = entry, circle = exit; the label is that trade's P&L on the $10,000 account. Chips along the top are the day-type model's end-of-session reads; the gate acts on the read at the trigger moment, which can differ — both are shown rather than hiding the disagreement. A losing stretch in this window stays on the chart because it happened: this is what a 55.6% win rate feels like at street level — streaks both ways, decided by the bracket.

Text version — all 7 trades in this window
Entry (ET)EntryExit (ET) ExitViaP&LEquity after
2026-06-18 14:45 739.77 2026-06-22 09:30 742.92 target +$66.06 $16,265
2026-06-29 12:40 720.51 2026-06-30 09:30 726.12 target +$123.44 $16,388
2026-06-30 10:10 731.60 2026-06-30 11:55 734.55 target +$64.99 $16,453
2026-07-01 10:05 730.58 2026-07-01 10:45 728.02 stop −$56.34 $16,397
2026-07-02 10:10 728.90 2026-07-02 10:20 725.68 stop −$70.86 $16,326
2026-07-14 13:50 721.46 2026-07-15 10:20 717.41 stop −$89.01 $16,237
2026-07-17 10:35 698.52 2026-07-17 11:00 693.88 stop −$106.70 $16,130

How the strategy works

The rule is fixed and mechanical. When /v1/weis reports a fresh cib_long event — a high-volume down-wave that fails to break down, followed by a low-volume pullback — and the day-type model (the day_type block of /v1/brooks) reads TrendUp at that same moment, the rule buys at the event price and brackets at ±3×ATR(60). The first level touched closes the trade. One position at a time. Long only: the short-side events measured 45.6% and 47.6% on ES against a 49.3% baseline, so the rule deliberately never shorts.

What the gate is worth

The trigger alone is a coin flip with a lean. The day-type gate is what turns it into the curve above — same trigger, same brackets, same eight years:

Gated (TrendUp only)Ungated (every trigger)
Final equity $16,130 · +61.3% $13,636 · +36.4%
Trades taken7841483
Win rate55.6% 52.8%
Worst drawdown-12.4% -21.4%

The gate declined 769 of 1598 triggers — 48.1% of the time it said no. Half the trades, +61.3% against +36.4%. A gate that never says no is not a gate.

The pre-registered evidence behind the rule

Two protocol differences to keep in view. First, this page's replay adds portfolio mechanics (one position at a time, compounding, gap fills), so its 55.6% is consistent with but not identical to the event-level numbers. Second, the pre-registered tests built their waves on all-session bars (pre-market and after-hours included), while /v1/weis — and this replay, which matches it — builds waves on regular-hours bars only. The event-level win rates above belong to the all-session construction; the regular-hours variant's evidence is this replay, not the pre-registered label. Full protocols on the methodology page.

Read this before believing the chart

Live paper trading — the same rule at a broker

Since Jul 28, 2026 an executor holding a simulated (paper) brokerage account runs this rule live, sized at a fixed 10 shares. It polls once a minute, accepts only events fresher than 15 minutes, and logs every decision — entries, exits, and triggers the gate declined. This section republishes that log nightly.

One configuration gap is measured and worth stating: the live executor computes its ATR from all-session bars (pre-market and after-hours included), so its brackets run about 27.4% tighter than this backtest's — measured at all 784 of the replay's entries. Replayed with those tighter brackets, the same signals returned +18.1% at a 54% win rate. Both configurations are published here until the executor and the backtest are aligned.

It went live mid-session at 2026-07-28 14:00 ET (its own log's first entry). Events older than 15 minutes are ignored, so a mid-session start begins by watching, not chasing.

Opened (ET)EntryStop TargetExitSignal source
2026-08-04 10:00:00-04:00 714.18 712.12 716.24 target@716.24 · 2026-08-04 10:40:16-0400 quantdata
2026-08-04 14:05:00-04:00 722.7 720.19 725.21 target@725.21 · 2026-08-04 15:20:56-0400 quantdata
2026-08-26 09:49:17-04:00 7694.75 7683.46 7706.04 stop@7683.46 · 2026-08-26 10:40:17-0400 quantdata
2026-08-27 09:46:09-04:00 7728 7715.95 7740.05 stop@7715.95 · 2026-08-27 10:05:34-0400 quantdata
2026-08-27 09:56:37-04:00 7718 7704.5 7731.5 target@7731.5 · 2026-08-27 10:50:01-0400 quantdata
2026-08-27 12:00:00-04:00 7741 7723.43 7758.57 stop@7723.43 · 2026-08-27 15:10:11-0400 quantdata
2026-08-28 11:08:21-04:00 7775.25 7760.27 7790.23 stop@7760.27 · 2026-08-28 11:55:26-0400 quantdata
2026-09-01 10:38:05-04:00 7670.75 7657.62 7683.88 stop@7657.62 · 2026-09-01 11:15:04-0400 quantdata

Triggers the executor saw this period, including the ones the gate declined: 2026-08-04 10:00:00-04:00 (SIGNAL); 2026-08-04 14:05:00-04:00 (SIGNAL); 2026-08-05 09:55:00-04:00 (skip(gate)); 2026-08-07 11:50:00-04:00 (skip(gate)); 2026-08-07 15:35:00-04:00 (skip(gate)); 2026-08-11 15:50:00-04:00 (skip(gate)); 2026-08-18 12:21:09-04:00 (skip(gate)); 2026-08-18 12:20:00-04:00 (skip(gate)); 2026-08-19 09:37:23-04:00 (skip(gate)); 2026-08-19 09:43:29-04:00 (skip(gate)); 2026-08-19 09:40:00-04:00 (skip(gate)); 2026-08-21 11:20:00-04:00 (skip(gate)); 2026-08-21 11:25:00-04:00 (skip(gate)); 2026-08-24 11:13:26-04:00 (skip(gate)); 2026-08-26 09:49:17-04:00 (SIGNAL); 2026-08-26 09:50:00-04:00 (skip(gate)); 2026-08-26 11:15:18-04:00 (skip(gate)); 2026-08-26 11:20:00-04:00 (skip(gate)); 2026-08-26 11:25:00-04:00 (skip(gate)); 2026-08-26 11:50:11-04:00 (skip(gate)); 2026-08-26 11:51:14-04:00 (skip(gate)); 2026-08-26 13:50:00-04:00 (skip(gate)); 2026-08-26 15:10:00-04:00 (skip(gate)); 2026-08-26 15:15:00-04:00 (skip(gate)); 2026-08-27 09:46:09-04:00 (SIGNAL); 2026-08-27 09:47:15-04:00 (SIGNAL); 2026-08-27 09:56:37-04:00 (SIGNAL); 2026-08-27 10:35:00-04:00 (SIGNAL); 2026-08-27 12:00:00-04:00 (SIGNAL); 2026-08-27 13:30:00-04:00 (SIGNAL); 2026-08-28 09:50:51-04:00 (skip(gate)); 2026-08-28 10:27:01-04:00 (skip(gate)); 2026-08-28 10:45:37-04:00 (skip(gate)); 2026-08-28 11:08:21-04:00 (SIGNAL); 2026-08-31 14:20:00-04:00 (skip(gate)); 2026-09-01 10:11:14-04:00 (skip(gate)); 2026-09-01 10:38:05-04:00 (SIGNAL); 2026-09-01 10:51:33-04:00 (SIGNAL).

Journal data as of 2026-09-02 (UTC), rebuilt nightly from the executor's own log. Prices in the table are signal-time reference prices; the simulated account's actual fills differ slightly.

Questions people actually search for

Is algorithmic trading profitable?

Sometimes, for some rules, in some periods — and the only honest way to answer is to show a ledger. This one mechanical rule turned $10,000 into $16,130 (+61.3%) over eight years of QQQ data, before commissions and slippage, while being in the market 13.4% of the time. Over the same period simply holding QQQ returned +327.4%. Both numbers are on this page because both are true; a page that shows you only one of them is selling something.

Does this strategy beat buy and hold?

No. It made a fraction of buy-and-hold's return (+61.3% vs +327.4%) with roughly a third of its worst drawdown (-12.4% vs -35.6%) and 13.4% of its market exposure. What it demonstrates is that the two endpoints carry measurable signal — not that a $10,000 account should prefer it to an index fund. We are not in the business of telling you what to prefer.

Do trading bots work?

The executor here is a few hundred lines of Python running a fixed rule — no discretion, no machine learning at order time. Whether it "works" is exactly what the nightly journal on this page measures: the backtest says the rule had an edge historically; the live paper account is where that claim meets fills, feed gaps and mid-session restarts. Judge it by the log, not by this paragraph.

What is paper trading?

Trading in a simulated brokerage account: real market data and real order mechanics, no real money. We use it because it produces an auditable record without risking capital — with one honest caveat: simulated fills are friendlier than real ones, so treat every P&L figure here as an upper bound.

How was this backtest done?

Eight years of QQQ one-minute data resampled to five-minute bars, events computed by the same code that serves /v1/weis, the day-type read taken at each trigger moment from the same model /v1/brooks serves in its day_type block, ±3×ATR(60) brackets, one position at a time, full-equity sizing with compounding, no cost model. The full protocol, and the pre-registered event-level tests it builds on, is on the methodology page.

Can my AI agent use the same endpoints?

Both halves, yes. The executor consumes GET /v1/weis/QQQ with an X-API-Key header, exactly as any agent would, and the gate half reads the day_type block of GET /v1/brooks/QQQ — the same model this backtest used, served for the day session. The gate itself is our rule, not a field the API returns; what your agent does with the descriptive statistics it gets back is its author’s decision, not our recommendation.

Is this investment advice?

No. Everything on this page is a historical measurement of one mechanical rule — what it did in a backtest and what a simulated account has logged since. It is educational and descriptive: not a recommendation to buy or sell anything, and nothing here adjusts to your situation.

Run the same trigger endpoint

The rule's trigger comes from GET /v1/weis/QQQ and its gate from the day_type block of GET /v1/brooks/QQQ — the same commercial JSON endpoints your script or AI agent can call. Start with a free key by email; no account, card or GUI is required.

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.

Read the API reference →

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

Educational analytics, not investment advice. The backtest is a historical replay with no cost model; the live account is simulated and holds no real money. Measured frequencies from one period are not predictions about any future period. Backtest generated 2026-07-29 by journal/backtest_qqq.py from brooks/data/qqq_1m.parquet; method details on the methodology page.