# Double top and double bottom on XAUUSD, 1-hour bars, reviewed version - specification (RIP Backtest protocol v1.0 plus the 8 Oct 2026 rules)

Specification written and **frozen 2026-11-11** (the owner: "aplică întâi recenzia, apoi îngheață și rulează"), applying the outside review of the first version that the owner pasted. No result of this version has been 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-11-11: the double top pattern on 1-hour bars, on **gold (XAUUSD)**, with the entry, stop and target taken from the commonly published rules (the sources and the owner's words are in `dtop_spec.md`).
- **This is the second version of the test, and the first one has already been run.** The first version (`dtop_spec.md`, frozen 2026-11-11 with the owner's "Da, îngheață și rulează") was run the same day, before the review reached this work: four variants, all buried (151, 75, 60 and 31 trades; control percentiles 49.6 to 80.4; one of them Inconclusive by rule 3). The owner then pasted an outside review of that draft and asked for it to be applied, frozen and run.
  - The changes below come from that review, which was written about the draft before any result existed; none was chosen after seeing the first results.
  - The review also asked that the threshold multiplier, k and the volatility unit not be changed after seeing results. They are the review's, fixed here.
  - Both versions are reported. They count as eight variants of one idea, together with the four of the head-and-shoulders test, so the development bar stays **t >= 2.5**.
- **What changed from the first version:**
  1. **The tolerance for equal tops** is now measured with ATR(14) of the 1-hour bars in dollars per ounce, read from the bars before the confirmation.
  2. **The prior trend** is now the 50-bar EMA of 1-hour closes (it was a higher high and a higher low of the zigzag).
  3. **The stop** has a fixed buffer of one tick ($0.01) beyond the second top (it had none).
  4. **No look-ahead** is stated as a rule and tested.
  5. **What happens to a second pattern during an open trade** is stated.
  6. **Costs of $0.45 and $0.75** are reported (not gated).
  7. **Tops and bottoms** are reported separately inside the two-sided variants.
  8. The variants are renamed **DT-1 to DT-4**.
- **Earlier tests on this file:** the gold hub lists 18 strategies; none passed every gate. The closest relative is the head-and-shoulders test on gold, 15-minute bars (`hs_spec.md`, 16 Oct 2026): four variants, all buried; the long-and-short version at the smaller scale passed 5 of 6 gates, failing only the development t (1.26), at the 100th percentile of its control. Its zigzag detector is reused here.
- Gold rose about elevenfold over the file, which favours long rules. That is why there are double-bottom-only variants. The control trades the same direction at other times.

## Instrument and data
As in the first version:
- **XAUUSD** on the IC Markets MT4 demo, 1-minute bid bars, 2004 to **2026-10-07 16:57 New York**.
- **The clock of our clock audit** (`gold_audit_clock.loadAuditClock`).
- **1-hour bars** on the New York clock, closing on the hour (`gh_lib.barsOf(M, 60)`), built from the minutes that exist. Positions are held over breaks, weekends and holidays.
- **Prices** have two decimals in every year of the file (checked 2026-11-11), so one tick is **$0.01**.
- **Data checks before the run** (`dtop_datacheck.js`, output in `dtop2_out`), the same five checks as the first version. Any failure stops the test.
- **Holes (rule 3):** the suspect and unclear gaps of `data_holes_xau.json`, carried over to the audit clock minute by minute. Trades open across such a gap are counted, and every gate and verdict is recomputed without them; a changed verdict becomes Inconclusive.

## No look-ahead (a rule)
- A zigzag pivot exists for the rules only from the close of the bar that confirms it, never from the bar where it formed.
- The pattern is examined at the close of the bar that confirms the second top (bottom), using the first top, the valley and the second top as confirmed pivots and only bars up to that close.
- The break, the stop and the target use only bars up to the break bar; the entry is at the minute after it.
- **Tested in the self-test:** the engine run on the data cut at the end of a bar must give exactly the same pivots, patterns and trades, for everything completed before the cut, as on the full data.

## The pattern (on 1-hour closes)
- **Zigzag (unchanged; the head-and-shoulders detector):**
  - s(t) = the standard deviation of the log changes of the 500 1-hour closes before bar t.
  - A peak is confirmed at the first bar whose close is at least k x s(t) below the highest close since the last trough; a trough the other way round.
  - The pivot's bar and price are those of that highest (lowest) close, the first if equal. Patterns from bar 501 on.
  - **Two scales, k = 3 and k = 6.**
- **Double top**, checked each time a peak is confirmed: the last three pivots are the **first top P1** (a peak), the **valley T1** (a trough) and the **second top P2** (the peak just confirmed, at bar c). The pattern is valid if:
  1. **prior trend:** the 50-bar EMA of 1-hour closes (seeded with the average of the first 50 closes, weight 2/51) is **higher at the bar of P2 than at the bar of P1** (it rose into the second top). Both values use only closes up to the bar of P2, which is before c.
  2. **equal tops:** |P2 - P1| <= 0.3 x k x ATR, in dollars per ounce, between the two tops' closes. ATR is Wilder's ATR(14) of the 1-hour bars at bar c - 1, the last bar before the confirmation. Wilder's ATR uses the true range, averaged over the first 14 bars and then smoothed with weight 1/14.
- **Levels, from the bars' highs and lows:**
  - the valley floor (the neckline) N = the lowest low of the bars from P1 to P2;
  - the top = the highest high of the same bars;
  - the height h = top - N.
- **Break (the confirmation):** the first 1-hour **close below N**, at or after bar c. It must come (a) before the next zigzag pivot is confirmed, and (b) fewer bars after P2 than there are from P1 to P2. Otherwise the pattern is dropped.
- **Double bottom:** the mirror image, checked each time a trough is confirmed.
  - The EMA50 is **lower** at the second bottom than at the first.
  - The neckline is the highest high between the two bottoms.
  - The break is a close above it.

## The trade
- **Entry:** at the open of the first 1-minute bar after the break bar.
  - A sell after a double top, a buy after a double bottom.
- **Stop:**
  - **double top:** SL = the second top + $0.01. The second top is the highest high of the 1-hour bars from the bar after T1 to the break bar.
  - **double bottom:** SL = the second bottom - $0.01. The second bottom is the lowest low of the same bars.
  - The buffer of one tick is fixed in advance, not optimised.
- **Target (the measure rule):**
  - **double top:** TP = N - h;
  - **double bottom:** TP = N + h.
- **No trade** if the entry is already at or beyond the target or the stop.
- **One position at a time.**
  - A pattern that breaks while a trade is open is **ignored**: it is not queued and not taken later, and the open trade is not changed.
  - Two patterns breaking on the same bar while flat: the one whose second top was confirmed first is taken.
- **Exits:**
  - checked inside each 1-minute bar from the entry minute on;
  - stop and target touched in the same minute: the stop is taken;
  - a level gapped through fills at the minute's open;
  - no time limit;
  - a position open at the end of the data is closed at the last close.
- **R** = h, the pattern's height (a trade reaching its target makes about +1 R before costs).
- **Four variants:**
  - **DT-1:** double tops (sell) and double bottoms (buy), k = 3;
  - **DT-2:** double tops and double bottoms, k = 6;
  - **DT-3:** double bottoms only (buy), k = 3;
  - **DT-4:** double bottoms only, k = 6.

## Costs
- **Baseline, used for every gate and verdict:** $0.30 per ounce per round trip, as in every gold test; slippage zero (optimistic, stated).
- **Cost sensitivity, reported, not gated:** $0.45 (1.5 x) and $0.75 (2.5 x) per round trip.
- **Financing, reported:**
  - scenario A: 3% a year of the entry price per calendar day held;
  - scenario B: the IC Markets XAUUSD swap recorded on 2026-10-12, Wednesday counting three.

## Periods, gates, control
- **Periods (by entry date):**
  - development 2004 to 2012;
  - validation 2013 to 2019;
  - holdout 2020 to 2026-10-07, **already used**.
- **Six gates per variant:**
  1. validation profit factor >= 1.2;
  2. at least 50 trades in each period;
  3. development **t >= 2.5**;
  4. above the 95th percentile of 500 runs of the matched control;
  5. positive without the 10 best trades;
  6. holdout net positive (flagged as used).

  A variant with fewer than 30 trades is Inconclusive.
- **Matched control (moved entries):**
  - All real entries are moved together by one random circular offset of whole days (at least 5% of the days), keeping:
    - each trade's direction and its time of day;
    - the number and spacing of the trades (less any that the one-position rule or a day without data removes);
    - the stop and target distances from the fill, in units of volatility (s x close of the last bar closed before the entry), with R scaled the same way.
  - 500 runs, seeds 1000 + run. Statistic: the average net R per trade.
  - Gate 4 requires beating its 95th percentile; the t gate alone is not enough.

## Engine and self-test (before the run)
New code:
- `dtop2_lib.js`, the engine, which reuses the first version's zigzag, exits and control;
- `dtop2_ref.js`, an independent re-implementation with its own bars, volatility, zigzag, EMA, ATR, patterns and walk;
- `dtop2_selftest.js`, which must pass before any result is printed. It checks:
  1. **hand-worked cases:**
     - the EMA50 and ATR(14) against direct computations;
     - the trend rule accepting and rejecting, for tops and for bottoms;
     - the equal-tops tolerance at its edge, in dollars, and with the ATR read at bar c - 1;
     - the stop with its $0.01 buffer, and the target;
     - a pattern ignored while a trade is open;
     - the rest as in the first version;
  2. the 1-hour bars and the volatility against naive recomputations on the real data;
  3. the re-implementation matched trade by trade for all four variants on the real data;
  4. **no look-ahead:** the data cut at four points must give identical pivots, patterns and trades for everything completed before each cut;
  5. the control at offset 0 reproducing the real trades.

## Before the article
Results go to the owner first:
- all four variants and every gate, the verdict and its cause;
- double tops and double bottoms separately, also inside DT-1 and DT-2;
- by year;
- the patterns found and confirmed, per scale;
- target and stop shares, and the pullback to the neckline;
- the cost sensitivity and the financing scenarios;
- the hole check;
- the comparison with the first version and with the head-and-shoulders test.

The question for the article: do mechanically detected zigzag double tops and bottoms have real predictive value after the neckline confirmation? One article, published only with the owner's agreement, whatever the result.

## Reading the result
"Buried" or "Inconclusive" mean a convincing edge was not demonstrated; neither is proof that none exists. One market, one timeframe, one broker's demo history, one mechanical definition at two scales.

### Run log
- 2026-11-11: frozen. sha256 of this file above the "### Run log" heading: 33e986112e2c5ea26f55deb2b59b94b3f69cfcbaf2f14d54b5b961e93399729d.
- 2026-11-11, before the run: dtop_datacheck.js --out=./dtop2_out passed every check (the same data and results as for the first version). dtop2_selftest.js PASSED on its first run (50 checks, among them the no-look-ahead check on four cuts of the data; engine = re-implementation on every pivot, pattern, break and trade; the EMA50 and ATR(14) equal at every bar).
- 2026-11-11: dtop2_run.js -> dtop2_out/: DT-1 272 trades, avg -0.054 R (gross -0.030), control percentile 34.2, Buried 1/6 (only gate 2), cause No proven edge; DT-2 107 trades, -0.054 R (gross -0.040), 40.2, Buried 1/6 (holdout +8.96 R), No proven edge; DT-3 147 trades, +0.034 R (gross +0.058), 51.4, Buried 1/6, Fragile; DT-4 52 trades, +0.085 R, 44.6, Buried 2/6, Fragile, and by rule 3 Inconclusive (27 of 52 trades open across a suspect or unclear gap; the 25 left are fewer than 30). Double tops lose before costs in both two-sided variants (-0.111 and -0.132 R a trade gross); costs of $0.45 and $0.75 change no sign except DT-3 at $0.75 (-0.002 R). No rule was changed.
- 2026-11-11: the owner asked for the article ("Da, scrie-l"). build_dtop_post.js (this version as the main result, the first version beside it) and wire_dtop.js written, to be published on 2026-11-13 after the CCI post (wire_dtop anchors on wire_cci). A full trial in a copy of the workspace (wire_cci, wire_dtop, build_all, check_site) passed with only the expected flags (two future publication dates; four pages changed by counts or a related link, to accept on the day); the copy was then deleted and nothing was wired in the real site.
- 2026-11-12: published as /posts/double-top-pattern-gold/, with the first version beside it (the owner asked for the article on 2026-11-11: "Da, scrie-l").
- 2026-11-12: added to the gold hub (best-gold-trading-strategy): both rule sets, 8 versions; the hub now counts 123 versions of 20 strategies.
