仓位管理:分数凯利的实际用法
凯利公式给出的是长期复利增速最大的仓位,但它的前提是胜率和盈亏比精确已知——在加密市场这两个数都是带误差的估计值。实践中的正确用法是取满凯利的 1/4 到 1/2,或者干脆改用更简单的固定比例风险法:每笔交易的最大亏损不超过账户的 1%–2%。
本文要点
- 凯利仓位 f* = (p×b − q) / b,其中 p 是胜率、q=1−p、b 是盈亏比。
- 满凯利的理论最大回撤可以接近 100%,它优化的是增速而不是生存概率。
- 参数估计误差会被凯利放大:胜率高估 5 个百分点,实际仓位可能超过最优值一倍以上。
- 分数凯利取 1/4 时,理论增速约为满凯利的 44%,但回撤大幅下降,风险收益权衡明显更好。
- 固定比例风险法(单笔风险 1%–2%)不需要估计胜率盈亏比,是更稳健的默认选择。
凯利公式是什么
凯利公式回答一个具体问题:已知一个有正期望的重复性赌局,每次应该投入总资金的百分之几,才能让长期复利增长速度最快。
二元形式(要么赢 b 倍、要么亏掉本金)下的公式是 f* = (p×b − q) / b,其中 p 是胜率,q = 1 − p,b 是盈亏比(平均盈利除以平均亏损)。举个数:胜率 55%、盈亏比 1.5,则 f* = (0.55×1.5 − 0.45) / 1.5 = 0.25,即每次投入 25% 资金。
注意公式的两个含义。一是期望为负时 f* 为负,数学在告诉你不要下注,任何仓位都会导致长期归零。二是它优化的目标是对数收益的期望,也就是几何增长率,而不是算术平均收益——这个区别是理解后面所有问题的钥匙。
def kelly_binary(p: float, b: float) -> float:
"""二元凯利: p 胜率, b 盈亏比(平均盈利/平均亏损)
返回建议投入的资金比例, 负值表示不应下注
"""
q = 1.0 - p
return (p * b - q) / b
def kelly_from_trades(returns) -> float:
"""从历史成交收益率序列估凯利。
returns: 每笔交易的收益率, 如 [0.03, -0.01, 0.05, ...]
"""
r = [x for x in returns if x == x]
wins = [x for x in r if x > 0]
losses = [-x for x in r if x < 0]
if not wins or not losses:
return 0.0
p = len(wins) / len(r)
b = (sum(wins) / len(wins)) / (sum(losses) / len(losses))
return kelly_binary(p, b)
def growth_rate(f: float, p: float, b: float) -> float:
"""给定下注比例 f 的对数增长率(每笔期望)"""
import math
if f <= 0 or f >= 1:
return float("-inf")
return p * math.log(1 + f * b) + (1 - p) * math.log(1 - f)
for p, b in ((0.55, 1.5), (0.45, 2.0), (0.60, 1.0), (0.50, 1.2)):
f = kelly_binary(p, b)
print(f"p={p:.2f} b={b:.1f} -> 满凯利 {f:.1%}, "
f"1/4 凯利 {f/4:.1%}")
# p=0.55 b=1.5 -> 满凯利 25.0%, 1/4 凯利 6.2%
# p=0.45 b=2.0 -> 满凯利 17.5%, 1/4 凯利 4.4%
# p=0.60 b=1.0 -> 满凯利 20.0%, 1/4 凯利 5.0%
# p=0.50 b=1.2 -> 满凯利 8.3%, 1/4 凯利 2.1%
python
为什么满凯利在加密市场等于迟早爆仓
满凯利在数学上是对的,但它的正确性建立在三个前提上,而加密市场把这三个前提全部破坏了。
前提一:p 和 b 精确已知。赌场里骰子的概率是已知的,市场里胜率只能靠历史估计。100 笔交易估出的胜率,标准误约为 5 个百分点。用 55% 代替真实的 50%,算出的仓位就从 8.3% 变成 25%,超出最优值三倍。凯利对参数误差极为敏感,而且误差方向总是偏向过度下注。
前提二:分布稳定。凯利假设每次赌局条件相同。市场制度会变——牛市里有效的动量策略在震荡市胜率会下降十几个百分点,而你的 f* 还是按牛市数据算的。
前提三:可以承受极端回撤。这是最要命的一条。满凯利策略的理论最大回撤可以趋近 100%,因为它只优化长期增速,完全不约束路径。一条数学上「最优」的曲线可能包含一次 80% 的回撤——账户理论上能恢复,但杠杆账户在到达那里之前就已经被强制平仓,人也早就停手了。
分数凯利:拿走大部分增速,扔掉大部分回撤
分数凯利的做法极简:算出 f* 之后乘一个小于 1 的系数,常用 1/4 到 1/2。它之所以有效,是因为凯利的增长率函数在最优点附近相当平坦,而回撤对仓位近似线性——减半仓位只损失约四分之一的增速,却把回撤也大致减半。
这个不对称性是分数凯利的全部理由。用 f = f*/2 时,理论增长率约为满凯利的 75%;用 f = f*/4 时约为 44%。但对应的回撤幅度下降得更多,破产风险下降的幅度更大。在参数本身带误差的现实条件下,这笔交换几乎总是划算的。
还有一个常被忽略的好处:分数凯利提供了对参数高估的容错。如果你把胜率高估了,f*/4 可能恰好落在真实最优值附近;而满凯利在同样的高估下已经进入过度下注区间——那个区间里增长率是负的,下注越多亏越快。
| 凯利系数 | 单笔投入资金比例 | 单笔账户风险 | 相对增速(理论) | 模拟最大回撤区间 | 评价 |
|---|---|---|---|---|---|
| 满凯利 f* | 25.0% | 1.25% | 100% | 60% – 85% | 数学最优,实践中不可执行 |
| 1/2 凯利 | 12.5% | 0.63% | 约 75% | 30% – 50% | 激进但可考虑,需高度确信参数 |
| 1/3 凯利 | 8.3% | 0.42% | 约 60% | 22% – 38% | 较常见的折中选择 |
| 1/4 凯利 | 6.2% | 0.31% | 约 44% | 15% – 28% | 推荐起点,容错空间充足 |
| 1/10 凯利 | 2.5% | 0.13% | 约 20% | 6% – 12% | 过度保守,资金效率偏低 |
| 2 倍凯利 | 50.0% | 2.50% | 负值 | > 90%,趋于归零 | 过度下注区,长期必然亏损 |
表格最后一行值得停下来看。下注比例超过满凯利的两倍时,长期增长率变为负数——即使每一笔交易的期望都是正的。这就是「策略有效但仍然亏钱」最常见的原因:不是信号不行,是仓位太重。
上表回撤区间来自蒙特卡洛模拟的示例范围,具体数值依赖收益分布假设,仅用于展示不同系数之间的相对关系,不代表任何实际策略的历史表现或未来预期。
更实用的替代:固定比例风险法
在实际交易中,多数人最终会用固定比例风险法而不是凯利,原因很实在:它不需要估计胜率和盈亏比这两个不可靠的量。
规则一句话:每笔交易的最大亏损固定为账户权益的 1%–2%。先确定入场价和止损价,两者的距离就是单位风险,用允许亏损金额除以单位风险,得到应该买多少。仓位大小由止损距离反向推导,而不是拍一个百分比。
这个方法有三个凯利没有的优点。一是自适应波动率:波动大时止损距离宽,算出的仓位自动变小。二是风险上限确定:连续亏 10 笔,账户损失约 10%–20%,不会出现失控。三是不需要任何统计估计,只需要你能定出止损位。
def size_by_fixed_risk(equity: float, entry: float, stop: float,
risk_pct: float = 0.01,
min_qty: float = 0.0,
qty_step: float = 0.0) -> float:
"""固定比例风险法计算下单量。
equity : 当前账户权益
entry : 预期入场价
stop : 止损价
risk_pct : 单笔可承受亏损占权益比例 (0.01 = 1%)
"""
per_unit_risk = abs(entry - stop)
if per_unit_risk <= 0:
return 0.0
qty = (equity * risk_pct) / per_unit_risk
# 交易所精度约束: 不满足就不下单, 而不是四舍五入放大
if qty_step > 0:
qty = (qty // qty_step) * qty_step
return qty if qty >= min_qty else 0.0
def atr_stop(entry: float, atr: float, side: int = 1,
k: float = 2.0) -> float:
"""按 ATR 倍数设止损, 使止损距离随波动率自适应"""
return entry - side * k * atr
# 示例: 10000 USDT 账户, 单笔风险 1%
eq, entry, atr = 10_000.0, 60_000.0, 1_200.0
stop = atr_stop(entry, atr, k=2.0) # 57600
qty = size_by_fixed_risk(eq, entry, stop, 0.01)
print(f"止损 {stop:,.0f}, 下单 {qty:.4f} BTC, "
f"名义 {qty*entry:,.0f} USDT, "
f"最大亏损 {qty*(entry-stop):,.0f} USDT")
# 止损 57,600, 下单 0.0417 BTC, 名义 2,500 USDT, 最大亏损 100 USDT
python
两种方法怎么选:一张对照表
分数凯利和固定比例风险法不是对立关系,它们回答的是不同问题。凯利问「这条策略值得给多少权重」,固定比例风险法问「这一笔最多能亏多少」。前者依赖对策略质量的统计估计,后者只依赖你能定出止损位。
实践中的常见组合是:用固定比例风险法算出基准仓位,再用分数凯利作为权重调整——对经过完整验证、样本外表现稳定的策略给 1.5% 的单笔风险,对刚上线观察期的策略给 0.5%。最终仓位取两种方法算出的较小值,这样任何一方的估计错误都不会单独造成失控。
| 维度 | 分数凯利 | 固定比例风险法 |
|---|---|---|
| 需要的输入 | 胜率 p、盈亏比 b(需 100 笔以上样本) | 入场价与止损价 |
| 估计误差敏感度 | 高,胜率偏差 5% 可致仓位偏差成倍 | 低,不涉及统计估计 |
| 波动率自适应 | 否,除非重新估参数 | 是,止损宽则仓位自动变小 |
| 最坏情况可控性 | 取决于系数,满凯利下不可控 | 明确,连亏 10 笔约损失 10%–20% |
| 适用场景 | 已验证、样本充足的成熟策略 | 新策略、多策略并行、默认选择 |
| 主要缺点 | 参数不准时会系统性过度下注 | 不区分策略优劣,资金效率略低 |
如果只能记住一条:先用固定比例风险法把生存问题解决掉,再考虑用凯利提高效率。顺序反过来的人,通常在有机会体会到凯利的复利优势之前,账户就已经不在了。
组合层面的风险预算
单笔 1% 只解决了单笔问题。同时持有多个仓位时,真实风险是它们的相关性加权之和,而不是简单相加。加密市场的特殊性在于:下跌时几乎所有币种的相关性都趋近 1,平时看起来分散的五个仓位,在暴跌日就是同一笔风险。
所以要在组合层面加三道约束。第一是总风险上限:所有未平仓位的止损同时触发时,账户总损失不超过 4%–6%。按单笔 1% 算,即最多同时持 4 到 6 个仓位。第二是相关性去重:把高度同向的品种视为一个仓位,山寨币与 BTC 的相关性常在 0.8 以上,不应各占一份独立额度。
第三是回撤刹车:账户从峰值回撤达到某个阈值时自动降低风险预算。例如回撤 10% 后把单笔风险从 1% 降到 0.5%,回撤 20% 后暂停开新仓。这条规则的作用不只是数学上的,它还替代了你在最难受时刻的临场判断——那时候的判断通常最糟。
- 单笔风险:账户权益的 1%–2%,由止损距离反推仓位。
- 同时持仓数:4–6 个,使总风险敞口控制在 6% 以内。
- 相关性去重:相关性 > 0.7 的品种共享一份风险额度。
- 回撤刹车:回撤 10% 减半风险,回撤 20% 停止开新仓。
- 杠杆上限:先在无杠杆条件下验证策略,杠杆只能是最后一步且需重新评估强平距离。
最后一条不是保守建议而是顺序问题。杠杆不改变策略的期望收益率,只放大波动和爆仓概率。一条在无杠杆下期望为负的策略,加杠杆只会让归零来得更快。仓位管理的作用是让一条有效策略活得足够久,它不能把无效策略变成有效——策略是否有效要靠Walk-Forward 验证和含成本复核来判断,相关成本量级见手续费与滑点建模。
什么是常见问题?
凯利公式算出来是负数,说明什么?
说明按你估计的胜率和盈亏比,这个策略的期望为负,任何正仓位都会导致长期资金衰减。此时应该做的是修正策略或放弃,而不是减小仓位继续跑——减小仓位只是让亏损变慢,不会让它变成盈利。
胜率和盈亏比该用多少笔交易来估?
至少 100 笔,且要来自样本外或 Walk-Forward 的测试段,不能用调参时的样本内数据。100 笔时胜率的标准误约 5 个百分点,这个误差在凯利公式里会被放大成仓位的成倍偏差,这也正是必须打折使用的原因。
分数凯利和固定比例风险法能同时用吗?
可以,而且常见做法是取两者的较小值。用凯利判断这条策略值不值得给较高权重,用固定比例风险法给出硬性上限,最终仓位取二者中更小的那个。这样既保留了对策略质量的区分,又保证了单笔风险不会失控。
账户很小(比如 1000 USDT)也要按 1% 风险吗?
按 1% 意味着单笔只能亏 10 USDT,很多品种的最小下单量会让你无法执行。这种情况下更现实的做法是先只交易一个品种、把单笔风险放宽到 2%–3%,并且明确认识到小账户的主要目标是验证流程和测量实盘偏差,不是获取收益。切忌用加杠杆的方式来凑最小下单量。