- 实现平台:BigQuant—人工智能量化投资平台
- 可在文末前往原文一键克隆代码进行进一步研究
从MPT到APT
前面文章为大家介绍了许多AI量化投资理念,CAPM和APT是现代投资组合理论的基石,在这篇教程中,我们阐述了CML和CAPM的关系,以及APT和CAPM的差异和不同,从而帮助读者在正式理解主动投资管理框架之前,打好理论基础和知识。
夏普组合与CML
我们在上期的教程中,已经证明了最优夏普组合就是在有效前沿上夏普比最大的风险资产组合。然而可以证明,在EMH的假设条件下,且在均衡状态下,最优夏普组合就是市场组合(市值加权组合)。
不过关于这个论点,有几个大家需要注意的地方:
- 这个是有效市场假说下的推论,读者可以选择不相信这个假说
- 这里的市场组合包含了全市场所有的风险资产,如股票、期货、金属、外汇、房地产、古玩等等
- 有效前沿是一个凸函数,在投资者均方投资决策的条件下,任何偏离最优夏普组合的行为都会得到纠正
有了上述总结,相信大家对这个结论也会有自己的判断。为了阐述后面的内容,教程后面将视最优夏普组合与市场组合为同一个概念,但是大家心里要清楚这里的前提假设和背景。
现在,为了引出CML资本市场线的概念,我们在风险资产外,加入了无风险资产的概念。
然后我们要介绍一个非常重要的定律,即分离定理:
指在投资组合中可以以无风险利率自由借贷的情况下投资人选择投资组合时都会选择无风险资产和风险投资组合的得最优组合点,因为这一点相对于其他的投资组合在风险上或是报酬上都具有优势。
所以谁投资都会都会选择这一点。投资人对风险的态度,只会影响投入的资金数量,而不会影响最优组合点。
\begin{align*}
E[r_{p}] = w_{f} r_{f} + w_{m} E[r_{m}]
\end{align*}
\begin{align*}
其中,w_{f} + w_{m} = 1
\end{align*}
我们的组合方差为:
\begin{align*}
\sigma_{p}^2 &= w_{f}^2 \sigma_{f}^2 + w_{m}^2 \sigma_{m}^2 + 2 w_f w_m cov(r_f,r_m)\
&= w_{m}^2 \sigma_{m}^2\
\Rightarrow \quad w_m &= \frac{\sigma_{p}}{\sigma_{m}}
\end{align*}
于是,我们得到CML的显示表达式:
\begin{align*}
E[r_{p}] = r_{f} + \left[ \frac{E[r_{m}]-r_{f}}{\sigma_{m}} \right] \sigma_{p}
\end{align*}
风险溢价
上式中的 E [ r m ] − r f σ m \frac{E[r_{m}]-r_{f}}{\sigma_{m}} σmE[rm]−rf,我们通常称之为风险溢价。分子表示超额收益,即超出无风险资产收益率的报酬,分母表示组合风险(标准差),
这个指标在经济意义上就是表示单位市场风险下的报酬,其实也是市场组合的夏普比率。CML的斜率预示了为了承担额外单位风险所需要支付的报酬,因此也被称为市场均衡价格下的风险。
换句话说,我可以可以这么理解和表示:
\begin{align*}
E[r_{p}] = r_{f} + 市场价格风险 \times 风险量
\end{align*}
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
rf = 0.05 # 无风险利率
mu = np.array([0.1,0.15,0.18]) # 预期收益率向量
sigma = np.array([0.1,0.12,0.15])
rou_ab, rou_ac, rou_bc = 0.2, 0.5, -0.2
# 协方差矩阵
C = np.array([[1, rou_ab, rou_ac],
[rou_ab, 1, rou_bc],
[rou_ac, rou_bc, 1 ]])
V = np.outer(sigma,sigma)*C
# 前沿曲线绘图函数
def plot_efficient_frontier(rf=rf,mu=mu,V=V,is_subplot=False,show_E=False,strategy=None):
f = mu-rf # 超额收益
N = len(mu)
e = np.ones(N)
sigma = np.sqrt(np.diag(V))
V_inverse = np.linalg.inv(V)
# 等权投资组合
w_E = e/N
sigma2_E = w_E.dot(V).dot(w_E)
sigma_E = np.sqrt(sigma2_E)
f_E = w_E.dot(f)
# 最小方差组合
w_C = V_inverse.dot(e)/e.T.dot(V_inverse).dot(e)
sigma2_C = w_C.dot(V).dot(w_C)
sigma_C = np.sqrt(sigma2_C)
f_C = w_C.dot(f)
# 夏普组合
w_Q = V_inverse.dot(f)/f.T.dot(V_inverse).dot(e)
sigma2_Q = w_Q.dot(V).dot(w_Q)
sigma_Q = np.sqrt(sigma2_Q)
f_Q = w_Q.dot(f)
# 有效前沿曲线
f_P = np.linspace(f_C,1.5*np.max(mu)) # 只取上半部分抛物线
get_w_P = lambda fp: (f_Q-fp)/(f_Q-f_C)*w_C + (fp-f_C)/(f_Q-f_C)*w_Q
w_P = np.array([get_w_P(fp) for fp in f_P])
k = (sigma2_Q-sigma2_C)/(f_Q-f_C)**2
sigma2_P = sigma2_C + k*(f_P-f_C)**2
sigma_P = np.sqrt(sigma2_P)
r_P = rf + w_P.dot(f)
# 策略组合
if strategy is not None:
w_S,f_S,sigma_S = strategy(pred_ret,V)
# 资本市场曲线CML
s = np.linspace(0,0.2)
CML = rf + f_Q/sigma_Q * s
# 有效前沿曲线绘制
plt.plot(sigma_P,r_P)
plt.title('CML',fontsize=10)
plt.xlabel('$\sigma$',fontsize=20)
plt.ylabel('return of Portfolio',fontsize=20)
#x_axis_low, x_axis_high = sigma_C-(sigma_P.max()-sigma_C)*0.1,sigma_P.max()
x_axis_low, x_axis_high = 0,sigma_P.max()
plt.xlim(x_axis_low, x_axis_high)
# 绘制风险资产
plt.plot(sigma,mu,'bo')
x_axis_len