状态切换凯利下注:让仓位在牛熊之间自动收放
凯利公式给出理论最优杠杆,但它假设赔率恒定——市场偏偏在牛熊两套参数间来回切。本文用纯 numpy 合成两状态市场(转移矩阵 P、牛市 μ=+0.09%/σ=0.9%、熊市 μ=-0.16%/σ=2.4%),先用 HMM 前向算法在线滤出熊市后验概率(识别准确率 95%),再把凯利分数按后验期望在牛熊之间加权收放。回测对决:固定半凯利与买入持有几乎重叠(总收益 25%、Sharpe 0.24、最大回撤 -64%),而状态切换凯利总收益 77%、Sharpe 0.52、最大回撤压到 -32%——收益翻三倍、回撤砍半,核心不是预测方向而是在熊市把杠杆主动收回甚至反手。全文诚实拆穿:凯利分数对参数估计误差极度敏感(牛市理论 f*=11 必须靠半凯利+CAP 硬压)、在线滤波天然滞后(状态切换后要几天才反应,切点附近必吃亏)、状态数与转移矩阵是先验强假设、样本外真实市场没有干净的两状态结构四类陷阱(中高阶)。
先说结论:凯利公式算的是”赔率固定时下多少注”,但市场的赔率不是固定的——它在牛市和熊市两套参数间反复横跳。把一个固定杠杆焊死在账户上,等于用牛市的胆量去接熊市的刀。本文的实验会证明:同样一套凯利逻辑,固定下注和买入持有几乎跑成一条线(总收益 25%、最大回撤 -64%),而让下注比例跟着”现在是牛是熊”的后验概率自动收放之后,总收益 77%、最大回撤压到 -32%——多出来的钱不来自预测涨跌,来自熊市里主动把杠杆收回去。但这套东西对参数估计误差极度敏感,用不好就是加速破产的杠杆放大器。
一、凯利公式:理论最优,但有一个致命假设#
凯利公式的核心是最大化长期对数增长率,而不是单期期望收益。对于连续收益的近似形式,最优下注比例是:
其中 μ 是资产的期望收益,σ² 是方差。直觉很清楚:预期回报越高、波动越小,就该押得越重。对数增长率随下注比例的变化曲线是一条开口向下的抛物线,顶点就在 f* 处:

上图是关键。绿线是牛市参数下的 g(f),红线是熊市参数下的 g(f)。看两条曲线的顶点位置:牛市的最优下注在正区间(该做多),熊市的最优下注在负区间(该做空或至少空仓)。如果你用牛市参数算出的 f* 去跑整段行情,那么每次进入熊市,你都停在红线的右侧——一个 g(f) 深度为负的位置,也就是在以最快速度亏钱。
这就是固定凯利的致命假设:它默认 μ 和 σ 永远不变。而真实市场最稳定的特征恰恰是”参数会变”。
二、两状态市场:用马尔可夫链造一个会切换的世界#
要验证这件事,我先造一个诚实的、参数确实会切换的市场。用一个两状态隐马尔可夫模型:
- 状态 0(牛市):日均值 μ=+0.09%,日波动 σ=0.9%
- 状态 1(熊市):日均值 μ=-0.16%,日波动 σ=2.4%
- 状态转移矩阵 P:牛市粘性 0.992(平均持续 125 天),熊市粘性 0.97(平均持续 33 天)
import numpy as np
np.random.seed(42)
T = 2000
P = np.array([[0.992, 0.008], # 牛市 -> [牛, 熊]
[0.030, 0.970]]) # 熊市 -> [牛, 熊]
mu = np.array([0.0009, -0.0016])
sig = np.array([0.009, 0.024])
states = np.zeros(T, dtype=int)
for t in range(1, T):
states[t] = np.random.choice(2, p=P[states[t-1]])
rets = np.random.normal(mu[states], sig[states])
price = 100 * np.cumprod(1 + rets)python这段代码里熊市天数占比约 23%。注意熊市的波动(2.4%)是牛市(0.9%)的近 3 倍——这符合现实的波动率聚集特征:跌的时候不但方向不对,晃动还更剧烈。

红色阴影就是熊市段。价格在牛市里稳步爬升,一进熊市就大幅回吐。肉眼都能看出,能不能在阴影区把仓位收回来,是这条曲线赚钱还是亏钱的分水岭。
三、在线滤波:用前向算法实时估计”现在是熊市的概率”#
问题来了:真实交易里你看不到 states 数组,只能看到收益序列。你得反过来从收益推断当前状态。这就是 HMM 的滤波问题——用前向算法在线估计状态后验概率。
关键在于”在线”:每天只用截至今天的信息更新后验,绝不偷看未来。前向递推分两步——先用转移矩阵做状态预测,再用当天收益的观测似然做贝叶斯更新:
def gaussian_pdf(x, m, s):
return np.exp(-0.5*((x-m)/s)**2) / (s*np.sqrt(2*np.pi))
alpha = np.zeros((T, 2))
alpha[0] = np.array([0.5, 0.5]) * gaussian_pdf(rets[0], mu, sig)
alpha[0] /= alpha[0].sum()
for t in range(1, T):
pred = alpha[t-1] @ P # 用转移矩阵预测今天的先验
emis = gaussian_pdf(rets[t], mu, sig) # 今天收益的观测似然
a = pred * emis # 贝叶斯更新
alpha[t] = a / a.sum()
p_bear = alpha[:, 1] # 熊市后验概率pythonalpha[t] 是归一化后的后验分布,p_bear 就是”今天处于熊市的概率”。这个滤波器的识别准确率(后验 >0.5 判熊市,与真实状态比对)达到 95%。

灰色块是真实熊市,红线是滤波器估的熊市后验概率。整体贴合得很好,但请盯住每一个切换点:真实状态从牛翻熊的瞬间,红线不会同步跳到 1,而是需要几天累积证据才爬上去。这个滞后不是 bug,是在线滤波的物理下限——你只有在坏消息发生之后才能确认坏消息。这几天的滞后,就是这套策略必然要交的学费,后面会算这笔账。
四、把凯利分数按后验概率加权#
现在把两块拼起来。每个状态有自己的凯利分数:
f_bull = mu[0] / sig[0]**2 # 牛市理论凯利 ≈ 11.1
f_bear = mu[1] / sig[1]**2 # 熊市理论凯利 ≈ -2.8python注意牛市理论凯利高达 11 倍杠杆——这是全凯利的通病:它算出的杠杆在现实中大到荒谬,因为它假设你对 μ、σ 的估计完全精确。任何估计误差都会被平方项放大成灾难。所以实务上必须用半凯利(乘 0.5)再加一个硬上限 CAP=1.0:
HALF, CAP, FLOOR = 0.5, 1.0, -0.5
def clip_f(f, floor=0.0):
return np.clip(f * HALF, floor, CAP)
# 状态切换凯利:用后验概率对两状态凯利做加权
f_dynamic = clip_f(p_bear * f_bear + (1 - p_bear) * f_bull, floor=FLOOR)
# 对照:固定半凯利(假设永远是牛市),忽略状态
f_static = clip_f(f_bull)pythonf_dynamic 的逻辑是:熊市概率越高,凯利仓位越往负区间收——从满仓做多,逐渐降到空仓,极端时反手做空(FLOOR=-0.5 允许适度做空)。

蓝线是动态仓位,橙色虚线是固定半凯利(永远顶格)。红色阴影是熊市。可以看到动态仓位在阴影区大幅下沉甚至转负,而固定策略始终焊死在上限——这就是全部差异的来源。
五、回测对决:收益翻三倍,回撤砍半#
用严格的次日执行(signal-on-t、execute-on-t+1,绝不用当天信号赚当天收益)跑三条曲线:
def equity(frac_arr):
eq = np.ones(T)
for t in range(1, T):
f = frac_arr[t-1] # 昨天收盘定的仓位
eq[t] = eq[t-1] * (1 + f * rets[t]) # 吃今天的收益
return eqpython| 策略 | 总收益 | 年化 Sharpe | 最大回撤 |
|---|---|---|---|
| 状态切换凯利 | +77.3% | 0.52 | -32.3% |
| 固定半凯利 | +25.2% | 0.24 | -63.6% |
| 买入持有 | +25.2% | 0.24 | -63.6% |

固定半凯利和买入持有几乎完全重叠——因为顶格满仓的半凯利本质就是”一直满仓”,跟买入持有没区别。真正拉开差距的是蓝线:它没有更会预测涨跌,它只是在熊市里认怂。收益翻三倍的表象之下,真正的功臣是最大回撤从 -64% 压到 -32%——回撤小了,复利的底子就没被打断,长期增长率自然更高。这正是凯利公式的初心:最大化长期增长的关键是活下去,而不是每一注都押满。
A. 实现细节#
- 信号字段:只用每日收益
rets[t]喂给前向滤波器,估出熊市后验p_bear[t]。仓位由后验对两状态凯利加权得出,绝不使用未来数据。 - 执行时点:严格次日执行。
t日收盘算出的仓位f_dynamic[t],用于捕获t+1日的收益。代码里用frac_arr[t-1] * rets[t]保证不偷看。 - 仓位口径:
f是账户净值的杠杆倍数。CAP=1.0 表示最多满仓(不加杠杆),FLOOR=-0.5 表示最多用半仓做空。半凯利系数 0.5 是抵御参数估计误差的安全边际。 - 凯利分数:用连续收益近似
f* = μ/σ²,而非离散赔率版凯利。这在日频小收益下是标准近似。 - 权益曲线口径:单资产、含杠杆、含做空、无交易成本的纯理论净值,用于隔离”状态切换”这一个变量的贡献。
B. 已知偏差#
- 参数已知是最大作弊:本文把真实的 μ、σ、转移矩阵 P 直接喂给了滤波器。真实市场里这三组参数都得从历史数据估计,且会随时间漂移。全凯利理论值 f*=11 的荒谬程度已经说明:凯利分数对 μ 的估计误差是平方级敏感,μ 估高一倍,杠杆就错到离谱。这也是为什么实务只敢用半凯利甚至四分之一凯利。
- 在线滤波必然滞后:第三节图里每个切换点的滞后是硬约束。状态真正翻转后,滤波器要累积几天证据才反应过来,这几天你还停在错误仓位上挨打。回测收益已经包含了这部分损失——它是净值,不是理论上限。
- 两状态是强先验:真实市场不止牛熊两态(还有震荡市、危机市、复苏市……),也没有干净的马尔可夫转移结构。状态数选错、转移矩阵设错,滤波器会系统性误判。
- 无交易成本:动态仓位每天都在微调,换手率远高于买入持有。真实的手续费和冲击成本会侵蚀相当一部分超额收益,尤其在仓位频繁反复的震荡段。
C. 结果解读#
超额收益的真正来源是回撤控制,不是选股或择时的方向能力。 看指标:两个策略的年化 Sharpe 从 0.24 提升到 0.52,翻了一倍多,但这不是靠多抓了几个涨停,而是靠在 23% 的熊市天数里把仓位收回来,避免了 -64% 那种伤筋动骨的回撤。复利数学的残酷在于:亏 50% 需要涨 100% 才能回本,把最大回撤从 64% 压到 32%,等于把”回本所需涨幅”从 178% 降到 47%——这才是总收益从 25% 跳到 77% 的底层原因。
滞后决定了这套策略吃不到拐点,只吃得到趋势中段。 从后验概率图能看出,滤波器在熊市中段最自信、仓位收得最狠,但在牛熊切换的头几天总是慢半拍。所以它赚的不是”精准逃顶抄底”的钱,而是”确认熊市后不再挨打、确认牛市后重新上仓”的钱。任何宣称能靠状态切换精准抓拐点的说法,都违背在线滤波的物理下限。
这套框架的实盘生死线在参数估计,不在模型结构。 本文用已知参数得到的漂亮结果,是这套方法的上限而非期望。真实部署时,μ 的估计噪声会让凯利分数剧烈抖动,稍不留神半凯利就变成过度杠杆。稳健的做法是:用滚动窗口估参数、用远低于理论值的凯利系数(1/4 或更低)、给转移矩阵加正则、并在样本外用 walk-forward 反复验证状态识别的稳定性。凯利公式是放大器——放大你的优势,也放大你估参数的错误。 在你确认自己真能估准牛熊参数之前,它更可能是加速破产的杠杆,而不是通往最优增长的捷径。