Mandelbrot Ch. 2: Fractals & Multi-Scale Market Geometry
阅读中文版Self-similarity across timeframes, the Koch curve and coastline paradox applied to price charts, and constructing multifractal price generators.
🔊 Listen to Article (Chinese Audio)
Mandelbrot Fractal Ch. 2: Fractals & Multi-Scale Market Geometry
"Show any expert a stock chart with the time axis erased — a one-minute chart, a daily chart, a yearly chart — and no one can tell which timeframe it is from shape alone. That is not coincidence; it is the mathematical signature of fractal structure." — Benoit Mandelbrot
From the Coastline Paradox to Market Geometry
Mandelbrot's fractal geometry begins with: "How long is the coast of Britain?" The answer depends on ruler length — shorter rulers capture more jagged detail and yield longer measured coastlines. This scale-dependence is the hallmark of a fractal: self-similarity across magnifications.
Applied to markets, erasing the time axis of a price chart reveals statistically similar "texture" whether the chart spans minutes, hours, days, or months.
The Mathematics of Fractal Dimension
$$D = \frac{\log(N)}{\log(1/r)}$$
For the Koch curve, each segment splits into 4 self-similar copies at scale $r = 1/3$:
$$D_{Koch} = \frac{\log 4}{\log 3} \approx 1.2619$$
Fractal Dimension of Price Paths
Using box-counting:
$$D = \lim_{\epsilon \to 0} \frac{\log N(\epsilon)}{\log(1/\epsilon)}$$
| Market Regime | Fractal Dimension | Path Character |
|---|---|---|
| Strong trend | $D \approx 1.2$–$1.35$ | Smooth, few reversals |
| Random walk / chop | $D \approx 1.5$ | Resembles Brownian motion |
| Panic / high volatility | $D \approx 1.6$–$1.8$ | Highly jagged, near plane-filling |
Multifractal Price Generators
Unlike Geometric Brownian Motion (single fractal everywhere), Mandelbrot's multifractal model allows local fractal dimension to vary by regime — calm periods vs. panics.
import numpy as np
def midpoint_displacement_fractal(n_iterations=10, roughness=0.5, seed=42):
np.random.seed(seed)
n_points = 2 ** n_iterations + 1
path = np.zeros(n_points)
path[-1] = np.random.normal(0, 10)
step, scale = n_points - 1, 10.0
while step > 1:
half = step // 2
for start in range(0, n_points - 1, step):
mid = start + half
path[mid] = (path[start] + path[start + step]) / 2 + np.random.normal(0, scale)
scale *= (0.5 ** roughness)
step = half
return path
Practical Execution Rules
- Do not draw conclusions from a single timeframe's chart pattern — self-similarity means head-and-shoulders on a daily chart is equally common (and equally non-predictive) on a 1-minute chart.
- Quantify regime with fractal dimension, not just moving averages — rising $D$ above 1.6 signals a shift to jagged, panic-like structure; reduce trend-following exposure.
- Reject the illusion that longer timeframes are inherently "more real." Fractal geometry shows no privileged natural timescale for price.