""" Name : c9_52_impacto_of_correlation_on_efficient_frontier.py Book : Python for Finance (2nd ed.) Publisher: Packt Publishing Ltd. Author : Yuxing Yan Date : 6/6/2017 email : yany@canisius.edu paulyxy@hotmail.com """ from matplotlib.finance import quotes_historical_yahoo_ochl as getData import matplotlib.pyplot as plt import numpy as np, pandas as pd, scipy as sp from numpy.linalg import inv, pinv begYear,endYear = 2012,2016 stocks=['IBM','WMT'] def ret_monthly(ticker): # function 1 x = getData(ticker,(begYear,1,1),(endYear,12,31),asobject=True,adjusted=True) logret=np.log(x.aclose[1:]/x.aclose[:-1]) date=[] d0=x.date for i in range(0,np.size(logret)): date.append(''.join([d0[i].strftime("%Y"),d0[i].strftime("%m")])) y=pd.DataFrame(logret,date,columns=[ticker]) return y.groupby(y.index).sum() def std_f(ticker): x=ret_monthly(ticker) return sp.std(x) def objFunction(W, R, target_ret): stock_mean=np.mean(R,axis=0) port_mean=np.dot(W,stock_mean) # portfolio mean #cov=np.cov(R.T) # var-cov matrix cov=cov0 port_var=np.dot(np.dot(W,cov),W.T) # portfolio variance penalty = 2000*abs(port_mean-target_ret)# penalty 4 deviation return np.sqrt(port_var) + penalty # objective function R0=ret_monthly(stocks[0]) # starting from 1st stock n_stock=len(stocks) # number of stocks std1=std_f(stocks[0]) std2=std_f(stocks[1]) for jj in sp.arange(1): k=0.1*std1*std2 #cov0=sp.array([[0.00266285,0.00037303],[0.00037303,0.0021296]]) #cov0=sp.array([[std1**2,k],[k,std2**2]]) cov0=sp.array([[std1**2,0.00037303],[0.00037303,std2**2]]) for i in xrange(1,n_stock): # merge with other stocks x=ret_monthly(stocks[i]) R0=pd.merge(R0,x,left_index=True,right_index=True) R=np.array(R0) out_mean,out_std,out_weight=[],[],[] stockMean=np.mean(R,axis=0) for r in np.linspace(np.min(stockMean),np.max(stockMean),num=100): W = np.ones([n_stock])/n_stock # starting from equal weights b_ = [(0,1) for i in range(n_stock)] # bounds, here no short c_ = ({'type':'eq', 'fun': lambda W: sum(W)-1. })#constraint result=sp.optimize.minimize(objFunction,W,(R,r),method='SLSQP',constraints=c_, bounds=b_) if not result.success: # handle error raise BaseException(result.message) out_mean.append(round(r,4)) # 4 decimal places std_=round(np.std(np.sum(R*result.x,axis=1)),6) out_std.append(std_) out_weight.append(result.x) plt.title('Efficient Frontier') plt.xlabel('Standard Deviation of the porfolio (Risk))') plt.ylabel('Return of the portfolio') plt.figtext(0.5,0.75,str(n_stock)+' stock are used: ') plt.figtext(0.5,0.7,' '+str(stocks)) plt.figtext(0.5,0.65,'Time period: '+str(begYear)+' ------ '+str(endYear)) plt.plot(out_std,out_mean,'--') plt.show()