將numpy作為np導入
將statsmodels.api作為sm #統計操作導入
將scipy.stats作為scs #科學計算導入
導入mapplotlib.pyplot asplt #繪圖
1.選擇幾只感興趣的股票。
000413徐東光電,00063中興通訊,002007華蘭生物,00001平安銀行,000002萬科a
並對比數據(2015-01-01至2015-12-31)。
在[1]中:
stock_set = ['000413。XSHE ',' 000063。XSHE ',' 002007。XSHE ',' 000001。XSHE ',' 000002。XSHE']
noa = len(stock_set)
df = get_price(stock_set,start _ date = ' 2015-01-01 ',end _ date = ' 2015-12-31 ','每日',['收盤'])
data = df['close']
#標準化時間序列數據
(data/data.ix[0]*100)。plot(figsize = (8,5))
Out[1]:
2.計算不同證券的均值和協方差。
壹年252個交易日,用日收益得出年化收益。計算投資資產的協方差是構建投資組合過程的核心部分。使用pandas內置方法產生協方差矩陣。
在[2]中:
returns = NP . log(data/data . shift(1))
returns.mean()*252
Out[2]:
000413.XSHE 0.184516
000063.XSHE 0.176790
002007.XSHE 0.309077
000001.XSHE -0.102059
000002.XSHE 0.547441
在[3]中:
returns.cov()*252
Out[3]:
3.隨機為不同的資產分配初始權重。
由於a股不允許建立空倉,所以所有的權重系數都在0-1之間。
在[4]中:
權重= np.random.random(noa)
權重/= np.sum(權重)
砝碼
Out[4]:
數組([ 0.37505798,0.21652754,0.31590981,0.06087709,0.03162758])
4.計算投資組合的預期年化回報、投資組合方差和投資組合標準差。
在[5]中:
NP . sum(returns . mean()* weights)* 252
Out[5]:
0.21622558669017816
在[6]中:
np.dot(權重。t,np.dot(returns.cov()*252,weights))
Out[6]:
0.23595133640121463
在[7]中:
np.sqrt(np.dot(權重。t,np.dot(returns.cov()* 252,權重)))
Out[7]:
0.4857482232609962
5.蒙特卡羅模擬產生大量的隨機組合。
此時,我們最想知道的是,對於給定的股票池(投資組合),如何找到風險和收益的平衡點。
接下來,通過蒙特卡羅模擬,產生大量隨機權重向量,並記錄隨機組合的期望收益和方差。
在[8]中:
port_returns = []
port_variance = []
對於範圍內的p(4000):
權重= np.random.random(noa)
權重/=np.sum(權重)
port _ returns . append(NP . sum(returns . mean()* 252 * weights))
port _ variance . append(NP . sqrt(NP . dot(weights。t,np.dot(returns.cov()*252,weights))))
端口返回= np.array(端口返回)
端口差異= np.array(端口差異)
#無風險利率設定為4%
無風險= 0.04
plt.figure(figsize = (8,4))
plt.scatter(port_variance,port_returns,c =(port _ returns-risk _ free)/port _ variance,marker = 'o ')
plt.grid(真)
plt.xlabel('例外波動率')
plt.ylabel('預期回報')
plt.colorbar(label = '夏普比率')
Out[8]:
6.投資組合優化1-夏普最大值
建立統計功能,記錄重要的投資組合統計數據(收益、方差和夏普比率)。
通過求解約束優化問題,得到最優解。約束條件是總權重為1。
在[9]中:
定義統計(重量):
權重= np.array(權重)
port _ returns = NP . sum(returns . mean()* weights)* 252
port _ variance = NP . sqrt(NP . dot(weights。t,np.dot(returns.cov()*252,權重)))
return NP . array([端口返回,端口變化,端口返回/端口變化])
#最優投資組合的推導是壹個約束優化問題。
將scipy.optimize導入為sco
#最小化夏普指數的負值
def min_sharpe(權重):
返回-統計(權重)[2]
#約束是所有參數(權重)之和為1。這可以用最小化函數的約定來表示,如下所示
cons = ({'type':'eq ',' fun ':lambda x:NP . sum(x)-1 })
#我們還將參數值(權重)限制在0到1之間。這些值作為由多個元組組成的元組被提供給最小化函數。
bnds = tuple((0,1) for x in range(noa))
#優化函數調用中唯壹忽略的輸入是起始參數列表(權重的初始猜測)。我們簡單地使用平均分布。
opts = sco.minimize(min_sharpe,noa*[1。/noa,],方法= 'SLSQP ',界限= bnds,約束= cons)
選擇
Out[9]:
狀態:0
成功:真的
njev: 4
非正規教育:28
好玩:-1.1623048291871221
x:數組([ -3.60840218e-16,2.24626781e-16,1.63619563 e-01,-2.27085639e-16,8.36380437 e-06537
消息:“優化成功終止。”
江淮:數組([1.81575805 e-01,5.40387481e-01,8.18073750e-05,1.03137662e+00,-1.6003847467
nit: 4
獲得的最佳組合權重向量是:
在[10]:
opts['x']。回合(3)
Out[10]:
數組([-0。, 0., 0.164, -0., 0.836])
夏普的三個統計數據的最大組合是:
在[11]:
#預期收益率、預期波動率和最優夏普指數
統計數據(opts['x'])。回合(3)
Out[11]:
數組([ 0.508,0.437,1.162])
7.投資組合優化2-最小方差
接下來,我們通過最小化方差來選擇最佳投資組合。
在[12]:
#但是我們定義了壹個函數來最小化方差。
定義最小方差(權重):
返回統計數據(權重)[1]
optv = sco.minimize(min_variance,noa*[1。/noa,],方法= 'SLSQP ',界限= bnds,約束= cons)
optv
Out[12]:
狀態:0
成功:真的
njev: 7
非正規教育:50
樂趣:0.3842969450547221
x:數組([1.14787640 e-01,3.28089742e-17,2.09584008e-01,3.53487044e-01,3.22141307 e-0654338
消息:“優化成功終止。”
jac:數組([ 0.3851725,0.43591119,0.3861807,0.3849672,0.38553924,0。])
nit: 7
方差最小的最優組合權向量和組合的統計數據分別為:
在[13]:
optv['x']。回合(3)
Out[13]:
數組([ 0.115,0。, 0.21 , 0.353, 0.322])
在[14]:
#獲得預期收益率、波動率和夏普指數。
統計數據(optv['x'])。回合(3)
Out[14]:
數組([ 0.226,0.385,0.587])
8.組合的有效前沿
有效邊界由在給定目標收益率下具有最小差異的投資組合組成。
優化中采用了兩個約束,1。給定目標收益率,2。投資組合權重之和為1。
在[15]:
定義最小方差(權重):
返回統計數據(權重)[1]
#當不同的目標回報水平(target_returns)循環時,最小化的壹個約束條件將改變。
target_returns = np.linspace(0.0,0.5,50)
target_variance = []
對於target_returns中的tar:
cons = ({'type':'eq ',' fun ':lambda x:statistics(x)[0]-tar },{'type':'eq ',' fun ':lambda x:NP . sum(x)-1 })
res = sco.minimize(min_variance,noa*[1。/noa,],方法= 'SLSQP ',界限= bnds,約束= cons)
target _ variance . append(RES[' fun '])
目標方差= np.array(目標方差)
下面是優化結果的演示。
交叉:曲線是有效前沿(目標收益率下的最優投資組合)
紅星:夏普最大的投資組合
黃興:最小方差投資組合
在[16]:
plt.figure(figsize = (8,4))
#圓圈:蒙特卡羅隨機組合分布
plt.scatter(port_variance,port_returns,c = port_returns/port_variance,marker = 'o ')
#交叉:有效邊界
plt.scatter(target_variance,target_returns,c = target _ returns/target _ variance,marker = 'x ')
#紅星:標誌最高夏普組合
PLT . plot(statistics(opts[' x '])[1],statistics(opts['x'])[0],' r* ',markersize = 15.0)
#黃星:標記的最小方差組合
PLT . plot(statistics(optv[' x '])[1],statistics(optv['x'])[0],' y* ',markersize = 15.0)
plt.grid(真)
plt.xlabel('預期波動率')
plt.ylabel('預期回報')
plt.colorbar(label = '夏普比率')