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.
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
| Point | Equity |
|---|---|
| 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
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) | Entry | Exit (ET) | Exit | Via | P&L | Equity 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 taken | 784 | 1483 |
| Win rate | 55.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
cib_longmeasured 51.8% on ES five-minute data, 2010–2026 (n=13,867, p=1.6e-5, pre-registered, CONFIRMED).- Gated by a
TrendUpread it measured 56.5% on ES, against 50.8% in the opposite context (p=0.002). - The day-type model was trained on ES only. Zero-shot on QQQ the gated trigger measured 54.3% under a TrendUp read vs 44.3% under TrendDown (p=7e-5); on NQ, 56.1% vs 45.3% (p=2e-6).
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
- Buy and hold beat it on raw return. QQQ itself returned +327.4% over the same period — with a -35.6% drawdown and 100% exposure, against the rule's -12.4% and 13.4%. That return was available from simply holding QQQ; this rule is not a route to it. This page demonstrates that the endpoints carry measurable signal — not that they beat holding an index fund.
- No costs are modeled. No commissions, no slippage, fills at the event-bar close. The live paper account below exists precisely to measure that gap.
- One backtest, one asset, one period. May 2018 – Jul 2026 contains one regime story. The pre-registered event-level tests (16 years, ES) are the stronger evidence; this replay is the portfolio illustration of them.
- The API also reports short-side events. They tested contrarian (45.6% / 47.6%) and are deliberately not traded — the endpoints describe the tape; the rule chooses what to act on.
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) | Entry | Stop | Target | Exit | Signal 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.
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.