投资组合就是一个权重向量
投资组合由每个资产的权重描述:即其价值中投入该资产的比例。权重之和为 1,负权重是为其他资产融资的空头头寸。一个期间的收益是各资产收益的加权平均,所以预期收益是点积 w @ mu。收益是容易的那一半:它是线性的,资产之间没有相互作用。风险则不是。
import numpy as np
weights = np.array([0.6, 0.4]) # 60% in asset A, 40% in asset B
mu = np.array([0.08, 0.05]) # expected annual returns
print(weights.sum()) # 1.0
print(weights @ mu) # 0.068 = 0.6 * 0.08 + 0.4 * 0.05方差是一个二次型
对两个资产,w1 * A + w2 * B 的方差是 w1**2 * var(A) + w2**2 * var(B) + 2 * w1 * w2 * cov(A, B):每个资产自身的方差,再加一个交叉项。n 个资产有 n * n 项 w_i * w_j * cov[i, j],整个和就是二次型 w @ cov @ w,在 NumPy 中只要一行。关键在交叉项:当两个资产不完全相关时,它们会部分抵消,于是组合的风险小于各自风险的加权平均。
# The variance two ways: the explicit formula and the matrix form
import numpy as np
weights = np.array([0.6, 0.4])
cov = np.array([[0.04, 0.006], [0.006, 0.01]]) # variances 0.04 and 0.01 (volatilities 20% and 10%), covariance 0.006
explicit = weights[0] ** 2 * cov[0, 0] + weights[1] ** 2 * cov[1, 1] + 2 * weights[0] * weights[1] * cov[0, 1]
matrix_form = weights @ cov @ weights
print(round(explicit, 6), round(matrix_form, 6)) # 0.01888 0.01888
print(round(float(np.sqrt(matrix_form)), 4)) # 0.1374 a 13.7% volatility, below 0.6*20% + 0.4*10% = 16%# Diversification: 50/50 in two assets of 20% volatility, for several correlations
import numpy as np
weights = np.array([0.5, 0.5])
for rho in (1.0, 0.5, 0.0, -0.5):
cov = 0.2 * 0.2 * np.array([[1.0, rho], [rho, 1.0]])
print(rho, round(float(np.sqrt(weights @ cov @ weights)), 4)) # 1.0: 0.2, 0.5: 0.1732, 0.0: 0.1414, -0.5: 0.1风险从哪里来?
基金经理想知道哪些仓位在制造风险。资产 i 的风险贡献是 w_i * (cov @ w)_i / sigma_p:它的权重,乘以它与整个组合的联动强度,再除以组合波动率 sigma_p。各项贡献之和恰好等于 sigma_p,把总风险拆成几个部分。权重小但与其余资产协方差很高的资产,贡献可能远超其权重所暗示的,而对冲仓位的贡献可以是负的。
# Risk contributions of a three-asset portfolio: they add up to the volatility
import numpy as np
weights = np.array([0.5, 0.3, 0.2])
cov = np.array([[0.0400, 0.0060, 0.0100],
[0.0060, 0.0100, 0.0020],
[0.0100, 0.0020, 0.0225]])
variance = weights @ cov @ weights
contributions = weights * (cov @ weights) / np.sqrt(variance)
print(np.round(contributions, 4), round(float(contributions.sum()), 4))
print(round(float(np.sqrt(variance)), 4))输入比公式更重要公式是精确的,但
mu 和 cov 是估计值,而且方差比预期收益可靠得多:预期收益噪声很大,协方差则小得多。权重、mu 和 cov 还必须对应同一个期间:把日协方差与年收益率混用是常见错误;方差乘以期数,波动率乘以其平方根。- 组合收益是线性的:
w @ mu。方差是二次型w @ cov @ w,含n * n项和交叉项,相关系数小于 1 就能降低风险。 - 波动率是
sqrt(variance * periods);年化必须与cov的期间一致。 - 风险贡献
w_i * (cov @ w)_i / sigma_p把波动率恰好按资产拆分;对冲仓位的贡献可能为负。
下一节:最小方差组合,选取使这一风险尽可能小的权重。
实验:评分内容
- 用
portfolio_return汇总预期收益25 分 - 用
portfolio_variance衡量风险25 分 - 用
portfolio_vol给出波动率25 分 - 用
risk_contributions按资产拆分风险25 分