double_bottom_breakdown
Double Bottom Breakdown
Bearish: two troughs test the same support level, then price breaks down below. Tolerance is normalized by daily volatility (z-scores). Requires minimum 8% rally between troughs.
Signal family
Pattern — Formal chart-pattern detectors (double tops / bottoms, failed breakouts, HH/HL structure).
Parameters
| Name | Description | Default | Range |
|---|---|---|---|
| peak_order | Peak detection window | 15 | 5–25 |
| tolerance_zscore | Tolerance (z-scores of daily vol) | 1.5 | 0.5–3.0 |
| min_separation | Min days between troughs | 25 | 10–60 |
| max_separation | Max days between troughs | 252 | 60–504 |
Historical context
110,750 triggers on 21,113 tickers, 1989-03-31 → 2026-05-01. Universe: US large-cap (mcap ≥ $100,000,000, price ≥ $1). Long-only convention: BUY at open T+1, hold the horizon, compare to S&P 500 Equal Weight over the same window.
Methodology footnotes
Benchmarks shown in the detail tables: spxew (S&P 500 Equal Weight — primary, median-stock view, avoids the 2020+ megacap-concentration distortion), spx (S&P 500 cap-weighted, distorted post-2020), msci (MSCI World USD). Per-stock regime tags: trending = ADX(14) ≥ 25, high vol = 20d realized annualized vol ≥ 20%. 1d return = intraday T+1 open→close; 20d = open T+1 to close T+20.
At a glance — alpha vs S&P 500 Equal Weight, US-only
Holding-period sensitivity. Bullish columns: positive = signal worked (long the trigger beat the index). Bearish columns: negative = signal worked (the flagged stock underperformed).
| Horizon | Bearish α |
|---|---|
| 5-day | +0.24% |
| 20-day | +0.57% |
| 60-day | +0.48% |
| 1-year | +1.86% |
Double Bottom Breakdown is a single-direction signal — only the bearish side is meaningful.
Where does DOUBLE_BOTTOM_BREAKDOWN actually fire?
The bucket distribution often reveals what the signal really is, regardless of its textbook label. Heavy concentration in "non-trending + high vol" = it's mostly a chop-market event. Heavy in "trending + low vol" = it picks up the smooth grinds. Read the chart before the alpha numbers — context shapes everything that follows.
Does it work in every regime?
Trigger alpha split by the host stock's own regime on the trigger date — trending or ranging, high-vol or low-vol. The 20d alpha you'd actually capture if you took the trade. Bars matching your direction's "right" sign (green) = the signal worked in that regime; opposite sign = avoid it there. A signal with one strong-positive bar and three flat ones isn't a "20d alpha" signal — it's a "20d alpha when the stock is X" signal.
Does it work in every era?
A multi-year average can hide major instability. The sample splits into three windows: 2015–2019 (pre-COVID), 2020–2022 (pandemic + 2022 bear), and 2023+ (post-ZIRP + AI megacap rally). All three matching your direction's "right" sign = the signal is durable. One era doing all the work = a regime-specific edge that may not repeat. The bigger the variance across eras, the smaller the position you should run.
↓ Bearish triggers negative alpha = signal was right (stock underperformed market)
| Bench | Metric | 1d | 5d | 20d | 60d | 252d |
|---|---|---|---|---|---|---|
| spx | Stock % | +0.06% | +0.34% | +1.95% | +3.84% | +13.47% |
| Bench % | +0.04% | +0.24% | +1.65% | +3.81% | +15.32% | |
| Alpha % | +0.02% | +0.13% | +0.29% | -0.00% | -1.65% | |
| Median alpha | +0.01% | +0.07% | -0.32% | -2.01% | -10.72% | |
| Hit rate (α>0) | 50.2% | 50.6% | 48.5% | 44.9% | 37.9% | |
| p (naive) | 0.0435 | <0.001 | <0.001 | 0.9834 | <0.001 | |
| p (HAC) | 0.0440 | <0.001 | <0.001 | 0.9863 | <0.001 | |
| N | 108,291 | 104,979 | 103,915 | 100,223 | 94,978 | |
| msci | Stock % | +0.06% | +0.34% | +1.95% | +3.84% | +13.47% |
| Bench % | +0.10% | +0.23% | +1.48% | +3.53% | +12.96% | |
| Alpha % | -0.01% | +0.10% | +0.39% | +0.46% | -0.07% | |
| Median alpha | -0.01% | +0.04% | -0.23% | -1.60% | -8.70% | |
| Hit rate (α>0) | 49.7% | 50.3% | 48.9% | 45.8% | 39.8% | |
| p (naive) | 0.1726 | <0.001 | <0.001 | <0.001 | 0.6863 | |
| p (HAC) | 0.1740 | <0.001 | <0.001 | <0.001 | 0.8639 | |
| N | 107,775 | 104,351 | 102,132 | 99,543 | 93,669 | |
| spxew | Stock % | +0.06% | +0.34% | +1.95% | +3.84% | +13.47% |
| Bench % | +0.08% | +0.09% | +1.31% | +3.33% | +11.60% | |
| Alpha % | -0.02% | +0.24% | +0.57% | +0.48% | +1.86% | |
| Median alpha | -0.01% | +0.15% | -0.10% | -1.49% | -7.17% | |
| Hit rate (α>0) | 49.7% | 51.2% | 49.5% | 46.0% | 41.5% | |
| p (naive) | 0.0839 | <0.001 | <0.001 | <0.001 | <0.001 | |
| p (HAC) | 0.0846 | <0.001 | <0.001 | <0.001 | <0.001 | |
| N | 107,429 | 103,985 | 102,317 | 98,881 | 93,585 |
Permutation null detail — all horizons × both benchmarks
| Horizon | Bench | Observed lift | Null mean | Null 95% CI | pperm |
|---|---|---|---|---|---|
| 1d | spx | +0.14% | +0.09% | [+0.08%, +0.11%] | 1.000 |
| 1d | msci | +0.14% | +0.10% | [+0.08%, +0.11%] | 1.000 |
| 1d | spxew | +0.13% | +0.08% | [+0.07%, +0.10%] | 1.000 |
| 5d | spx | +0.58% | +0.39% | [+0.35%, +0.43%] | 1.000 |
| 5d | msci | +0.55% | +0.40% | [+0.36%, +0.44%] | 1.000 |
| 5d | spxew | +0.66% | +0.38% | [+0.34%, +0.42%] | 1.000 |
| 20d | spx | +1.76% | +1.26% | [+1.19%, +1.34%] | 1.000 |
| 20d | msci | +1.74% | +1.28% | [+1.20%, +1.35%] | 1.000 |
| 20d | spxew | +1.82% | +1.24% | [+1.16%, +1.31%] | 1.000 |
| 60d | spx | +3.48% | +2.72% | [+2.60%, +2.85%] | 1.000 |
| 60d | msci | +3.50% | +2.73% | [+2.61%, +2.86%] | 1.000 |
| 60d | spxew | +3.24% | +2.65% | [+2.52%, +2.79%] | 1.000 |
| 252d | spx | +7.37% | +5.74% | [+5.50%, +5.98%] | 1.000 |
| 252d | msci | +6.82% | +5.65% | [+5.41%, +5.89%] | 1.000 |
| 252d | spxew | +6.98% | +5.43% | [+5.19%, +5.66%] | 1.000 |
Example triggers on US large-caps (2023+, mcap ≥ $30B)
Six recent bearish DOUBLE_BOTTOM_BREAKDOWN triggers on US mega-caps. Top three: the signal's best outcomes. Bottom three: the worst. Catalyst-driven outliers (|α| > 25%) excluded so what's left is the signal's own typical good and bad days, not earnings shocks.
Strongest outcomes (what DOUBLE_BOTTOM_BREAKDOWN looks like when it works)
Weakest outcomes (what DOUBLE_BOTTOM_BREAKDOWN looks like when it fails)
Stock-regime quadrants (2×2 per-stock, 20d alpha detail table)
| Quadrant | N | Stock % (spx) | Bench % (spx) | Alpha % (spx) | p (HAC) | Stock % (msci) | Bench % (msci) | Alpha % (msci) | p (HAC) | Stock % (spxew) | Bench % (spxew) | Alpha % (spxew) | p (HAC) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Trending + Low vol Clean directional grind, low whipsaw | 8,020 | +0.29% | +1.40% | -1.07% | <0.001 | +0.29% | +1.24% | -0.90% | <0.001 | +0.29% | +1.09% | -0.77% | <0.001 |
| Trending + High vol Crisis selloff or parabolic rally | 38,766 | +2.35% | +1.76% | +0.56% | <0.001 | +2.35% | +1.56% | +0.70% | <0.001 | +2.35% | +1.27% | +0.98% | <0.001 |
| Non-trending + Low vol Quiet chop, summer doldrums | 8,718 | +0.33% | +1.47% | -1.09% | <0.001 | +0.33% | +1.36% | -0.98% | <0.001 | +0.33% | +1.32% | -0.91% | <0.001 |
| Non-trending + High vol Classical "whipsaw zone" for momentum | 55,246 | +2.17% | +1.67% | +0.52% | <0.001 | +2.17% | +1.50% | +0.58% | <0.001 | +2.17% | +1.37% | +0.73% | <0.001 |
Sub-period breakdown table (20d alpha)
| Period | N | Alpha % (spx) | p (HAC) | Alpha % (msci) | p (HAC) | Alpha % (spxew) | p (HAC) |
|---|---|---|---|---|---|---|---|
| 2015-2019 2015-01-01 → 2020-01-01 | 32,427 | -0.26% | <0.001 | -0.01% | 0.8301 | -0.24% | <0.001 |
| 2020-2022 2020-01-01 → 2023-01-01 | 35,740 | +0.71% | <0.001 | +0.86% | <0.001 | +0.84% | <0.001 |
| 2023-2026 2023-01-01 → 2099-01-01 | 42,512 | +0.34% | <0.001 | +0.29% | <0.001 | +0.95% | <0.001 |
Methodology and caveats
How to read. Entry at open of T+1 (one trading day after the signal fires on close of T). 20d = open T+1 to close T+20. Alpha = stock return − benchmark return over the same window (Convention A, single-sided, textbook). For bullish triggers, POSITIVE alpha = signal was right. For bearish triggers, NEGATIVE alpha = signal was right (stock underperformed market). No sign-flipping; the direction of the bet determines what "good" looks like. Per-stock regime is each stock's own ADX(14) and RV(20) at the trigger date — not market-wide state.
Three p-values, three robustness tests. (a) p_naive: scipy one-sample t-test on winsorized alphas. Optimistic because overlapping 20d windows on the same ticker inflate effective N. (b) p_hac: Newey-West HAC with lag = horizon — corrects for the overlap and is the academic-finance standard. (c) p_perm: fraction of 200 random-date null iterations with mean ≥ observed. Tests whether the signal beats random date selection at all. A signal that clears all three (pnaive, phac, pperm all < 0.05) has real information; a signal that fails pperm has zero edge even if the t-test says "significant."
Caveats. (i) Universe reflects today's active tickers; delisted losers pruned → survivorship bias. (ii) Mcap ≥ $100M filter uses today's snapshot, not point-in-time — mild lookahead on which stocks enter the sample, not on returns. (iii) Means and p-values use winsorized alphas (1/99 percentile) to prevent data errors from dominating. Medians and hit rates use raw data. (iv) Zero transaction costs assumed. Realistic bid-ask + commissions remove 20–40bps from 20d alpha on US large-caps, more on small-cap. Sub-20bps alpha is noise in practice. (v) Past performance does not predict future results.
How to use this
1 · When to reach for this signal
Caution recommended. Bearish 20d alpha is +0.29% and worse than random . Either direction fails the "beats random" test. Don't use Double Bottom Breakdown as a standalone entry trigger. It may still be useful as part of a composite (section 4).
2 · When it works — the setups that drive it
- Best bearish setup: Trending + High vol — alpha +0.56% / 20d on 38,766 historical triggers.
- Best era for bearish: 2020-2022 — alpha +0.71% / 20d.
3 · When it fails — common false positives
- Weakest bearish cell: Non-trending + Low vol — alpha -1.09% / 20d on 8,718 triggers.
- Worst era for bearish: 2015-2019 — alpha -0.26% / 20d.
Signal-specific failure patterns
4 · Pairing inside a screen
The statements below describe how this signal relates to others by construction — which indicator family it belongs to, and where same-family redundancy might reduce the independence of evidence inside a Daily Report. These are taxonomic classifications drawn from standard technical-analysis texts; they are not pairing backtests. A multi-signal convergence backtest is planned but not yet run.
Reversal-pattern family
Double bottom and double top are canonical two-swing reversal patterns (Edwards & Magee, Technical Analysis of Stock Trends, 11th ed. 2018; Bulkowski, Encyclopedia of Chart Patterns, 3rd ed. 2021; Lo, Mamaysky, and Wang, "Foundations of Technical Analysis", Journal of Finance 55(4), 2000). A completed double-bottom breakdown and a failed-double-bottom signal on the same stock fire in sequence rather than concurrently — they represent different stages of the same pattern.
What would likely rescue this signal
This block calls out the data or conditions that could turn a technically weak signal into a usable one in a composite screen. Based on signal mechanics and the observed failure patterns above; individual combinations are not yet backtested.
- Volume filter — Breakdowns on weak volume often reverse as squeezes; 1.5-2× average volume gate should concentrate the alpha.
- Hold to 60d — The signal is stronger at 60d than 20d. Time stop at 60 trading days captures more.
- Regime filter on market breadth — Edge is in narrow-breadth regimes (2020+). Gate on 'market breadth < 55%' to enable the signal only when the regime favors it.
See also Why technical-only signals don't survive on their own for the broader argument.
5 · Before you act — a 5-point checklist
- Normal trading day? Rule out earnings (within ±3 days), ex-dividend, or known corporate-action dates — the signal is almost certainly reading noise, not momentum, in those windows.
- Where is price vs its own 50 / 200 DMA? Pattern signals carry their own structural context; check that the implied support/resistance levels have historical relevance, not just the most-recent 3-month range.
- What's the sector breadth doing? An isolated signal in a broadly down-trending sector is a lower-confidence setup than one firing with the rest of its peer group.
- Is ADV20 enough for your size? If the trigger is on a $500M name and you want to move $1M notional, you're the tape. Consider adv20d ≥ 5% of your intended position.
- What invalidates you? Define a price level (for longs: a close below the trigger-day low; for shorts: close above the trigger-day high) and honor it. The backtest alpha is an average; any one trade can be at either tail.
Execution notes
Tradable at 60d under Convention A. 20d signal is borderline significant; 60d is clear. Entry open T+1. Skip the 2015-2019 regime if you're calibrating on period sub-samples — it's inverted relative to current behavior. Recent 2023-2026 alpha is only −0.12, so don't oversize.