# TTM Squeeze on XAUUSD, 1-hour bars - specification (RIP Backtest protocol v1.0 plus the 8 Oct 2026 rules)

Specification written and **frozen 2026-10-14 (approved by the owner the same day, draft 1 unchanged)**, before any Bollinger, Keltner, momentum value, signal or trade of this test was computed. Once frozen, any change of a rule is documented and treated as a separate test; bugs may be fixed.

## Why this test, and what was looked at before
- **Chosen by the owner** on 2026-10-14 ("TTM Squeeze aur h1") from a list of well-known strategies not yet on the site. The TTM Squeeze is John Carter's indicator (*Mastering the Trade*), built into thinkorswim and copied on TradingView (best known as LazyBear's "Squeeze Momentum Indicator"): the market "squeezes" when the Bollinger Bands move inside the Keltner Channels, and the trade is taken when the squeeze "fires" (the Bollinger Bands move back out), in the direction of a momentum histogram. Market and timeframe chosen by the owner: **gold (XAUUSD), 1-hour bars**.
- The definitions differ slightly between platforms; we use the common one below (the thinkorswim and LazyBear settings: 20 bars, Bollinger 2.0 standard deviations, Keltner 1.5 average true ranges, momentum as a 20-bar linear regression). Other settings will not be tried after seeing the result.
- Earlier tests on this gold file: daily and 1-hour golden crosses, EMA 9/20 (15-minute and 1-hour), the opening-range breakout, the Turtle rules, the noise area breakout and RSI 30/70. Bollinger Bands were tested before on ES (a reversal rule at the bands, 1-hour bars); **no squeeze rule and no Keltner Channel has been tested on the site**. No number of this test was looked at.

## Instrument and data
- **XAUUSD** on the IC Markets MetaTrader 4 demo server, a spot gold CFD in US dollars per ounce; 1-minute bid history from the first bar of 2004 to **2026-10-07 16:57 New York**, the part of the file read by the published gold studies (`gx_lib.loadGold({ fix: false })`).
- **Bars:** 1-hour bars on the New York clock, close time = bar time, built from the minutes that exist (`gh_lib.barsOf`), as in the RSI and EMA tests; incomplete bars are kept as they are, empty ones do not exist. Positions are held over the daily break, weekends and holidays.
- **Clock:** the file's time labels are an hour early in many weeks of 2004-2010 (clock audit). The bars are cut on whole hours, so a shifted label moves whole bars in time without changing their contents or order; nothing in the rules depends on the time of day. Stated in the article; no second run.
- **Holes (rule 3):** `data_holes_xau.json`; trades open across a suspect or unclear gap are counted, and every gate and verdict is recomputed without them; a changed verdict becomes Inconclusive.

## The indicator (all on 1-hour closes, highs and lows; 20 bars)
- **Bollinger Bands:** SMA(20) of the closes +/- 2.0 x the standard deviation of the last 20 closes (population formula, as on both platforms).
- **Keltner Channels:** SMA(20) of the closes +/- 1.5 x ATR(20), ATR(20) being the simple average of the last 20 true ranges.
- **Squeeze on** at bar k: the upper Bollinger band is below the upper Keltner line **and** the lower band is above the lower Keltner line. **The squeeze fires** at bar k when it was on at bar k - 1 and is not on at bar k.
- **Momentum (the histogram):** the value at bar k of the 20-bar least-squares line fitted to d = close - ((highest high of 20 bars + lowest low of 20 bars) / 2 + SMA(20) of the closes) / 2, taken at its last point (LazyBear's formula, `linreg(d, 20, 0)`).

## Rules
- **Entry:** when the squeeze fires at the close of bar k, **long** if the momentum is above zero, **short** if it is below (long-only variants ignore the shorts). Entry at the open of the first 1-minute bar after bar k. One position at a time; a signal while a position is open is ignored.
- **Exit A (Carter's momentum exit):** a long is closed after the **second consecutive bar of falling momentum** (momentum[k] < momentum[k-1] < momentum[k-2], the histogram "changing colour" for two bars), or when the momentum closes below zero, whichever comes first; shorts the mirror. Exit at the open of the next minute.
- **Exit B (hold the move):** a long is closed only when the momentum closes below zero (the histogram crosses to the other side); shorts the mirror. Exit at the open of the next minute.
- **No stop, no target** in either exit, as in the usual description of the squeeze; the article reports the worst open loss of every trade.
- **R** (the unit of the results): 1.5 x ATR(14) of the 1-hour bars at the signal bar (`E.indicators`, as in the gold RSI and EMA tests), in dollars per ounce; a normalisation unit, not a maximum loss.
- **Four variants:** **SQ-LS-A, SQ-L-A, SQ-LS-B, SQ-L-B** (long and short / long only x exit A / exit B).

## Costs
- **Baseline:** $0.30 per ounce per round trip, as in every gold test on the site; slippage zero, which is optimistic and stated.
- **Scenario A:** 3% a year of the entry price per calendar day held, longs and shorts alike. **Scenario B:** today's IC Markets XAUUSD swap as recorded on 2026-10-12 (long -57.03, short +39.767 points per lot per night; Wednesday counting three), not a historical swap. The verdict is that of the baseline.

## Periods, gates, control
- **Periods (by entry date):** development 2004 .. 2012; validation 2013 .. 2019; holdout 2020 .. 2026-10-07 (**already used** by the earlier gold tests).
- **Six gates per variant:** validation profit factor >= 1.2; at least 50 trades in each period; development **t >= 2.0** (four variants of a strategy not tested before on the site); above the 95th percentile of 500 runs of the matched control; positive without the 10 best trades; holdout net positive (flagged used). Fewer than 30 trades: Inconclusive.
- **Matched control (moved entries):** every real entry moved, all together, by one random circular offset of at least 5% of the days, to the same time of day on the new day, same direction; from there managed by the same exit rule (A or B), costs and one-position rule. 500 runs, seeds 1000 + run. Statistic: the average net R per trade.

## Engine and self-test (before the run)
A new engine (`sq_lib.js`) and a self-test that must pass before any result is printed:
1. Hand-worked cases: Bollinger and Keltner values; squeeze on, off and firing; the momentum regression against a hand calculation; long and short entries by the momentum sign; long only ignoring shorts; exit A on two falling bars and on the zero cross; exit B on the zero cross only; entries and exits at the next minute; one position at a time; costs, R and the financing scenarios.
2. The indicator against a naive recomputation on the real data.
3. An **independent re-implementation** matched trade by trade for all four variants on the real data.
4. The control at offset 0 reproduces the real trades.

## Before the article
Results go to the owner first: all four variants, every gate, long and short separately, by year, the worst open loss per trade, how long squeezes and trades last, the cost per trade against the gross, both scenarios, the hole check. One article, published only with the owner's agreement.

## Reading the result
"Buried" or "Inconclusive" mean a statistically convincing edge was not demonstrated; neither is proof that none exists. One market, one timeframe, one broker's demo history, the standard settings only.
