约束、交易成本与再平衡
直觉
前几节的组合都是「理想解」——可以卖空、可以天天免费调仓。现实里:多数人不能卖空(要做多约束)、每次调仓都要付成本、频繁再平衡会被成本吃掉。把工程现实加进来,理论权重才能真正落地。
1. 做多约束
加上 后,闭式解失效,改用数值优化(如 SLSQP):
2. 再平衡与成本
组合会漂移(涨多的资产权重变大)。定期再平衡拉回目标,但每次按换手 付成本:
- 再平衡越频繁 → 越贴近目标风险,但成本越高;
- 越不频繁 → 成本低,但风险漂移大。
「人话」解释:再平衡是「免费的午餐」吗?
再平衡强迫你「卖涨买跌」,自带一点均值回归收益,同时把风险维持住。 但它是有成本的——交易费、税、冲击成本。频率过高,成本反而吞掉再平衡收益。 实务里常见月度或季度再平衡,是「贴近目标」与「成本可控」的折中。
可运行案例:做多约束 + 再平衡频率
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from numpy.linalg import inv
from scipy.optimize import minimize
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()
S = R.cov().values * 252
n = len(assets); ones = np.ones(n)
# —— 1) 做多约束下的最小方差 ——
w_uncon = inv(S) @ ones / (ones @ inv(S) @ ones) # 无约束(可能卖空)
res = minimize(lambda w: w @ S @ w, np.ones(n)/n, method='SLSQP',
bounds=[(0, 1)]*n, constraints=[{'type':'eq','fun':lambda w: w.sum()-1}])
w_long = res.x
print("最小方差权重:"); print(pd.DataFrame({'无约束(可卖空)':w_uncon,'做多约束':w_long}, index=assets).round(3))
# —— 2) 再平衡频率 vs 成本(等权组合) ——
mr = R.resample('ME').sum() # 月对数收益
cost_bps = 20.0
def run(freq):
w = np.ones(n)/n; nav = []
for i, (_, r) in enumerate(mr.iterrows()):
nav.append(w @ r.values)
w = w * np.exp(r.values); w /= w.sum() # 漂移
if (i + 1) % freq == 0: # 每 freq 月再平衡
nav[-1] -= np.abs(w - np.ones(n)/n).sum() * cost_bps/1e4
w = np.ones(n)/n
return (1 + pd.Series(nav)).cumprod()
plt.figure(figsize=(8, 3.6))
for freq, name in [(1, '月度'), (3, '季度'), (12, '年度')]:
eq = run(freq)
plt.plot(eq.index, eq, label=f'{name}再平衡 末值={eq.iloc[-1]:.2f}')
plt.title(f'等权组合再平衡频率对比(成本 {cost_bps:.0f} bps)')
plt.ylabel('净值'); plt.legend(fontsize=8); plt.tight_layout(); plt.show()
小结
- 做多约束需数值优化(SLSQP),权重与无约束解不同;
- 再平衡维持目标风险,自带「卖涨买跌」,但有交易成本;
- 频率是「贴近目标」与「成本」的权衡,实务多用月度/季度。
模块 7 完成。下一模块回到回测工程,把约束、成本、防偏差做成可落地的流程。