# 用python绘制有效前沿

01

1、投资者在考虑每一次投资选择时，其依据是某一持仓时间内的证券收益的概率分布。

2、投资者是根据证券的期望收益率的方差或标准差估测组合的风险。

3、投资者的决定仅仅是依据证券的风险和收益。

4、在一定的风险水平上，投资者期望收益最大；在一定的收益水平上，投资者希望风险最小。

02

```def portfolio1(ra,rb,sa,sb,rho,wa):
wb = 1 - wa
rp = wa*ra + wb*rb
sp = ((wa**2)*(sa**2) + (wb**2)*(sb**2) + 2*wa*wb*sa*sb*rho)**0.5
return rp,sp

ra = 0.05;rb = 0.1;sa = 0.15;sb = 0.2
rho = np.arange(-10,11,2)/10
wa = np.arange(101)/100

result = pd.DataFrame(columns = ['rho','wa','rp','sp'])
for rhos in rho:
for was in wa:
rp,sp = portfolio1(ra,rb,sa,sb,rhos,was)
x = pd.DataFrame([rhos,was,rp,sp]).T
x.columns = ['rho','wa','rp','sp']
result = result.append(x)
result = result.reset_index(drop = True)

plt.figure(figsize=(20,5))
for i in rho:
datas = result.loc[result.rho ==i]
plt.scatter(datas.sp,datas.rp,marker = 'o',label = 'rho = '+ str(i))
plt.legend()
plt.xlabel('sigma',fontsize = 20)
plt.ylabel('r',fontsize = 20)
plt.show()```

03

```def weights(n):
w = np.random.random(n)
return w/w.sum()

def performance(price,w):
rf = 0.04
ret = price.pct_change(1).dropna()
r_mean = ret.mean()*252
p_mean = np.sum(r_mean*w)
r_cov = ret.cov()*252
p_var = np.dot(w.T,np.dot(r_cov,w))
p_std = np.sqrt(p_var)
p_sharpe = (p_mean-rf)/p_std
return p_mean,p_std,p_sharpe

np.random.seed(1)
p_mean,p_std,p_sharpe = np.column_stack([performance(datax,weights(5)) for i in range(20000)]) #产生随机组合

plt.figure(figsize = (10,5))# YlGnBu
plt.scatter(p_std, p_mean, c=p_sharpe, marker = 'o',cmap = 'YlGnBu',s = 15)
plt.xlabel('std')
plt.ylabel('mean')
plt.colorbar(label = 'Sharpe')
plt.title('Mean and Std of Returns')
plt.show()```

```r_min = result[0]
r_mean_list = np.linspace(r_min,r_min*6,51)
v_list = []
for r in r_mean_list:
cons1 = ({'type':'eq','fun':lambda w:performance(datax,w)[0]-r},{'type':'eq','fun':lambda w:np.sum(w)-1})
opt_var_1 = minimize(min_variance,x0 = weights(5),args = (datax,),bounds=((0,1),(0,1),(0,1),(0,1),(0,1)),constraints = cons1)
#最小方差下的收益率
v_min = performance(datax,opt_var_1.x)[1]
v_list.append(v_min)

plt.figure(figsize = (10,5))
plt.scatter(p_std, p_mean, c=p_sharpe,  marker = 'o',cmap = 'YlGnBu',s = 10)
plt.xlabel('std')
plt.ylabel('mean')
plt.colorbar(label = 'Sharpe')
plt.scatter(v_list,r_mean_list,marker = '*',color = 'orange',label = '有效前沿')
plt.scatter(result[1],result[0],marker = '*',color = 'red',s = 100,label = '最小方差组合')
plt.legend(prop=font)
plt.title('Mean and Std of Returns')
plt.show()```

03

```def EqualWeight(datas):
ret = datas.pct_change(1).fillna(0)
data_norm = datas/datas.iloc[0,]*1000
result = data_norm.copy()

result['ym'] = result.index
result['ym'] = result.ym.apply(lambda x:x.year*100 + x.month)
weights = pd.DataFrame(columns = datas.columns,index = datas.index).fillna(1/datas.shape[1])
result = result.loc[datetime.date(2011,1,4):]
result['nav'] = ((ret*weights).sum(axis = 1) + 1).cumprod()*1000
return weights,result```

```def funs(weight,sigma):
weight = np.array([weight]).T
result = np.dot(np.dot(weight.T,np.mat(sigma)),weight)[0,0]
return(result)

def ConstraintGMOWeight(datas,period ='month',alpha = 1):
ret = datas.pct_change(1).fillna(0)
data_norm = datas/datas.iloc[0,]*1000
result = data_norm.copy()
result['m'] = result.index
result['m'] = result.m.apply(lambda x:x.month)
weights = pd.DataFrame(columns = datas.columns,index = datas.index).fillna(0)

# 约束
cons = ({'type': 'eq', 'fun': lambda x:  1 - sum(x)})
# 边界
bnds = ((0, alpha),(0, alpha),(0, alpha),(0, alpha),(0, alpha))

if period == 'month':
for i in range(result.shape[0]):
if i == 0:
pass
elif result.m[i] != result.m[i - 1]:
sigma = ret.iloc[:i].cov()
weight = [0 for i in range(datas.shape[1])]
res =  minimize(funs,weight, method='SLSQP',args = (sigma,),
bounds=bnds,constraints=cons,tol=1e-8)
weights.iloc[i,:] =  res.x

else:
weights.iloc[i,:] = weights.iloc[i-1,:]

elif period == '6month':
for i in range(result.shape[0]):
if i == 0:
pass
elif (result.m[i] != result.m[i - 1] and  result.m[i]%6==0) :
sigma = ret.iloc[:i].cov()
weight = [0 for i in range(datas.shape[1])]
res =  minimize(funs,weight, method='SLSQP',args = (sigma,),
bounds=bnds,constraints=cons,tol=1e-8)
weights.iloc[i,:] =  res.x
else:
weights.iloc[i,:] = weights.iloc[i-1,:]

elif period == 'year':
for i in range(result.shape[0]):
if i == 0:
pass
elif (result.m[i] != result.m[i - 1] and  result.m[i]%12==0) :
sigma = ret.iloc[:i].cov()
weight = [0 for i in range(datas.shape[1])]
res =  minimize(funs,weight, method='SLSQP',args = (sigma,),
bounds=bnds,constraints=cons,tol=1e-8)
weights.iloc[i,:] =  res.x
else:
weights.iloc[i,:] = weights.iloc[i-1,:]

else:
return '请输入调仓周期'
result = result.loc[datetime.date(2011,1,4):]
result['nav'] = ((ret*weights).sum(axis = 1) + 1).cumprod()*1000
return weights,result```

58 篇文章32 人订阅

0 条评论