halo 的技术博客

返回

大多数人学 Kelly 公式,学到的是「一个能让你赚最快的仓位公式」。错。Kelly 真正回答的问题不是买不买,而是这笔该下多大注。它是在「长期复合增长最快」和「别把自己玩破产」之间,用一条数学曲线替你找的那个最优平衡点。

举个最刺痛的例子:你有个胜率 55% 的硬币赌局,每次赢了拿 1 倍利润、输了亏掉本金。直觉告诉你「有点优势,多押点」——但你敢押多少?押 10%、50%、还是 all-in?押太少,复利几十年也跑不赢通胀;押太多,一次连输五把就出局,优势再大也与你无关。Kelly 给的精确答案是:押 10%。多一分长期变慢,少一分白白浪费优势——而这条曲线,正是下面要推导的东西。

结论先放这:离散下注 f=(bpq)/bf^*=(bp-q)/b,连续(正态)策略 f=μ/σ2f^*=\mu/\sigma^2 在我们的设定(年化收益 10%、波动 20%)下,连续 Kelly 算出满仓比例高达 250%(即该上 2.5 倍杠杆);而蒙特卡洛 4000 条 10 年路径显示:全 Kelly 终值中位数最高(3.47x),但曾有 42% 的路径腰斩;满仓(f=1)腰斩率仅 3.6% 却终值垫底;半 Kelly 用 2.55x 终值把腰斩率压到 9.2%——这就是 Kelly 体系里最反直觉也最值钱的权衡。

一、离散 Kelly:一个硬币赌局的推导#

假设你有一个正期望的赌局:每次胜率 pp,输了赔光下注额、赢了拿 bb 倍利润(对称赔率 b=1b=1)。下注比例为 ff(满仓 f=1f=1),那么赌 NN 次后的财富是各期乘积:

W=(1+bf)Np(1f)NqW = (1+bf)^{Np}(1-f)^{Nq}

取对数、除以 NN,得到期望对数增长率

G(f)=pln(1+bf)+qln(1f)G(f) = p\ln(1+bf) + q\ln(1-f)

ff 求导令为零,立刻得到 Kelly 分数

f=bpqbf^* = \frac{bp-q}{b}

代入 p=0.55, b=1p=0.55,\ b=1

p, q, b = 0.55, 0.45, 1.0
f_star = (b * p - q) / b
print(f"f* = {f_star:.4f}")          # 0.1000 → 每次下 10% 仓位

import numpy as np
fs = np.linspace(0.001, 0.99, 400)
G  = p * np.log(1 + b * fs) + q * np.log(1 - b * fs)
print(f"G 在 f* 处达峰: {G.max():.4f}")   # 峰值 = 最优长期增速
python

注意一个反直觉的点:如果赔率变成 b=2b=2(赢拿 2 倍、输亏 1 倍),同样 55% 胜率下 f=(2×0.550.45)/2=0.325f^*=(2\times0.55-0.45)/2=0.325,仓位直接翻三倍多——Kelly 对赔率极度敏感,这也是它危险的根源之一:你稍微估错 bbpp,最优仓位就会大幅漂移。另外要强调,这里的「长期」指的是下注次数趋近无穷的数学极限,而不是你我的三五年——这恰恰是 Kelly 最容易被误读的地方:它保证的是渐近最优,不保证「前十年」你就笑到最后,期间一次极端回撤就可能让你提前出局。

关键点:G(f)G(f)ff^* 处是唯一峰值;一旦越线(overbet,f>ff>f^*),曲线掉头向下,越过 f=1/bf=1/bG(f)<0G(f)<0——长期必亏。这不是「激进一点多赚」,而是「过了凯利点就开始慢性自杀」。

期望对数增长率在 f* 处达峰,越线即转负

二、连续 Kelly:从赌局到资产组合#

把「胜/负」换成「资产日收益服从 N(μd,σd2)N(\mu_d,\sigma_d^2)」,把「下注比例」换成「仓位 ff」(满仓 f=1f=1)。每期财富乘子 1+frt1+f\cdot r_t,对收益做二阶泰勒展开,期望对数增长近似为:

G(f)fμ12f2σ2G(f) \approx f\mu - \frac{1}{2}f^2\sigma^2

令导数为零:

f=μσ2f^* = \frac{\mu}{\sigma^2}

mu, sigma = 0.10, 0.20
f_cont = mu / sigma**2
print(f"f* = {f_cont:.3f}")     # 2.5 → 该上 2.5 倍杠杆!
python

注意这个 250% 的数字:它暴露了 Kelly 的第一个致命特性——只要你的策略夏普够高、波动够低,理论最优仓位会远超 100%。如果这个数字让你觉得离谱,恰恰说明 Kelly 的「数学最优」和「现实可行」之间隔着一整条杠杆约束:回测里它年化翻几倍,但真去开 2.5 倍杠杆,遇到 2008 或 2020 那种单月 −20% 的行情,保证金早被强平了。复利的前提永远是「你还坐在牌桌上」——这是后面陷阱部分的伏笔。

注意这个 250% 的数字:它暴露了 Kelly 的第一个致命特性——只要你的策略夏普够高、波动够低,理论最优仓位会远超 100%。但现实中杠杆有成本、有强平线、有流动性,全 Kelly 的「数学最优」往往落在你根本借不到、或借了会被 margin call 爆掉的地方。

三、蒙特卡洛:增长、腰斩与路径#

我们用 4000 条 10 年(2520 日)的路径,对比四类资金曲线:满仓 f=1f=1、全 Kelly、半 Kelly、固定 0.25。重点看两件事——终值中位数代表「长期赚多少」,曾腰斩占比代表「中途被清零或强平的风险有多大」:

rng = np.random.default_rng(4026)
T = 252 * 10
shocks = rng.normal(mu/T, sigma/np.sqrt(T), size=(4000, T))   # 日收益
def wealth(f):
    return np.cumprod(1 + f * shocks, axis=1)
fracs = {"满仓 f=1.0":1.0, "全 Kelly":2.5, "半 Kelly":1.25, "固定 0.25":0.25}
paths = {n: wealth(f) for n, f in fracs.items()}
ruin  = {n: (paths[n].min(1) < 0.5).mean() for n in fracs}      # 曾腰斩占比
final = {n: np.median(paths[n][:, -1]) for n in fracs}
python

结果(10 年中位数):

策略终值中位数曾腰斩路径占比
满仓 f=1.02.22x3.6%
全 Kelly (2.5x)3.47x42.1%
半 Kelly (1.25x)2.55x9.2%
固定 0.251.27x0.0%

不同仓位下终值与腰斩概率:满仓终值垫底,全 Kelly 腰斩率爆表

抽样财富路径:满仓最陡但频繁暴跌,半 Kelly 更平滑

读这张表要读懂三件事:

  1. 全 Kelly 终值最高——数学没骗你,长期复合它确实最优;
  2. 但它有 42% 的概率中途腰斩(财富跌到一半以下),对实盘而言这往往意味着「在黎明前被强平出局」;
  3. 半 Kelly 把仓位砍半,终值只从 3.47x 降到 2.55x(损失约 27% 长期收益),腰斩率却从 42% 砍到 9%——用一小块期望,换回一大块睡眠。

四、分数 Kelly:实务里的标准答案#

正因为全 Kelly「收益最高但心惊肉跳」,业界几乎从不用满额 Kelly,而是用 分数 Kelly(fractional Kelly)

fused=αf,α(0,1]f_{used} = \alpha \cdot f^*,\quad \alpha\in(0,1]

  • α=0.5\alpha=0.5(半 Kelly):增长约为全 Kelly 的 75%,波动与回撤大幅减半;
  • α\alpha 越小越保守,直到退化为「固定比例定投」;
  • 一个经验法则:当你对自己的 μ,σ\mu,\sigma 估计越没把握,α\alpha 取越小
alpha = 0.5
f_used = alpha * f_cont      # 实战下单仓位,而非理论 f*
python

经验上,全 Kelly 的回撤中位数常年在 50% 量级,半 Kelly 能压到 25% 左右,四分之一 Kelly 通常不超过 15%。代价是长期收益按比例递减,但对你「能不能把策略执行下去、会不会在低谷砍仓」的边际改善,往往是指数级的。换句话说:分数 Kelly 买的是「活下去的概率」,卖的是「一点点理论最优增速」——对绝大多数非无限现金流的账户,这简直是最划算的一笔交易。

五、真实陷阱(致命版)#

1. 你根本不知道真 μ\muσ\sigma:Kelly 对输入极度敏感。f=μ/σ2f^*=\mu/\sigma^2,若你高估了 μ\mu 或低估了 σ\sigma(回测里太常见),算出的 ff^*越过真实最优点、滑向 overbet 区——误差直接把你从「增长最快」推到「长期必亏」。这是 Kelly 最阴险的坑:估计错一点,方向就反了。

2. 满额 Kelly 的回撤能到 50%+:上面 42% 腰斩率已经说清。对带杠杆的资金,腰斩 = 强平 = 游戏结束,复利再美也与你无关。

3. 杠杆与做空约束:连续 Kelly 动辄算出自变量 >100% 的仓位,但券商不给、成本吃光、极端日会爆。真实可下仓位是 min(Kelly 理论值, 可借上限, 心理承受上限)

4. 独立同分布假设:Kelly 默认各期「独立」。可真实市场有波动聚集、有相关性突变,连续亏损会成串出现——此时 Kelly 的「长期」比你活到的「长期」长得多。

5. 多资产时 f 是向量不是标量*:单资产 f=μ/σ2f^*=\mu/\sigma^2 成立,多资产要用 Kelly 克里格(Kelly Criterion for portfolios),最优权重正比于 Σ1μ\Sigma^{-1}\mu。直接对每个资产套单变量公式会严重低估组合层面的风险抵消。一个最小实现:

import numpy as np
mu = np.array([0.12, 0.08, 0.05])          # 三资产年化期望
Sigma = np.array([[0.04, 0.01, 0.00],       # 协方差矩阵
                   [0.01, 0.03, 0.01],
                   [0.00, 0.01, 0.02]])
w_kelly = np.linalg.solve(Sigma, mu)          # w* ∝ Σ⁻¹μ(未归一化)
w_kelly = w_kelly / w_kelly.sum()            # 归一成组合权重
print("多资产 Kelly 权重:", np.round(w_kelly, 3))
python

这里 Σ1μ\Sigma^{-1}\mu 会自动低配高波动、高相关的资产,高配低波动、与其他资产负相关的资产——本质就是「最大化分散化 + 押注预期收益」的合成。但它同样逃不开陷阱 1:只要 μ\muΣ\Sigma 估计有偏,算出来的权重可能极端到不可执行。

结语#

Kelly 公式不是「满仓冲锋的许可证」,恰恰相反——它是反直觉的谨慎工具:它用数学告诉你「别因为有点优势就 all-in」。真正成熟的用法是:用 Kelly 算出理论上限,再用分数 Kelly 和你的置信度,把它砍到一个你既睡得着、又不会被误差推过悬崖的仓位。把「估计误差」和「杠杆约束」两道坑记在心里,Kelly 才是你资金曲线上最便宜的那道护栏。

本文数据与图表由 generate_kelly_criterion_images.py 用 numpy/scipy 从零计算(离散 G(f) 解析 + 连续策略蒙特卡洛),非占位图。把 musigmapb 换成你自己的策略统计,整套代码可直接复用。

Kelly 公式与资金管理:用分数凯利把收益与破产风险一起优化
https://blog.halo26812.eu.org/blog/kelly-criterion-sizing
Author halo
Published at 2026年7月11日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨