如果你问一个学金融的人”应该怎么构建投资组合”,十有八九会得到同一个答案:找一个均值方差有效前沿上的点,在你能承受的波动下最大化收益。这是 Markowitz 1952 年告诉我们的事,也是现代组合理论的基石。
但 Shefrin 和 Statman 在 2000 年提出了一个扎心的问题:真实投资者根本不这么干。 他们不会盯着一个”整体最优”的组合,而是把财富切成好几份,分别塞进”保本""养老""买房""博一把”这些心理上完全不同的账户里—而且每一份都用自己的规则管。这套理论叫 行为组合理论(Behavioral Portfolio Theory, BPT)。
本文要做三件事:把金字塔画出来、用 Python 把它跑出来、再把它和均值方差前沿做硬碰硬的数值对比,看看”非理性”的行为组合到底差在哪、又凭什么让人更满意。

一、心智账户:财富不是一整块,而是一层层#
传统理论假设投资者对 100 万只有”一个效用函数”。但行为学实验反复证明:同样 100 万,放在”紧急备用金”账户和”炒股”账户里,投资者的风险态度天差地别。这就是心理账户(mental accounting)。
BPT 把这种现象结构化成一座金字塔,从塔底到塔尖,每一层对应一个心理目标:
- 安全层(保本):绝对不能亏的底线,对应货基、国债、存款。
- 收入层(安稳):稳定现金流覆盖生活,对应高股息、债基、REITs。
- 成长层(增值):长期跑赢通胀,对应股票、股票基金。
- 投机层(致富):小概率博取极高收益,对应个股、期权、加密资产。
注意,这和我们熟悉的”风险平价""全天候”完全不同:各层之间不是按风险贡献分配,而是按”目标”分配。一个刚还完房贷的人,可能把 50% 放进安全层;一个想十年后换大房子的年轻人,可能把 40% 压在成长层。目标驱动,而非波动驱动。
二、Python 实战 1:构建金字塔并模拟四层净值#
先把这座金字塔变成可计算的对象,再模拟每一层在五年里的净值路径。关键代码:
import numpy as np
import pandas as pd
# 行为金字塔的四层:每层有独立的目标收益、可接受波动与资产池
layers = {
"安全层": {"target": 0.015, "max_vol": 0.01, "weight": 0.30,
"assets": ["货币基金", "国债", "存款"]},
"收入层": {"target": 0.045, "max_vol": 0.05, "weight": 0.20,
"assets": ["高股息", "债基", "REITs"]},
"成长层": {"target": 0.100, "max_vol": 0.18, "weight": 0.20,
"assets": ["宽基股", "股票基金"]},
"投机层": {"target": 0.220, "max_vol": 0.45, "weight": 0.30,
"assets": ["个股", "期权", "加密"]},
}
def simulate_layer(mu_a, vol_a, T=252 * 5, seed=0):
"""用几何随机游走模拟某一层的日度累积净值。"""
rng = np.random.default_rng(seed)
daily = rng.normal(mu_a / 252, vol_a / np.sqrt(252), T)
return np.cumprod(1 + daily)
paths = {name: simulate_layer(v["target"], v["max_vol"], seed=i)
for i, (name, v) in enumerate(layers.items())}
curve = pd.DataFrame(paths)
print("五年后各层累积净值 (起始=1):")
print(curve.iloc[-1].round(3))
print(f"\n整体组合 (按权重加权) 净值: "
f"{sum(layers[n]['weight'] * curve[n].iloc[-1] for n in layers):.3f}")python跑出来你会看到:安全层几乎是一条平滑向上的直线,投机层则大起大落。这正是行为组合想达成的效果—有些钱”必须安稳”,有些钱”可以冒险”,它们不该被混在一起用同一个夏普比率去优化。

三、Python 实战 2:行为组合 vs 均值方差前沿#
现在做最核心的对比。我们给定 6 个资产(对应金字塔各层的可投资产),用蒙特卡洛撒出大量随机组合,画出均值方差可行域与有效前沿;再把前面那座金字塔对应的权重标上去,看它落在哪。
# 六个资产的年化预期收益、波动与相关性(示意,对应金字塔各层资产)
mu = np.array([0.02, 0.04, 0.06, 0.09, 0.12, 0.20])
sig = np.array([0.01, 0.05, 0.10, 0.16, 0.24, 0.45])
corr = np.array([
[1.00, 0.30, 0.10, -0.05, -0.10, -0.15],
[0.30, 1.00, 0.45, 0.20, 0.10, 0.00],
[0.10, 0.45, 1.00, 0.55, 0.40, 0.20],
[-0.05,0.20, 0.55, 1.00, 0.75, 0.45],
[-0.10,0.10, 0.40, 0.75, 1.00, 0.65],
[-0.15,0.00, 0.20, 0.45, 0.65, 1.00],
])
cov = np.outer(sig, sig) * corr
# 行为金字塔组合权重(按各层目标收益反推的示范权重)
w_bpt = np.array([0.30, 0.20, 0.20, 0.18, 0.09, 0.03])
bpt_mu = w_bpt @ mu
bpt_vol = np.sqrt(w_bpt @ cov @ w_bpt)
# 蒙特卡洛包络:同样波动下 MV 能给出的最高收益(近似有效前沿)
rng = np.random.default_rng(20260710)
W = rng.dirichlet(np.ones(6), 8000)
P_mu, P_vol = W @ mu, np.sqrt(np.einsum("ij,jk,ik->i", W, cov, W))
front = {}
for v, m in zip(P_vol, P_mu):
k = round(v, 3)
front[k] = max(front.get(k, -9), m)
mv_same_vol = max([m for v, m in front.items() if abs(v - bpt_vol) < 0.01], default=None)
print(f"行为金字塔组合: 收益 {bpt_mu:.3f} / 波动 {bpt_vol:.3f}")
print(f"同样波动下 MV 最高收益: {mv_same_vol:.3f}")
print(f"被支配的收益差: {(mv_same_vol - bpt_mu) * 100:.2f} 个百分点")python
结论很”伤自尊”但很重要:在均值方差坐标系里,行为金字塔组合落在有效前沿的”内部”—同样波动下,Markowitz 能给你更高的收益。 也就是说,从纯数学角度,BPT 是”被支配”的、不是均值方差最优。
那它为什么还存在?因为它是目标最优,不是均值方差最优。投资者宁可接受一个”在 MV 意义上低效、但每一层都让我睡得着觉”的组合。量化圈常犯的错误,是用自己的效用函数去嘲笑别人的组合—而 BPT 提醒我们:效用函数本来就是因人而异、因账户而异的。
四、Python 实战 3:把”安全优先”变成可优化的目标#
BPT 不是只能”凭感觉分层”。Lopes 的 SP/A 理论(安全、潜力、期望)和 Roy 的”安全首要准则”给了我们一个可量化的抓手:先保证不跌破心理底线,再去追求上行。
Roy 安全首要比率(Safety-First Ratio)长这样:
其中 是投资者“无法接受的破产阈值”。但要小心:Roy 准则在纯多头、无约束时会退化为“全仓最安全资产”——因为安全资产波动极小,SFR 分子分母比最高。所以真实用法必须加约束。我们用 (投资者要求的最低年化回报,低于此则组合失败)加单资产上限 35% 做示范:
from scipy.optimize import minimize
R_min = 0.03 # 投资者要求的最低年化回报(低于此视为“失败”)
def neg_sfr(w):
w = np.clip(w, 0, 1); w /= w.sum()
mu_p = w @ mu
vol_p = np.sqrt(w @ cov @ w)
return -(mu_p - R_min) / vol_p # 取负,交给最小化
res = minimize(neg_sfr, x0=np.ones(6) / 6,
bounds=[(0, 0.35)] * 6, # 单资产上限:防止退化为全仓最安全资产
constraints=[{"type": "eq", "fun": lambda w: w.sum() - 1}])
w_sf = res.x
print("安全优先组合权重:", np.round(w_sf, 3))
print(f" 预期收益 {w_sf @ mu:.3f} / 波动 {np.sqrt(w_sf @ cov @ w_sf):.3f}")python你会发现:SFR 优化在“最低回报 3%”约束下,把低于该门槛的 2% 安全资产直接归零,并把权重显著压向中低波动资产(债券、高股息、宽基股),同时保留少量成长与投机敞口以达成目标——它本质上是在“不破产”和“有得赚”之间找平衡,和金字塔“先保底、再图进”的逻辑完全一致。这给了量化从业者一个桥接点:可以先用 BPT 确定各层目标,再用 SFR / CVaR 约束对每一层内部做优化,把行为逻辑翻译成可计算的约束条件。
五、行为组合理论的量化启示与陷阱#
把 BPT 真正用进量化框架,有几点必须说清:
1. 它不是”反量化”,而是”多目标量化”。 你可以把每一层当成一个子组合,各自设定目标收益、最大回撤、再平衡规则,然后按心理权重拼起来。这比强行追求一个全局夏普最大点,更能经得起实盘的心理考验。
2. 层间相关性常常被低估。 危机时”安全层”(国债)和”成长层”(股票)确实会此消彼长,但投机层往往和成长层高度同向—下跌时两层一起亏,心理账户的保护作用会被击穿。量化上要显式建模层间相关,尤其压力情景下的相关性抬升。
3. 目标会漂移,账户会”泄漏”。 牛市里人会把投机层越调越大(“我再赚点就收”),熊市里又恐慌性把成长层挪去安全层。行为组合的真实风险,往往不是模型风险,而是投资者自己改写了账户规则。做产品化时要加”目标锚定”和再平衡纪律。
4. 心智账户有真实代价。 把资金锁死在不同账户里,会损失跨账户的风险分散与税务/手续费优化。BPT 不是免费午餐,它用”可接受的次优”换取”可执行性”,这个 trade-off 必须向自己坦白。
小结#
行为组合理论最大的价值,不是证明 Markowitz 错了,而是告诉我们:“最优组合”如果不匹配投资者的心理目标,就只是纸面上的最优,实盘里会被恐惧和贪婪撕碎。 把财富切成金字塔、每层独立管理、用 SFR/CVaR 把”安全优先”翻译成硬约束—这才是行为金融能给量化带来的、可落地的那部分。
下一篇,我们聊聊另一类”非传统”的量化输入:怎么从网页里爬出文本、再把文本挖成信号。