多因子选股策略,收益较大,回撤较小

策略分享
标签: #<Tag:0x00007fcf790e0c68>

(shengda_123) #1
克隆策略
In [ ]:
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('efficient frontier',fontsize=20)
    plt.title('efficient frontier',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()
    plt.xlim(x_axis_low, x_axis_high)
    # 绘制风险资产
    plt.plot(sigma,mu,'bo')
    x_axis_length = x_axis_high-x_axis_low
    text_margin_space = x_axis_length*0.03
    for i in range(N):
        plt.text(sigma[i]+text_margin_space,mu[i]-text_margin_space,'asset '+str(i+1),fontsize=10)
    # 绘制等权投资组合
    if show_E:
        plt.plot(sigma_E, rf+f_E,'ko')
        plt.text(sigma_E+text_margin_space,rf+f_E-text_margin_space,'E',fontsize=15)
    # 绘制策略组合
    if strategy:
        plt.plot(sigma_S, rf+f_S,'ko')
        plt.text(sigma_S+text_margin_space,rf+f_S-text_margin_space,'S',fontsize=15)
    # 绘制最小方差组合与夏普组合(市场组合),以及无风险资产
    plt.plot(sigma_C, rf+f_C,'go')
    plt.text(sigma_C+text_margin_space,rf+f_C-text_margin_space,'C',fontsize=15)
    plt.plot(sigma_Q, rf+f_Q,'ro')
    plt.text(sigma_Q-text_margin_space,rf+f_Q+text_margin_space,'Q',fontsize=15)
#    plt.plot(0, rf,'yo')
#    plt.text(0-0.005,rf+0.008,'$r_{f}$',fontsize=15)
    # 绘制CML
    # plt.plot(s, CML, 'r-')
    # plt.text(0.15,0.28,'CML',fontsize=15)
    if not is_subplot:
        plt.show()
plt.figure(figsize=(15,9))
plot_efficient_frontier(show_E=True)