box_signals.py is the whole signal engine in one file, every disputed rule exposed as a flag; it reproduces the published entry list bar for bar. run_variants.py generates the count table in section 8, build_stats.py everything else. reference/ has all 1,374 trades, the 10-variant signal counts, and the base signal list with the 21 EMA feature recomputed. Option quotes are licensed ThetaData NBBO minute data and are not included; 5-minute bars are not either. The engine runs on any 5-minute OHLCV frame.
Bars. 5-minute bars from 04:00 to 19:55 ET, resampled to 60 minutes on the on-the-hour grid, extended hours included. The oscillator is computed on that series. Regular-hours-only bars are a different series and give a different answer; section 8 measures how different.
Compression (the grey candle). Saty Phase Oscillator compression: grey when the 21-period Bollinger band on the price side sits inside the 2x ATR14 Keltner band, except when the gap between them is not shrinking and price is already inside the 1.854x ATR expansion zone. ATR is Wilder (RMA). The stdev is pandas' sample stdev; Pine's ta.stdev is the population one and is grey slightly more often.
The box. The high and low of the first 5 grey candles of a compression run, or fewer if the run ends sooner. After the 5th grey candle the box is frozen. The run stays live for 10 calendar days.
The entry, as the rules say and the live bot codes it. The first candle that comes out of compression must close above the box high. That is the spec on this page and the 1,374-trade cohort. Long only.
The entry, as the backtest actually coded it. The published run armed when the bar's high took out the box and then set direction from the close against the box midpoint. That is looser: 574 of the 3,833 long in-window signals poke above the box and close back inside it. Both readings are in section 3.
One shot per compression run. Only the first candle out of compression is tested. If it does not take out the box, that run is over and no later candle re-arms it. Reading it the other way roughly doubles the count (section 8).
Window. Only signals whose hourly close lands 10:00-15:00 ET, Monday to Friday.
Gates. Stock at or above its daily 21 EMA as of the prior completed RTH close. Two-sided option quote no wider than 5% of mid. No volume gate -- the floor was dropped on 2026-07-13 and the live bot does not use one.
Position. One call, strike nearest spot + 0.75 x prior daily ATR14, nearest expiry in the 21-37 day window. 4% of the account in premium for the curves here.
Exits, keyed to the stock. 5-minute close below the box low, sell. Once the stock has run +1.0 x daily ATR in favour, sell on any 5-minute close at or below entry + 25% of the peak gain. Time cap 10 trading days. Median hold 5 calendar days, 90th percentile 14; the cap bound on 265 of 1,374 trades.
| Stage | n | of all | |
|---|---|---|---|
| Compression episodes that produced a box break (both sides, all hours) | 14,503 | 100% | |
| Hourly close lands 10:00-15:00 ET, Mon-Fri | 7,231 | 50% | |
| Long side (breaks below the box are not shorted) | 3,833 | 26% | |
| The close itself is above the box high | 3,259 | 22% | |
| Stock above its daily 21 EMA as of the prior close | 2,457 | 17% | |
| A two-sided quote exists on the ~1-strike-OTM 28-DTE call | 1,721 | 12% | |
| That quote is no wider than 5% of mid -> the live spec | 1,374 | 9% |
| Cohort | Trades | Mean/trade | Median | Win | PF | t | Growth | Max DD |
|---|---|---|---|---|---|---|---|---|
| the old headline | 1,031 | +11.85% | -6.7% | 41.3% | 1.62 | 3.56 | 66.05x | -43% |
| Volume floor still on, the 21 EMA feature missing on 559 signals, no spread cap applied. | ||||||||
| no 21 EMA gate | 1,767 | +5.74% | -5.2% | 39.3% | 1.34 | 2.25 | 25.67x | -66% |
| Spread cap on, volume floor off, trend gate off. | ||||||||
| break on the bar high | 1,593 | +5.43% | -5.1% | 38.2% | 1.33 | 1.94 | 14.87x | -68% |
| 21 EMA + spread cap, armed the way the backtest actually coded it. | ||||||||
| close above the box | 1,374 | +5.95% | -4.6% | 40.0% | 1.36 | 2.19 | 13.76x | -53% |
| The spec on this page: the rules as written and as the live bot codes them. | ||||||||
| close above the box + volume floor | 711 | +13.50% | -4.1% | 44.7% | 1.77 | 3.51 | 29.78x | -23% |
| Shown because this gate is what flattered the old headline. | ||||||||
f_hourrel >= 1, a floor on the breakout hour's volume against its own 20-session same-clock-hour median. The rules text dropped that gate in July and the live bot never applies it. (2) The 21 EMA distance was inherited from an earlier cohort that only covered 3,087 of the 3,833 long signals, so d21dist >= 0 silently threw away 559 signals whose feature was simply absent. It is recomputed here for all of them. (3) The stated 5%-of-mid spread cap was never applied to the published cohort at all; it is applied here.| Cohort | Trades | Mean/trade | Median | Win | PF | t | Growth | Max DD |
|---|---|---|---|---|---|---|---|---|
| 2019 -> Jul 2026 (full) | 1,374 | +5.95% | -4.6% | 40.0% | 1.36 | 2.19 | 13.76x | -53% |
| 2019 - 2022 | 624 | +3.83% | -3.4% | 42.8% | 1.30 | 1.04 | 2.18x | -44% |
| 2023 -> Jul 2026 | 750 | +7.72% | -8.6% | 37.6% | 1.39 | 1.95 | 6.33x | -49% |
| 2025 -> | 234 | +14.10% | -13.5% | 36.3% | 1.65 | 1.45 | 3.03x | -29% |
| 2026 YTD | 29 | +11.84% | +0.4% | 51.7% | 1.54 | 0.84 | 1.13x | -13% |
| Year | n | Mean/trade | Win | PF | Growth | Max DD | Top 5 |
|---|---|---|---|---|---|---|---|
| 2019 | 167 | +4.12% | 42% | 1.39 | 1.25x | -18% | 211% |
| 2020 | 140 | -0.48% | 46% | 0.95 | 0.96x | -22% | -- |
| 2021 | 189 | +14.83% | 47% | 2.33 | 2.84x | -12% | 56% |
| 2022 | 128 | -8.08% | 34% | 0.60 | 0.64x | -39% | -- |
| 2023 | 282 | +9.76% | 38% | 1.54 | 2.57x | -47% | 77% |
| 2024 | 234 | -1.12% | 38% | 0.95 | 0.81x | -49% | -- |
| 2025 | 205 | +14.42% | 34% | 1.67 | 2.69x | -29% | 84% |
| 2026 | 29 | +11.84% | 52% | 1.54 | 1.13x | -13% | 242% |
| Ticker | n | Mean/trade | Win | PF | Best |
|---|---|---|---|---|---|
| NVDA | 106 | +0.64% | 51% | 1.10 | 176% |
| NFLX | 104 | +1.33% | 43% | 1.29 | 150% |
| AMD | 102 | +19.91% | 41% | 2.04 | 429% |
| GOOGL | 99 | -2.53% | 42% | 0.84 | 342% |
| AAPL | 93 | +3.07% | 46% | 1.18 | 333% |
| AMZN | 89 | -0.27% | 38% | 0.98 | 486% |
| MSFT | 85 | +16.58% | 36% | 1.84 | 407% |
| AVGO | 84 | -2.22% | 34% | 0.66 | 175% |
| TSLA | 79 | +9.03% | 46% | 1.72 | 575% |
| PLTR | 68 | +8.95% | 44% | 1.37 | 726% |
| INTC | 65 | +9.41% | 38% | 1.41 | 537% |
| MU | 64 | +19.26% | 31% | 1.83 | 623% |
| JPM | 60 | -9.26% | 30% | 0.64 | 241% |
| UBER | 54 | -1.81% | 22% | 0.94 | 381% |
| BAC | 52 | +7.53% | 42% | 1.38 | 239% |
| DIS | 51 | +42.82% | 43% | 3.36 | 670% |
| META | 46 | -2.58% | 48% | 0.88 | 176% |
| SMCI | 26 | -6.65% | 35% | 0.67 | 116% |
| HOOD | 25 | -6.36% | 24% | 0.77 | 366% |
| COIN | 22 | +3.28% | 32% | 1.15 | 309% |
| Reading | Box breaks | In window | Long | Above 21 EMA | Trades |
|---|---|---|---|---|---|
| break on the bar high (what the backtest did) | 14,503 | 7,231 | 3,833 | 2,816 | 1,593 |
| regular-hours bars, grid still on the hour | 6,860 | 6,263 | 3,286 | 2,472 | 1,382 est |
| close must clear the box high (rules + live bot) | 12,142 | 6,074 | 3,259 | 2,457 | 1,374 |
| the box must complete all 5 grey bars | 8,703 | 3,809 | 2,012 | 1,566 | 876 est |
| any later bar out of compression may trigger | 21,754 | 10,027 | 5,273 | 3,894 | 2,178 est |
| population stdev in the oscillator (Pine ta.stdev) | 14,731 | 7,327 | 3,900 | 2,863 | 1,601 est |
| 30-minute bars instead of hourly | 30,030 | 16,653 | 8,312 | 5,707 | 3,191 est |
| regular-hours bars, grid anchored at 09:30 | 6,316 | 5,777 | 3,048 | 2,295 | 1,283 est |
| regular hours + strict close + 5 grey bars | 3,672 | 3,309 | 1,739 | 1,395 | 780 est |
| 09:30 grid + strict close + 5 grey bars | 3,357 | 3,047 | 1,586 | 1,269 | 710 est |
| Cohort | Trades | Mean/trade | Median | Win | PF | t | Growth | Max DD |
|---|---|---|---|---|---|---|---|---|
| no gates at all | 2,265 | +5.48% | -7.1% | 37.4% | 1.29 | 1.64 | 41.16x | -76% |
| 21 EMA only | 1,721 | +5.34% | -6.5% | 37.9% | 1.29 | 1.92 | 15.95x | -63% |
| spread <= 5% only | 1,767 | +5.74% | -5.2% | 39.3% | 1.34 | 2.25 | 25.67x | -66% |
| 21 EMA + spread (the live spec) | 1,374 | +5.95% | -4.6% | 40.0% | 1.36 | 2.19 | 13.76x | -53% |
| live spec + the dropped volume floor | 711 | +13.50% | -4.1% | 44.7% | 1.77 | 3.51 | 29.78x | -23% |
| Gate | Fires on | Real | Random median | Random 5-95% | Verdict |
|---|---|---|---|---|---|
| 21 EMA | 76% | +5.34% | +5.66% | +3.06% .. +6.56% | inside band, free parameter |
| spread <= 5% | 78% | +5.74% | +5.51% | +3.02% .. +6.52% | inside band, free parameter |
| volume floor (dropped) | 52% | +13.50% | +5.57% | +2.94% .. +8.08% | outside band, real work |
| Window | Half mean | Half PF | Half growth | Full mean | Full PF | Full growth | Give-up |
|---|---|---|---|---|---|---|---|
| 2019 -> Jul 2026 (full) | +5.95% | 1.36 | 13.76x | +4.51% | 1.26 | 6.33x | -24% |
| 2019 - 2022 | +3.83% | 1.30 | 2.18x | +2.44% | 1.18 | 1.54x | -36% |
| 2023 -> Jul 2026 | +7.72% | 1.39 | 6.33x | +6.24% | 1.30 | 4.10x | -19% |
| 2025 -> | +14.10% | 1.65 | 3.03x | +12.23% | 1.55 | 2.56x | -13% |
| 2026 YTD | +11.84% | 1.54 | 1.13x | +9.17% | 1.40 | 1.10x | -23% |
| Cohort | Trades | Mean/trade | Median | Win | PF | t | Growth | Max DD |
|---|---|---|---|---|---|---|---|---|
| every signal | 1,374 | +5.95% | -4.6% | 40.0% | 1.36 | 2.19 | 13.76x | -53% |
| one open per name at a time | 1,087 | +7.87% | -4.6% | 40.7% | 1.47 | 2.76 | 17.50x | -42% |
Strike and expiry were chosen on the whole record. The exit rule was picked on 2019-2022 and run untouched on 2023-2026, which is a real out-of-sample test. The ~1-strike-OTM 28-DTE cell was not; treat the exact per-trade figure as flattered.
The curve compounds trades single-file. In reality several positions are open at once, so the path is a simplification in both directions. Section 13 is the nearest honest correction.
Fills are quote-based, not filled orders. Entry and exit prices come from ThetaData NBBO minute quotes at the actual timestamps, marked half-spread. No partials, no queue, no assignment, no dividends. Calls are always sold, never exercised.
Exits are evaluated on 5-minute closes of the underlying, and the live bot only looks once per run, so real exits lag the modelled ones. That lag is logged live but is not in these numbers.
Long-only megacap momentum. 2020 was flat and 2022 was the worst stretch. Expect it to bleed in bear markets, and expect the typical trade to lose money: the median trade here is -4.6%.
No live track record. The forward paper record accrues at /bilbo-paper.html. It is being generated by the no-volume-gate version, which is the 1,374-trade spec on this page, not the old headline.