5D Library › Non-Ergodic Wealth Dynamics, the Kelly Criterion and Volatility Drag · 中文
Chapter 5 Shannon’s Demon and the Rebalancing Bonus
A stock that goes nowhere
According to Poundstone’s account, Claude Shannon put forward a thought experiment in a lecture at MIT in the 1960s: a stock either doubles or halves each day, with equal probability, so in the long run it neither rises nor falls (its geometric mean is √(2 × 0.5) = 1). What happens if half one’s money is in this stock and half in cash, readjusted back to half and half after every close (Poundstone 2005)?
The answer: the portfolio is multiplied each day by 1.5 or 0.75, with a geometric mean of √(1.5 × 0.75) ≈ 1.061, growing by about 6 % a day. An asset that goes nowhere in the long run, plus cash and mechanical rebalancing, becomes a steadily growing portfolio. The result came to be called Shannon’s demon; Luenberger’s textbook calls it “volatility pumping” (Luenberger 1998).
Calculation
The exact values for Shannon’s demon; the small-volatility approximation “rebalancing bonus ≈ one-eighth of the variance of log returns”; and simulations adding transaction costs and swapping in a trending asset.
# Shannon's demon. An asset doubles or halves each period with equal probability: its
# typical (geometric) growth is zero, sqrt(2 * 0.5) = 1. Hold half in this asset and half
# in cash (zero interest), and rebalance back to 50/50 after every period.
import math, random, statistics
up, down = 2.0, 0.5
hold = math.sqrt(up * down)
r_up, r_down = 0.5 + 0.5 * up, 0.5 + 0.5 * down
reb = math.sqrt(r_up * r_down)
print(f"asset alone: {up} or {down}; geometric growth {100 * (hold - 1):+.2f} % a period")
print(f"50/50 rebalanced: {r_up} or {r_down};"
f" geometric growth {100 * (reb - 1):+.2f} % a period")
# Small-volatility rule: with log-returns of variance v, a 50/50 mix rebalanced each
# period gains about v/8 a period in log growth over the average of its two parts.
for sd in (0.05, 0.10, 0.20):
ex = 0.5 * math.log(0.5 + 0.5 * math.exp(sd)) + 0.5 * math.log(0.5 + 0.5 * math.exp(-sd))
print(f"log-return +/-{sd:.2f}: bonus {ex:.5f} a period, v/8 = {sd ** 2 / 8:.5f}")
random.seed(9)
def path(n=200, cost=0.0, p_up=0.5):
a = w = 1.0
for _ in range(n):
f = up if random.random() < p_up else down
a *= f
risky = 0.5 * w * f
w = 0.5 * w + risky
w -= cost * abs(risky - 0.5 * w) # proportional cost on the amount traded back
return a, w
print(f"\n2,000 paths of 200 periods: median final wealth")
print(f"{'case':>36} {'asset held':>11} {'rebalanced':>11}")
cases = (("fair coin, no costs", {}), ("fair coin, 1 % cost on trades", {"cost": 0.01}),
("fair coin, 5 % cost on trades", {"cost": 0.05}),
("trending asset (up 60 % of periods)", {"p_up": 0.6}))
for label, kw in cases:
res = [path(**kw) for _ in range(2000)]
ma = statistics.median(a for a, _ in res); mw = statistics.median(w for _, w in res)
print(f"{label:>36} {ma:11.3g} {mw:11.3g}")
# asset alone: 2.0 or 0.5; geometric growth +0.00 % a period
# 50/50 rebalanced: 1.5 or 0.75; geometric growth +6.07 % a period
# log-return +/-0.05: bonus 0.00031 a period, v/8 = 0.00031
# log-return +/-0.10: bonus 0.00125 a period, v/8 = 0.00125
# log-return +/-0.20: bonus 0.00499 a period, v/8 = 0.00500
#
# 2,000 paths of 200 periods: median final wealth
# case asset held rebalanced
# fair coin, no costs 1 1.3e+05
# fair coin, 1 % cost on trades 1 9.34e+04
# fair coin, 5 % cost on trades 1 2.45e+04
# trending asset (up 60 % of periods) 1.1e+12 1.37e+11Where the money comes from
The rebalancing bonus is not mysterious. After the asset rises, it is more than half the portfolio, and rebalancing sells some; after it falls, rebalancing buys some. It mechanically “sells after rises and buys after falls”. On an asset that swings back and forth without rising in the long run, this turns fluctuation into return.
In the language of Chapter 2: the portfolio’s expected return is the average of its two parts (the asset’s arithmetic expected return is +25 % a period, cash’s is 0, so 12.5 %), but its volatility is only half the asset’s, so its volatility tax is only a quarter of the asset’s. The asset alone: an expectation of +25 % eaten entirely by the volatility tax; the portfolio: an expectation of +12.5 %, of which the tax eats only part. For small fluctuations, the log growth rate of the half-and-half portfolio exceeds the average of its two parts’ log growth rates by about σ2/8, where σ2 is the variance of the asset’s log returns.
When it fails
The simulations also show the limits of the rebalancing bonus:
- Transaction costs eat part of the bonus. Under the extreme swings of Shannon’s demon (doubling or halving each period) the bonus is large and costs only shrink it; under the small fluctuations of ordinary assets σ2/8 is itself small (about 0.5 % a period for a log-return standard deviation of 20 %), and the costs and taxes of frequent rebalancing may cancel it completely.
- In a persistent trend, buy-and-hold does better. If the asset rises 60 % of the time, the buy-and-hold portfolio holds ever more of it and enjoys the full rise; rebalancing keeps selling the winner and falls clearly behind.
The same holds for rebalancing between two risky assets.
Calculation
Two risky assets, each with expected return 6 % and volatility 30 %: the growth rate of a half-and-half mix rebalanced continuously, for different correlations; and median wealth after 30 years, buy-and-hold against monthly rebalancing, when the two assets have the same or different growth rates.
# Rebalancing between two risky assets. Each has mu = 6 % and sigma = 30 % a year, so each
# alone has typical growth g = 6 % - 4.5 % = 1.5 %. A 50/50 mix rebalanced continuously
# has the same mu but volatility sigma_p = sigma sqrt((1 + rho) / 2), so it grows at
# mu - sigma_p^2 / 2. The difference (the "diversification return") exists only while the
# two assets keep growing at similar rates; if one grows faster for good, buy-and-hold
# ends up concentrated in it.
import math, random, statistics
def g_rebalanced(mu, sigma, rho):
return mu - 0.5 * sigma ** 2 * (1 + rho) / 2
print(f"{'correlation':>12} {'each alone g':>13} {'50/50 rebalanced g':>19}")
for rho in (1.0, 0.5, 0.0, -0.5):
print(f"{rho:12.1f} {0.06 - 0.5 * 0.09:+13.4f} {g_rebalanced(0.06, 0.30, rho):+19.4f}")
def step(mu, sigma, dt):
return math.exp((mu - sigma ** 2 / 2) * dt + sigma * math.sqrt(dt) * random.gauss(0, 1))
def sim(mu1, mu2, sigma=0.30, years=30, n=1500, seed=10):
random.seed(seed)
dt = 1 / 12; out = []
for _ in range(n):
a = b = w = 1.0
for _ in range(int(years / dt)):
r1, r2 = step(mu1, sigma, dt), step(mu2, sigma, dt)
a *= r1; b *= r2
w *= 0.5 * r1 + 0.5 * r2 # rebalanced monthly
out.append(((a + b) / 2, w)) # buy-and-hold starts 50/50, never trades
return out
print("\nmedian wealth after 30 years, uncorrelated assets, monthly rebalancing (start = 1)")
print(f"{'asset drifts':>16} {'buy and hold':>13} {'rebalanced':>11}")
for mu1, mu2 in ((0.06, 0.06), (0.10, 0.02), (0.14, -0.02)):
res = sim(mu1, mu2)
h = statistics.median(x for x, _ in res); w = statistics.median(y for _, y in res)
print(f"{f'{mu1:.0%} and {mu2:.0%}':>16} {h:13.2f} {w:11.2f}")
# correlation each alone g 50/50 rebalanced g
# 1.0 +0.0150 +0.0150
# 0.5 +0.0150 +0.0262
# 0.0 +0.0150 +0.0375
# -0.5 +0.0150 +0.0488
#
# median wealth after 30 years, uncorrelated assets, monthly rebalancing (start = 1)
# asset drifts buy and hold rebalanced
# 6% and 6% 2.40 3.12
# 10% and 2% 3.52 3.12
# 14% and -2% 8.87 3.14Each asset alone has a long-run growth rate of only 1.5 % (6 % less a 4.5 % volatility tax); uncorrelated, the half-and-half rebalanced mix grows at 3.75 %, and the lower the correlation the higher the rate. The difference is called the diversification return, and Fernholz and Shay gave its general form in stochastic portfolio theory (Fernholz and Shay 1982). But when the two assets have different drifts (10 % and 2 %, or 14 % and −2 %), the buy-and-hold portfolio gradually concentrates in the stronger asset and ends up ahead of the rebalanced one.
Evidence
Simple rebalancing is not bad. DeMiguel, Garlappi and Uppal compared a 1/N equal-weight portfolio (rebalanced periodically) with a dozen or so “optimal” portfolios based on estimated parameters; across several data sets no optimisation method reliably beat the simple equal-weight portfolio out of sample, mainly because of estimation error (DeMiguel et al. 2009). This echoes Chapter 3: the less precisely the parameters are estimated, the less one should trust elaborate optimisation.
Note
The rebalancing bonus is not a free lunch. It requires that the parts of the portfolio have similar long-run growth rates and swing back and forth relative to one another. If you do not know which part will be stronger in the long run, rebalancing is a discipline for staying diversified under uncertainty; if you do know (or the market is in a persistent trend), it will keep making you sell the winner. The results of this chapter do not support the claim that “rebalancing always raises returns”, only that “between assets with similar growth rates and large fluctuations, rebalancing turns part of the fluctuation into growth”.
Summary
Shannon’s demon shows that a highly volatile asset that goes nowhere in the long run, plus cash and mechanical rebalancing, can make a steadily growing portfolio. The bonus comes from selling after rises and buying after falls; mathematically, lower portfolio volatility means a smaller volatility tax, about one-eighth of the variance for small fluctuations. Its limits are just as clear: transaction costs and taxes eat it, and a persistent trend makes buy-and-hold better; the diversification return between two risky assets also exists only while their growth rates are similar. The next chapter turns to a more dangerous kind of fluctuation: extreme events in the tails of the distribution.
References
Fan, Y. (2026). Non-Ergodic Wealth Dynamics, the Kelly Criterion and Volatility Drag: From Itô's Lemma on Geometric Brownian Motion and Ruin Barriers to Barbell Portfolios, Read Beside the Shiji's 'Biographies of the Money-Makers' [非遍历性财富动力学、凯利准则与波动率税] (Version 1.0.0). 5D Library. https://doi.org/10.5281/zenodo.23754709 · Licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).