最大夏普组合 · 切线组合
直觉
有效前沿上夏普比率最高的那一点,叫切线组合(tangency portfolio)——从无风险利率画一条线(资本配置线 CAL)与前沿相切,切点就是它。它是「风险资产的最优组合」:任何理性投资者都应持有切线组合 + 无风险资产的某种比例(两基金分离定理)。
闭式解
切线组合权重有解析解(设无风险利率 ):
(此处 为超额收益;为简洁取 。)
「人话」解释:CAL 与切点
无风险资产(波动为 0、收益 )是纵轴上一个点。把它和风险组合连线,斜率就是该组合的夏普比率。 斜率最大的那条线(CAL)恰好相切于有效前沿——切点即切线组合,夏普最大。 切线组合 + 无风险借贷,能实现 CAL 上任意风险-收益点,比单纯持有前沿更优。
可运行案例:切线组合与资本配置线
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('/data/multi_asset_daily.csv', parse_dates=['date']).set_index('date')
assets = ['equity', 'bond', 'commodity', 'reit']
R = np.log(df[assets] / df[assets].shift(1)).dropna()
mu = R.mean().values * 252
S = R.cov().values * 252
n = len(assets)
invS = np.linalg.inv(S); ones = np.ones(n)
rf = 0.0
# 切线组合闭式解
w_tan = invS @ mu / (ones @ invS @ mu)
sr = (w_tan @ mu - rf) / np.sqrt(w_tan @ S @ w_tan)
tan_v, tan_r = np.sqrt(w_tan @ S @ w_tan), w_tan @ mu
print("切线组合权重(最大夏普):", dict(zip(assets, np.round(w_tan, 3))))
print(f"夏普 = {sr:.3f}")
# 画前沿 + CAL + 切点
def frontier_weights(target):
A = np.vstack([mu, ones]).T
M = np.block([[S, A], [A.T, np.zeros((2, 2))]])
return np.linalg.solve(M, np.concatenate([np.zeros(n), [target, 1.0]]))[:n]
grid = np.linspace(mu.min(), mu.max(), 60)
fv = [np.sqrt((w:=frontier_weights(t)) @ S @ w) for t in grid]
fr = [frontier_weights(t) @ mu for t in grid]
vol_grid = np.linspace(0, np.max(np.sqrt(np.diag(S))) * 1.3, 50)
plt.figure(figsize=(8, 4.5))
plt.plot(vol_grid, rf + sr * vol_grid, 'r--', lw=1.3, label='资本配置线(CAL)')
plt.plot(fv, fr, color='#2563eb', lw=1.4, label='有效前沿')
plt.scatter([tan_v], [tan_r], color='crimson', s=65, zorder=5, label='切线组合')
plt.xlabel('年化波动'); plt.ylabel('年化收益'); plt.legend(); plt.tight_layout(); plt.show()
小结
- 切线组合 = 夏普最大的组合,权重有闭式解 ;
- CAL 从无风险利率出发与前沿相切于切点;
- 理性投资者持有「切线组合 + 无风险资产」(两基金分离)。