跳转至

均值方差模型的有效前沿曲线

在无做空限制的情形下推导均值方差模型的有效前沿曲线,本质上是求解一个带有等式约束的最优化问题。

\[ \begin{aligned} & \underset{w}{\text{minimize}} & & \frac{1}{2} w^{\top} \sum w \\\ & \text{subject to} & & w^{\top} e=1 \\\ & & & w^{\top} \mu=\mu_0 \end{aligned} \]

png

有效前沿曲线

问题描述

已知\(N\)个资产的预期收益率\(\mu_{N\times1}\),收益率协方差矩阵\(\Sigma_{N\times N}\),均值方差模型需要求解的是:给定投资组合的预期收益率为\(\mu_0\),找到一个最优的权重向量\(w_{N\times1}\),使得投资组合收益率的方差最小。

假设投资组合可以任意做空,则可以用如下最优化问题表示均值方差模型:

\[ \begin{aligned} & \underset{w}{\text{minimize}} & & \frac{1}{2} w^{\top} \sum w \\\ & \text{subject to} & & w^{\top} e=1 \\\ & & & w^{\top} \mu=\mu_0 \end{aligned}\tag{0}\label{0} \]

其中,\(e\)\(N\times1\)的单位向量。

拉格朗日乘数法求解最优化问题

对于上述带有等式约束的最优化问题,写出对应的拉格朗日函数:

\[ \begin{aligned} &\mathcal{L}\left(w, \lambda_1, \lambda_2\right)\\\ =&\frac{1}{2} w^{\top} \Sigma w+\lambda_1\left(w^{\top} e-1\right)+\lambda_2\left(w^{\top} \mu-\mu_0\right) \end{aligned} \]

\(\mathcal{L}\left(w, \lambda_1, \lambda_2\right)\)的三个自变量求一阶偏导,并令其等于 0:

\[ \frac{\partial \mathcal{L}}{\partial w}=0 \Rightarrow \Sigma w+\lambda_1 e+\lambda_2 \mu=0 \tag{1}\label{1} \]
\[ \frac{\partial \mathcal{L}}{\partial \lambda_1}=0 \Rightarrow e^{\top} w-1=0 \tag{2}\label{2} \]
\[ \frac{\partial \mathcal{L}}{\partial \lambda_2}=0 \Rightarrow \mu^{\top} w-\mu_0=0 \tag{3}\label{3} \]

由公式\(\eqref{1}\)可知:

\[ w=\Sigma^{-1}\left(-\lambda_1 e-\lambda_2 \mu\right)\tag{4}\label{4} \]

将公式\(\eqref{4}\)代入公式\(\eqref{2}\)和公式\(\eqref{3}\),得:

\[ \begin{array}{l} e^{\top} \Sigma^{-1}\left(-\lambda_1 e-\lambda_2 \mu\right)-1=0 \\\ \mu^{\top} \Sigma^{-1}\left(-\lambda_1 e-\lambda_2 \mu\right)-\mu_0=0 \end{array}\tag{5}\label{5} \]

整理得:

\[ \begin{aligned} & e^{\top} \Sigma^{-1} e {\color{red}{\lambda_1}}+e^{\top} \Sigma^{-1} \mu {\color{blue}{\lambda_2}}+1=0 \\\ & \mu^{\top} \Sigma^{-1} e {\color{red}{\lambda_1}}+\mu^{\top} \Sigma^{-1} \mu {\color{blue}{\lambda_2}}+\mu_0=0 \end{aligned}\tag{6}\label{6} \]

这是一个关于\(\lambda_1\)\(\lambda_2\)的线性方程组,为简化表示,可以记:

\[ \begin{aligned} A&=e^{\top} \Sigma^{-1} e \\\ B&=e^{\top} \Sigma^{-1} \mu=\mu^{\top} \Sigma^{-1} e \\\ C&=\mu^{\top} \Sigma^{-1} \mu \end{aligned}\tag{7}\label{7} \]

用消元法可以容易解出:

\[ \begin{aligned} & \lambda_1=\frac{B \mu_0-C}{A C-B^2} \\\ & \lambda_2=\frac{B-A \mu_0}{A C-B^2} \end{aligned}\tag{8}\label{8} \]

\(\lambda_1\)\(\lambda_2\)代入公式\(\eqref{4}\),得:

\[ \begin{aligned} w^* & =\Sigma^{-1}\left(-\lambda_1 e-\lambda_2 \mu\right) \\\ & =\Sigma^{-1}\left(\frac{C-B \mu_0 }{A C-B^2}e+\frac{A \mu_0-B}{A C-B^2} \mu\right) \end{aligned}\tag{9}\label{9} \]

这就是最优化问题\(\eqref{0}\)的解。

从最优权重向量到有效前沿曲线

由最优化问题\(\eqref{0}\)可知,每一个预期收益水平\(\mu_0\)都对应一个最优权重\(w^\ast\)。在\(w^\ast\)下,投资组合的⽅差为(详细推导见公式\(\eqref{13}\)):

\[ \begin{aligned} \sigma^2\left(\mu_0\right) =& w^{\ast\top} \Sigma w^\ast \\\ =& \frac{A \mu_0^2-2 B \mu_0+C}{A C-B^2} \end{aligned}\tag{10}\label{10} \]

可⻅,\(\sigma^2\)是关于\(\mu_0\)的二次函数。但有效前沿曲线的横轴是\(\sigma\),而不是\(\sigma^2\)。对公式\(\eqref{10}\)做一定的变换,可得如下形式:

\[ \frac{\sigma^2\left(\mu_0\right)} {a^2} - \frac{\mu_{0}^{2}} {b^2}=1\tag{11}\label{11} \]

因此\(\mu_0\)关于\(\sigma\)的函数图像是一个双曲线。

最小方差组合

由公式\(\eqref{10}\)可知,当

\[ \begin{aligned} \mu_0=&-\frac{-2 B}{2 A}\\\ =&\frac{B}{A} \end{aligned}\tag{12}\label{12} \]

时,\(\sigma^2\left(\mu_0\right)\)取最小值。

将公式\(\eqref{12}\)代入公式\(\eqref{9}\),可得最小方差组合的权重向量。

数值模拟

基于 16 个全球指数的历史日线数据,计算有效前沿曲线。

Python
import qstock as qs
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"] = ["KaiTi"]
plt.rcParams["axes.unicode_minus"] = False
import seaborn as sb
Python
global_indexs = [
    "道琼斯",
    "标普 500",
    "纳斯达克",
    "恒生指数",
    "英国富时",
    "法国 CAC40",
    "德国 DAX",
    "日经 225",
    "韩国 KOSPI",
    "澳大利亚标普 200",
    "印度孟买 SENSEX",
    "俄罗斯 RTS",
    "加拿大 S&P",
    "台湾加权",
    "美元指数",
    "路透 CRB 商品指数",
]
df = qs.get_price(global_indexs, start="20200101")
# 将数据转换为日收益率
df = df.pct_change().dropna()
# 计算历史收益率均值,作为预期收益率
mu = df.mean()
# 计算历史收益率协方差矩阵,作为预期协方差矩阵
cov = df.cov()
Text Only
100%|██████████| 16/16 [00:03<00:00,  4.65it/s]
Python
# 历史日收益率均值
print(mu)
Text Only
标普500         0.000340
道琼斯           0.000306
纳斯达克          0.000351
韩国KOSPI       0.000126
英国富时全股        0.000051
德国DAX30       0.000218
澳大利亚标普200     0.000122
法国CAC40       0.000239
美元指数          0.000114
加拿大S&P/TSX    0.000254
印度孟买SENSEX    0.000626
俄罗斯RTS       -0.000192
台湾加权          0.000294
恒生指数         -0.000306
路透CRB商品指数     0.000604
日经225         0.000239
dtype: float64
Python
# 历史协方差矩阵热力图
# 设置图片大小
fig, ax = plt.subplots(figsize=(20, 10))
# 生成热力图。cmap 是颜色,annot 是是否显示相关系数,mask 是上三角形矩阵
# 生成 mask,覆盖上三角形矩阵,包括对角线
matrix = np.triu(cov, k=1)
sb.heatmap(cov, cmap="Blues", annot=True, mask=matrix)
plt.show()

png

Python
def get_optimal_weight(mu, cov, mu_0):
    """

    Args:
        mu: 期望收益率
        cov: 协方差矩阵
        mu_0: 给定的目标收益率

    Returns:
        optimal_weight: 最优权重
    """
    # 协方差矩阵的逆
    cov_inv = np.linalg.inv(cov)
    # 单位向量
    ones = np.ones(len(mu))
    # 生成 A、B 和 C
    a = ones.dot(cov_inv).dot(ones)
    b = ones.dot(cov_inv).dot(mu)
    c = mu.dot(cov_inv).dot(mu)
    # 计算 lambda_1
    lambda_1 = (b * mu_0 - c) / (a * c - b**2)
    # 计算 lambda_2
    lambda_2 = (b - a * mu_0) / (a * c - b**2)
    # 计算最优权重
    optimal_weight = -lambda_1 * cov_inv.dot(ones) - lambda_2 * cov_inv.dot(mu)
    return optimal_weight
Python
# 最小方差组合
# 协方差矩阵的逆
cov_inv = np.linalg.inv(cov)
# 单位向量
ones = np.ones(len(mu))
# 生成 A、B 和 C
a = ones.dot(cov_inv).dot(ones)
b = ones.dot(cov_inv).dot(mu)
# 计算最小方差组合的预期收益率
u_min_var = b / a
# 计算最小方差组合权重
w_min_var = get_optimal_weight(mu, cov, u_min_var)
# 计算最小方差组合的预期标准差
std_min_var = np.sqrt(w_min_var.T.dot(cov).dot(w_min_var.T))
Python
# 对不同的目标收益率,计算最优权重
mu_0_list = np.linspace(-0.001, 0.001, 100)
optimal_weight_list = np.array(
    [get_optimal_weight(mu, cov, mu_0) for mu_0 in mu_0_list]
)
# 计算有效前沿
std_list = [
    np.sqrt(optimal_weight.T.dot(cov).dot(optimal_weight.T))
    for optimal_weight in optimal_weight_list
]
# 绘制有效前沿
# plt.style.use('seaborn')
plt.figure(figsize=(10, 6))
plt.plot(std_list, mu_0_list)
plt.plot(std_min_var, u_min_var, "ro")
# 文字注释
plt.text(std_min_var + 0.0005, u_min_var, "最小方差组合", fontsize=18)
plt.xlabel("std")
plt.ylabel("mu")
plt.show()

png

公式\(\eqref{10}\)的详细推导

\[ \begin{aligned} \sigma^2\left(\mu_0\right)= & w^{\ast^\top} \Sigma w^\ast \\\ = & \left(\frac{C-B \mu_0}{A C-B^2} e^{\top}+\frac{A \mu_0-B}{A C-B^2} \mu^{\top}\right) \Sigma^{-1} \Sigma \Sigma^{-1}\left(\frac{C-B \mu_0}{A C-B^2} e+\frac{A \mu_0-B}{A C - B^2} \mu\right) \\\ = & \frac{C-B \mu_0}{A C-B^2} e^{\top} \Sigma^{-1} \frac{C-B \mu_0}{A C-B^2} e + \frac{C-B \mu_0}{A C-B^2} e^{\top} \Sigma^{-1} \frac{A \mu_0-B}{A C-B^2} \mu \\\ & + \frac{A \mu_0-B}{A C-B^2} \mu^{\top} \Sigma^{-1} \frac{C-B \mu_0}{A C-B^2} e + \frac{A \mu_0-B}{A C-B^2} \mu^{\top} \Sigma^{-1} \frac{A \mu_0-B}{A C-B^2} \mu\\\ = & \frac{\left(C-B \mu_0\right)^2}{\left(A C-B^2\right)^2} A+2 \frac{\left(C-B \mu_0\right)\left(A \mu_0-B\right)}{\left(A C-B^2\right)^2} B+\frac{\left(A \mu_0-B\right)^2}{\left(A C-B^2\right)^2} C\\\ =& \frac{A C^2-2 A B C \mu_0+A B^2 \mu_0^2 +2 A B C \mu_0-2 B^2 C-2 A B^2 \mu_0^2+2 B^3 \mu_0 +A^2 C M_0-2 A B C \mu_0+B^2 C} { \left(A C-B^2\right)^2} \\\ =& \frac{A C^2-A B^2 \mu_0^2+2 B^3 \mu_0+A^2 C \mu_0-2 A B C \mu_0-B^2 C}{\left(A C-B^2\right)^2} \\\ =& \frac{\left(A C-B^2\right)\left(A \mu_0^2-2 B \mu_0+C\right)}{\left(A C-B^2\right)^2} \\\ =& \frac{A \mu_0^2-2 B \mu_0+C}{A C-B^2} & \end{aligned}\tag{13}\label{13} \]

评论