BubbleGuard

Detection Methodology

One 0-100 score per market, from nine modules that look at different things and often disagree. This page says how they are combined, where the thresholds come from, and how often the alert level lights up in a market where nothing is wrong.

The score is not an average

Averaging nine modules buries the one that is shouting under the eight that are calm, and a bubble is usually one loud signal. So the composite takes the strongest of three specialist detectors — LPPLS, Technical, Credit stress — and weighs it 70%, with the weighted mean of all nine supplying the other 30% as context.

score = 0.7 × max(LPPLS, Technical, Credit stress) + 0.3 × weighted mean of all nine

That choice is most of the engine. Replayed over the historical episodes, this formula flagged 8 of 9 before their peak; the same modules combined as a plain weighted mean flagged 2 of 9. So read the weights below for what each module contributes to the context term, not as nine ingredients of equal standing: the detection comes from the strongest specialist, and the weighted mean is what surrounds it.

The weights below are the ones in the source; they add up to 105, so the engine normalises them before use and the percentages shown are the normalised ones. They also shift by timeframe: a yearly view leans on valuation, macro and LPPLS, a daily one on technicals and sentiment.

The nine modules

LPPLSspecialist

21.0%

Log-Periodic Power Law Singularity, the Sornette (2001) fit. Looks for super-exponential price growth wrapped in accelerating oscillations — the shape a market makes when the rise is feeding on itself.

Valuation

13.3%

CAPE (30%), Buffett indicator (25%), Tobin's Q, Hussman P/S and the equity risk premium (15% each), each scored against its own history rather than an absolute level.

Macro

12.4%

FRED series, cached for a day: 10Y-2Y and 10Y-3M curve spreads, real Fed funds, high-yield OAS, M2 growth, the S&P-to-M2 ratio, Sahm rule, industrial production and credit growth.

Sentiment

12.4%

VIX and VVIX, put/call ratio, AAII bull-bear, margin debt, insider buying and IPO pace. Several of these have no free feed: where one is missing the module scores it neutral instead of inventing it.

ML ensemble

11.4%

Random forest, XGBoost, isolation forest and a three-state hidden Markov model over 23 price-based features. Trained on labelled historical windows, which is also why it is excluded from the historical backtest.

Credit stressspecialist

9.5%

The crises that price alone misses. Inversion memory (the deepest 10Y-2Y inversion of the last year, which stays armed after the curve re-steepens), high-yield spread widening, and the current level of both.

Technicalspecialist

8.6%

Weekly and monthly RSI, distance from the 200- and 50-day averages, Bollinger %B, proximity to the all-time high, the slope of the 200-day, volatility regime, volume spikes and a parabolic-move detector.

Microstructure

6.7%

Short interest days-to-cover, ETF flows, how much of the market sits in its ten largest names, and the high-beta to low-beta ratio. The premium data sources here are not subscribed: the module degrades to free proxies or to neutral.

GSADF

4.8%

The Phillips-Shi-Yu (2015) right-tailed test for explosive roots, with the backward variant date-stamping the start and end of a bubble episode. It carries the smallest weight because on real, noisy data it came out close to constant.

When a module has no data

It scores a neutral 50 and stays in the mix at its weight. That keeps one missing feed from swinging the composite, and it means a score is never built on a module that silently failed — but it also means a market with thin data sits closer to the middle than the evidence alone would put it.

What the score means

0–40

Low

40–51

Moderate

51–60

Elevated

60–66

High

66–100

Extreme

Where the alert level comes from, and what it costs

51 is not a round number someone liked. It is the point that best separated 8 historical bubble episodes from 25 readings taken in calm markets (S&P 500 and Nasdaq, quarterly, 2010-2017), each scored point-in-time, with only the data available on the day.

100%

Episodes caught

Every one of those episodes crossed 51 within the twelve months before its peak.

24%

Calm readings above it too

Roughly one calm-market reading in four crossed the same level. A score at Elevated is a reason to look, not a forecast.

That second number is the honest half of the first. A threshold low enough to catch every episode is also low enough to fire in a quiet market about a quarter of the time, and no amount of tuning removes the trade-off — it only moves it. The historical replay behind these figures is retrospective: it was run after the fact, on episodes already labelled as bubbles, and what it found is below.

What the historical replay found

9 of the 14 labelled episodes have daily history a replay can use. 8 of those 9 crossed the alert level before their peak, on average 19.8 months early. The remaining one, cannabis stock bubble 2018 (TLRY), produced no testable point at all: the stock had been listed two months at the peak and the tests need a year of daily data — which is why this is published as 8 of 9 and not as 8 of 8.

US Housing Bubble / GFC 2007

21 months

Flagged in January 2006; ^GSPC peaked in October 2007.

Dot-com Bubble 2000

29 months

Flagged in October 1997; ^IXIC peaked in March 2000.

Which is the part to be careful with. 29 months of warning means someone who sold on that flag sat out years of the largest part of the rise. A score at Elevated is a reason to look, not a forecast: this is a regime and systemic-risk monitor, not a timing tool and not an exit signal.

Price alone does not see 2007

A second replay ran the price-based tests on their own — GSADF, LPPLS and the technical module, equally weighted. It caught 8 of 13 episodes and only 7.1 months ahead on average, and it never flags the 2007–09 crisis before the peak. In the full engine that detection comes from the credit module: the curve inversion and the widening of high-yield spreads, not the shape of the price. The same asymmetry shows on the dot-com: price alone sees it 2 months ahead, the full engine 29. It is the clearest argument in these results for keeping a module that has nothing to do with charts.

Run on 25 September 2026. The full point-by-point output is committed in backend/results/backtest/.

Nothing on this page is typed in by hand. The weights, bands and calibration figures are generated from the engine source (composite.py) and the replay figures from the committed run in backend/results/backtest/, both by backend/scripts/export_engine_spec.py; a unit test fails if any of them drift apart.

Disclaimer: BubbleGuard scores are for informational purposes only and do not constitute financial advice. Past model performance does not guarantee future results.