
用 Python 揭秘均值回归策略:你的收益从何而来?
2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含 500 篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!
很多做量化、学 Python 的同学都听过「凯利公式」,也都被建议过:别上全凯利,用「半凯利」(k = 0.5)就稳了。这几乎成了仓位管理里的「行业默认值」。
但「半凯利」真的对吗?答案是:它只在一种非常特定的条件下才正确。当你的策略统计证据不足时,半凯利可能让你的仓位整整大了 5 倍;而当你的策略已经被多年实盘验证时,半凯利又会让你白白错过收益。
这篇文章会用 Python 代码,带你一步步拆开凯利公式背后的数学,搞懂为什么「一个固定系数」根本无法同时解决两类完全不同的风险,并给出一套可以直接落地的「贝叶斯凯利」流程。代码全部带中文注释,适合一边读一边敲。
先回顾基础。假设资产价格服从带漂移 μ 和波动率 σ 的几何布朗运动,在 k 分数凯利下,对数财富的增长率为:
这个函数在 k = 1(全凯利)时取得最大值。我们用 Python 验证一下「半凯利捕获 75% 增长」这个经典结论:
def kelly_growth(k, mu, sigma):
"""计算 k 分数凯利下的对数财富增长率
k: 凯利分数,k = 1 为全凯利
mu: 预期收益(漂移项)
sigma: 波动率
"""
return k * (mu ** 2 / sigma ** 2) * (1 - k / 2)
# 假设年化预期收益 8%,波动率 20%
g_full = kelly_growth(1.0, 0.08, 0.20) # 全凯利
g_half = kelly_growth(0.5, 0.08, 0.20) # 半凯利
print(f"全凯利增长率: {g_full:.4f}")
print(f"半凯利增长率: {g_half:.4f}")
print(f"半凯利捕获比例: {g_half / g_full:.0%}") # 输出约 75%也就是说:半凯利只牺牲了 25% 的增长率,却能大幅降低回撤风险。再看回撤概率,无限期内财富跌破初始水平 b 倍的概率为:
def drawdown_prob(k, b=0.5):
"""无限期内财富曾经跌破初始水平 b 倍的概率
k: 凯利分数
b: 回撤水平,0.5 表示跌到只剩一半
"""
return b ** (2 / k - 1)
for k in [1.0, 0.5, 0.25]:
print(f"k = {k}: P(50% 回撤) = {drawdown_prob(k):.2%}")
# 输出:
# k = 1.0 -> 50.00%
# k = 0.5 -> 12.50%
# k = 0.25 -> 0.78%看到这里你可能觉得:半凯利真香。但这里有一个关键前提:上面所有漂亮的性质,都建立在 k 乘的是「真实凯利分数」f* = μ/σ² 之上。可现实里我们永远只有「估计凯利分数」f̂* = μ̂/σ²,因为 μ 是估出来的,不是已知的。
这是全文最核心的洞察。仓位管理其实要同时对付两类风险:
固定的「半凯利」用同一个系数 0.5 同时去糊这两个问题,结果是两个都没解决好。
举个对比就懂了:A 策略的 t 统计量是 0.5(几乎没有统计证据),B 策略的 t 统计量是 4.0(证据非常充分)。在传统半凯利下,两者都被砍成 k = 0.5。可它们的「优势可信度」天差地别,却用了一模一样的仓位系数,这显然不合理。
更要命的是,估计误差的代价远大于方差误差。研究表明,对数效用投资者的均值估计误差,其后果约是方差估计误差的 33 倍、协方差估计误差的 100 倍,量级大致是 100 : 3 : 1。也就是说,半凯利费劲去管的方差风险,恰恰是那个「小问题」;而真正的「大问题」估计风险,反而被一个不区分证据质量的固定系数草草打发了。
有一个非常优雅的等价关系:对收益估计乘以系数 k 做收缩后再上全凯利,等价于直接用 k 分数凯利。
换句话说,当你用半凯利时,你其实是在隐含地宣称:「我相信真实收益只有我估计值的 50%。」用四分之一凯利,就是在说「只信 25%」。
但问题是,这个收缩比例应该由统计证据决定,而不是拍脑袋定个 0.5。与统计证据一致的贝叶斯收缩因子是:
其中 t = SR × √T 是优势的 t 统计量(SR 为夏普比率,T 为样本年数),c 是「先验怀疑参数」。
把传统系数 k 与收缩因子对应起来,即 k = t² / (t² + c)。在标准默认值 c = 4 下解出来:
关键结论来了:在 c = 4 下,传统的 k ∈ [0.25, 0.5] 只对 t ∈ [1.15, 2.0] 的策略是贝叶斯一致的。如果你的策略 t = 1.0,贝叶斯最优仓位比半凯利小了约 5 倍;如果你的 t 远大于 2.0,半凯利又会让你下注不足。
c 的含义很直观:它是「你认为优势和没有优势可信度各占一半」时所对应的 t² 值。给三个可参考的档位:
一个实用原则:不确定时选更大(更保守)的 c。因为对真优势用了保守 c,后续数据会让 t 自然增大、收缩自然释放,错误可恢复;而对弱优势用了宽松 c,错误会随着每一笔交易不断累积。
整个流程分三步:算 t 统计量 → 做估计风险收缩 → 叠加方差风险控制。组合后作用在原始 f̂* 上的总乘数为:
其中 v 是方差风险控制系数,默认 v = 0.5(提供与传统半凯利相同的方差保护)。下面是完整实现:
import numpy as np
def bayesian_kelly(sr_live, T_years, c=4, v=0.5):
"""贝叶斯凯利仓位计算(完整三步流程)
参数:
sr_live : 实盘(年化)夏普比率
T_years : 实盘累计年数
c : 先验怀疑参数(1 宽松 / 4 标准 / 9 严格)
v : 方差风险控制系数,默认 0.5
返回:
t : 调整后的 t 统计量
shrinkage : 估计风险收缩因子
k_total : 作用在估计凯利分数上的总乘数
"""
# 第一步:计算 t 统计量
t = sr_live * np.sqrt(T_years)
# 短样本修正:T < 5 年时夏普估计标准误较大,做保守下调
if T_years < 5:
t = t * (1 - 1 / np.sqrt(2 * T_years))
# 第二步:估计风险收缩,t 越大越接近 1(越信任优势)
shrinkage = t ** 2 / (t ** 2 + c)
# 第三步:叠加方差风险控制,得到总乘数
k_total = v * shrinkage
return t, shrinkage, k_total
# 案例:不同夏普比率的策略,各自该上多大仓位
print(f"{'夏普':>4} | {'t值':>6} | {'收缩':>6} | {'k_total':>8}")
print("-" * 36)
for sr in [0.5, 1.0, 1.5, 2.0]:
t, s, k = bayesian_kelly(sr, T_years=4, c=4, v=0.5)
print(f"{sr:>4} | {t:>6.2f} | {s:>6.2f} | {k:>8.2f}")直接看一张参考表(c = 4,v = 0.5)就更清晰了——它揭示了一个被忽视的真相:
读法:随着实盘时间变长、表现被确认,t 增大,总乘数才逐渐升高、向半凯利靠拢。换句话说,传统半凯利(k = 0.5)应该是「优势被多年验证后才趋近的终点」,而不是每个新策略一上来就套用的「起点」。
假设某策略的实盘夏普从 1.5 一路衰减到 0.8(被市场「卷」掉了),我们看看贝叶斯凯利如何自动反应:
# 同样 5 年窗口,对比优势衰减前后的建议仓位
for sr in [1.5, 0.8]:
t, s, k = bayesian_kelly(sr, T_years=5, c=4, v=0.5)
print(f"夏普 = {sr}: t ≈ {t:.2f}, 收缩 ≈ {s:.2f}, k_total ≈ {k:.2f}")
# 夏普从 1.5 -> 0.8,k_total 会从约 0.37 自动降到约 0.22
# 而固定半凯利始终是 0.50:既在强优势期下注不足,
# 又在优势减弱时没能提供额外保护这正是固定半凯利的尴尬:它两头都不讨好。而贝叶斯凯利会随证据变化自动调整仓位,证据强就加、证据弱就减。
一个补充提醒(易错点):上面的回撤公式假设连续调仓、收益服从对数正态。如果你的策略收益是肥尾或有偏的,这个公式会低估真实回撤风险,此时应改用「带回撤概率上限的风险约束凯利」直接求解,而不是简单套用回撤公式。
这篇文章的核心结论可以浓缩成几句话:
t² / (t² + c) 做与证据匹配的估计风险收缩,再用固定的 v 做方差风险控制,得到 k_total = v · t²/(t²+c)。对学 Python 的你来说,最好的吸收方式就是把上面几个函数敲一遍、改改参数跑一跑,亲眼看看仓位是怎么随证据自动收放的。仓位管理不是玄学,它是一段可以写成代码、可以被验证的数学。
2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:
星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用
9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解
好书推荐