3. 经典最优投资问题:Merton问题简介,从连续时间金融到随机控制
好,咱们今天聊一个在量化金融里绕不开的经典问题——Merton问题。
说实话,我刚入行那会儿,觉得这东西就是纯理论,离实战很远。直到后来做资产配置策略,发现很多看似高深的模型,底层逻辑都跟Merton那套框架脱不了干系。你想想看,一个投资者,手里有笔钱,怎么在股票和债券之间分配,才能让未来某个时间点的效用最大化?这就是Merton问题的核心。
3.1 从离散到连续:为什么我们要跳进连续时间?
传统的投资组合理论,比如Markowitz的均值-方差模型,是在单期框架下玩的。你决定好权重,然后等着期末算账。但现实世界不是这样的。市场每分每秒都在波动,你的仓位可以随时调整。
我个人习惯把这个问题想成一个“动态决策”过程。你今天觉得股票好,买了80%仓位,明天暴跌了,你怎么办?是死扛还是止损?连续时间金融就是允许你“随时”做这个决策。
Merton在1969年和1971年的两篇论文里,把这个动态问题给数学化了。他假设市场是连续的,股票价格服从几何布朗运动,投资者可以无摩擦地连续交易。嗯,这里要注意,连续交易在现实中是不可能的,但数学上它给了我们一个漂亮的解析解。
3.2 数学框架:状态变量与控制变量
咱们先把数学架子搭起来。假设有两种资产:
- 无风险资产(债券):价格B(t)满足 dB = rB dt,r是无风险利率。
- 风险资产(股票):价格S(t)满足 dS = μS dt + σS dW,μ是预期收益率,σ是波动率,W是标准布朗运动。
投资者的财富过程W(t)可以写成:
dW = [rW + π(μ - r)W - c] dt + πσW dW
这里π是投资于股票的比例,c是消费率。这个方程说白了就是:财富的变化 = 投资收益 + 风险暴露 - 花掉的钱。
目标函数是最大化期望效用:
J(W, t) = max E[ ∫₀ᵀ e^{-ρs} U(c(s)) ds + e^{-ρT} U(W(T)) ]
其中ρ是主观贴现率,U(·)是效用函数。最常用的效用函数是CRRA(常数相对风险厌恶):
U(c) = c^{1-γ} / (1-γ)
γ是风险厌恶系数。γ越大,你越不愿意冒险。
3.3 HJB方程:随机控制的核心工具
解决这类动态优化问题,靠的是HJB方程(Hamilton-Jacobi-Bellman)。这个名字听起来吓人,其实思路很简单:
“你今天做的决策,不仅要考虑今天的效用,还要考虑这个决策对未来财富的影响。”
数学上,HJB方程长这样:
ρV = max_{c, π} [ U(c) + V_t + (rW + π(μ-r)W - c)V_W + 0.5 π²σ²W² V_WW ]
V(W, t)是值函数,表示在财富W、时间t时的最大期望效用。V_t、V_W、V_WW分别是V对时间和财富的偏导数。
这个方程怎么解?先对c和π求一阶条件,得到最优控制表达式,然后代回方程,解出V的具体形式。
对于CRRA效用函数,我们可以猜解V的形式为:
V(W, t) = e^{-βt} W^{1-γ} / (1-γ) * g(t)
然后代入HJB方程,得到g(t)的常微分方程。最终解出来,最优投资比例是常数:
π* = (μ - r) / (γ σ²)
这个公式漂亮吧?它告诉你,最优风险资产配置比例,等于超额收益除以风险厌恶乘以方差。说白了,就是夏普比率除以风险厌恶。
3.4 知识体系结构图
下面这张图帮你理清Merton问题的知识脉络:
3.5 代码实现:数值求解Merton问题
理论讲完了,咱们来点实际的。下面这个Python代码演示了如何用有限差分法数值求解HJB方程。说实话,解析解只在CRRA效用下存在,换了其他效用函数就得靠数值方法。
import numpy as np
import matplotlib.pyplot as plt
# 参数设置
gamma = 3.0 # 风险厌恶系数
rho = 0.05 # 主观贴现率
r = 0.03 # 无风险利率
mu = 0.08 # 股票预期收益率
sigma = 0.20 # 股票波动率
T = 10.0 # 投资期限
# 网格参数
W_max = 10.0 # 最大财富
N_W = 100 # 财富网格点数
N_T = 1000 # 时间网格点数
# 网格
W = np.linspace(0, W_max, N_W)
dt = T / N_T
# 值函数初始化(终端条件:V(W,T) = W^(1-gamma)/(1-gamma))
V = np.zeros((N_W, N_T+1))
V[:, -1] = W**(1-gamma) / (1-gamma)
# 有限差分求解(隐式格式)
for n in range(N_T-1, -1, -1):
# 对每个财富点,求解最优控制
for i in range(1, N_W-1):
# 计算偏导数(中心差分)
V_W = (V[i+1, n+1] - V[i-1, n+1]) / (2 * (W[1]-W[0]))
V_WW = (V[i+1, n+1] - 2*V[i, n+1] + V[i-1, n+1]) / (W[1]-W[0])**2
# 最优投资比例(来自一阶条件)
pi_star = (mu - r) * V_W / (gamma * sigma**2 * W[i] * V_WW + 1e-10)
pi_star = np.clip(pi_star, 0, 1) # 限制杠杆
# 最优消费(来自一阶条件)
c_star = (V_W)**(-1/gamma)
# HJB方程更新
V[i, n] = V[i, n+1] + dt * (
c_star**(1-gamma)/(1-gamma) +
(r*W[i] + pi_star*(mu-r)*W[i] - c_star) * V_W +
0.5 * pi_star**2 * sigma**2 * W[i]**2 * V_WW -
rho * V[i, n+1]
)
# 边界条件
V[0, n] = V[1, n] # W=0时,值函数平坦
V[-1, n] = V[-2, n] # 上边界
# 结果可视化
plt.figure(figsize=(10, 6))
plt.plot(W, V[:, 0], 'b-', linewidth=2, label='数值解 V(W,0)')
plt.plot(W, W**(1-gamma)/(1-gamma) * np.exp(-rho*T), 'r--', label='解析解(近似)')
plt.xlabel('财富 W')
plt.ylabel('值函数 V')
plt.title('Merton问题数值解 vs 解析解')
plt.legend()
plt.grid(True)
plt.show()
3.6 实战中的坑与反思
Merton问题虽然漂亮,但直接套用到实盘会出问题。我总结几个常见的坑:
- 参数估计误差:μ和σ的估计误差会直接传导到π*上。我建议用滚动窗口估计,或者加贝叶斯先验。
- 交易成本:Merton假设无摩擦交易,但现实中买卖价差、佣金都会影响最优策略。我曾经在回测中加了10个基点的交易成本,最优π*就降了5%。
- 跳跃风险:几何布朗运动假设价格连续,但市场有跳跃。2008年金融危机时,很多用Merton模型做配置的基金都亏惨了。
- 消费平滑:模型假设消费可以连续调整,但现实中消费有惯性。你不可能今天消费100万,明天消费10块。
嗯,说了这么多,其实就想表达一个意思:Merton问题是一个极好的理论起点,但实战中需要做大量调整。我个人习惯把它当作基准,然后在这个基础上加各种现实约束。
最后,记住那个简洁的公式:π* = (μ - r) / (γ σ²)。它背后蕴含的直觉——风险溢价除以风险厌恶乘以风险——是所有资产配置策略的底层逻辑。
公众号:蓝海资料掘金营,微信deep3321