Mandelbrot Ch. 4: Volatility Clustering & Multi-Fractal Trading Time
阅读中文版Why large moves cluster together, the distinction between clock time and trading time, and building a multifractal time-deformation model.
🔊 Listen to Article (Chinese Audio)
Mandelbrot Fractal Ch. 4: Volatility Clustering & Multi-Fractal Trading Time
"Market time is not the uniform time of a clock — it is elastic, compressed by panic and stretched by calm. Understanding this distinction between trading time and clock time is the key to volatility clustering." — Benoit Mandelbrot
"Large Changes Follow Large Changes, Small Follow Small"
Mandelbrot's cotton-price research revealed volatility clustering: violent moves cluster together, calm periods cluster together, and the clustering pattern itself is fractal — self-similar across timeframes. This directly contradicts Geometric Brownian Motion's assumption of constant volatility.
Clock Time vs. Trading Time
Mandelbrot distinguished clock time (uniform physical seconds) from trading time — the market's internal rhythm of information flow and activity, which is not synchronized with the clock.
$$\theta(t) = \int_0^t \phi(s)\,ds$$
where $\theta(t)$ is cumulative trading time and $\phi(s)$ is an activity-density proxy (volume or realized volatility). Under trading time $\theta$, prices behave closer to standard Brownian motion; under clock time $t$, they show clustered fat tails.
GARCH vs. Multifractal Cascades
$$\sigma_t^2 = \omega + \alpha\epsilon_{t-1}^2 + \beta\sigma_{t-1}^2$$
GARCH captures short-run mean-reverting volatility clustering with a single autoregressive timescale. Mandelbrot's multifractal cascade model instead allocates volatility weight recursively across multiple timescales, naturally reproducing cross-scale clustering.
| Model | Time-Scale Treatment | Clustering Fidelity |
|---|---|---|
| GBM | Single constant volatility | None |
| GARCH(1,1) | Single autoregressive scale | Partial, short-run only |
| Multifractal cascade | Multi-level cascade | Cross-scale self-similar clustering |
import numpy as np
def multifractal_cascade_volatility(n_steps=1024, levels=10, m0=0.6, seed=7):
np.random.seed(seed)
weights = np.ones(1)
for _ in range(levels):
m1 = np.random.choice([m0, 2 - m0], size=len(weights))
m2 = 2 - m1
weights = np.column_stack([weights * m1, weights * m2]).flatten()
weights = weights[:n_steps] / np.mean(weights[:n_steps])
return np.random.normal(0, 1, n_steps) * np.sqrt(np.abs(weights))
Practical Execution Rules
- Cut leverage proactively during panic regimes rather than waiting for lagging volatility confirmation — clustering means high volatility tends to persist for subsequent sessions.
- Model options around information-flow density, not calendar days — earnings, FOMC, and holidays deform trading time relative to clock time.
- Monitor multiple realized-volatility windows (5/20/60-day) rather than a single GARCH parameter, since clustering has genuine cross-scale structure.