『壹』 三支股票 A.B和C,請問該如何算出最優的投資組合配比(最大
投資組合理論是金融領域中一個重要的概念,旨在幫助投資者配置資產以實現風險與收益的最佳平衡。當面對三支股票A、B和C的投資組合時,如何計算最優的投資組合配比,即最大化收益的同時控制風險,成為了投資者關注的焦點。本文將深入探討投資組合理論的核心原理,並通過實際案例展示如何利用Python編程語言來實現投資組合優化。
首先,讓我們明確投資組合理論的核心理念。該理論基於通過均值和方差來評估資產組合的優劣。均值代表資產組合的預期收益率,而方差則衡量了收益率的波動性或風險。通過優化資產組合的預期收益率與風險,投資者可以實現風險調整後的最高收益。
接下來,我們將通過一個簡單的例子來展示如何運用Python實現投資組合理論。假設我們有三隻股票,它們分別是東旭光電、中興通訊、華蘭生物、平安銀行和萬科A。首先,我們需要收集這五隻股票的歷史數據,然後計算它們的平均收益和協方差矩陣。接著,我們將使用蒙特卡洛模擬方法生成大量隨機資產組合,以探索可能的風險與收益組合。通過最大夏普比率和最小方差兩種優化策略,我們可以找到最優資產組合配置權重參數,進而確定投資組合的有效前沿。
在實際操作中,可以利用Python的pandas庫處理數據,numpy庫進行矩陣運算,以及scipy庫求解優化問題。具體步驟包括:
1. **數據收集與預處理**:獲取股票歷史價格數據,計算每日收益並轉換為年化收益。
2. **計算均值與協方差**:利用每日收益計算各股票的年化收益,然後計算協方差矩陣。
3. **隨機權重分配**:由於A股市場不允許建立空頭頭寸,所有權重必須在0-1之間。
4. **計算預期收益與風險**:基於隨機權重計算組合的預期收益和方差。
5. **蒙特卡洛模擬**:生成大量隨機權重組合,記錄每種組合的預期收益與方差。
6. **優化**:使用最大夏普比率和最小方差方法,找到最優資產組合配置權重。
7. **展示有效前沿**:通過圖形展示不同目標收益率下的最優投資組合,包括有效前沿、夏普最大組合和方差最小組合。
通過以上步驟,我們不僅能夠計算出最優的投資組合配比,還能直觀地理解不同風險水平下的收益表現,為投資者提供一個更加科學的決策依據。
綜上所述,投資組合理論通過構建資產組合模型,幫助投資者在風險與收益之間尋求最佳平衡。使用Python編程語言可以輕松實現這一過程,使得投資決策更加高效、精確。無論是針對三支股票還是整個市場,運用投資組合理論進行資產配置都能顯著提升投資效率和回報。
『貳』 如何用python實現Markowitz投資組合優化
0.導入需要的包import pandas as pd
import numpy as np
import statsmodels.api as sm #統計運算
import scipy.stats as scs #科學計算
import matplotlib.pyplot as plt #繪圖
1.選取幾只感興趣的股票
000413 東旭光電,000063 中興通訊,002007 華蘭生物,000001 平安銀行,000002 萬科A
並比較一下數據(2015-01-01至2015-12-31)
In[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', 'daily', ['close'])
data = df['close']
#規范化後時序數據
(data/data.ix[0]*100).plot(figsize = (8,5))
Out[1]:
2.計算不同證券的均值、協方差
每年252個交易日,用每日收益得到年化收益。計算投資資產的協方差是構建資產組合過程的核心部分。運用pandas內置方法生產協方差矩陣。
In [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
In [3]:
returns.cov()*252
Out[3]:
3.給不同資產隨機分配初始權重
由於A股不允許建立空頭頭寸,所有的權重系數均在0-1之間
In [4]:
weights = np.random.random(noa)
weights /= np.sum(weights)
weights
Out[4]:
array([ 0.37505798, 0.21652754, 0.31590981, 0.06087709, 0.03162758])
4.計算預期組合年化收益、組合方差和組合標准差
In [5]:
np.sum(returns.mean()*weights)*252
Out[5]:
0.21622558669017816
In [6]:
np.dot(weights.T, np.dot(returns.cov()*252,weights))
Out[6]:
0.23595133640121463
In [7]:
np.sqrt(np.dot(weights.T, np.dot(returns.cov()* 252,weights)))
Out[7]:
0.4857482232609962
5.用蒙特卡洛模擬產生大量隨機組合
進行到此,我們最想知道的是給定的一個股票池(證券組合)如何找到風險和收益平衡的位置。
下面通過一次蒙特卡洛模擬,產生大量隨機的權重向量,並記錄隨機組合的預期收益和方差。
In [8]:
port_returns = []
port_variance = []
for p in range(4000):
weights = np.random.random(noa)
weights /=np.sum(weights)
port_returns.append(np.sum(returns.mean()*252*weights))
port_variance.append(np.sqrt(np.dot(weights.T, np.dot(returns.cov()*252, weights))))
port_returns = np.array(port_returns)
port_variance = np.array(port_variance)
#無風險利率設定為4%
risk_free = 0.04
plt.figure(figsize = (8,4))
plt.scatter(port_variance, port_returns, c=(port_returns-risk_free)/port_variance, marker = 'o')
plt.grid(True)
plt.xlabel('excepted volatility')
plt.ylabel('expected return')
plt.colorbar(label = 'Sharpe ratio')
Out[8]:
6.投資組合優化1——sharpe最大
建立statistics函數來記錄重要的投資組合統計數據(收益,方差和夏普比)
通過對約束最優問題的求解,得到最優解。其中約束是權重總和為1。
In [9]:
def statistics(weights):
weights = np.array(weights)
port_returns = np.sum(returns.mean()*weights)*252
port_variance = np.sqrt(np.dot(weights.T, np.dot(returns.cov()*252,weights)))
return np.array([port_returns, port_variance, port_returns/port_variance])
#最優化投資組合的推導是一個約束最優化問題
import scipy.optimize as sco
#最小化夏普指數的負值
def min_sharpe(weights):
return -statistics(weights)[2]
#約束是所有參數(權重)的總和為1。這可以用minimize函數的約定表達如下
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,], method = 'SLSQP', bounds = bnds, constraints = cons)
opts
Out[9]:
status: 0
success: True
njev: 4
nfev: 28
fun: -1.1623048291871221
x: array([ -3.60840218e-16, 2.24626781e-16, 1.63619563e-01, -2.27085639e-16, 8.36380437e-01])
message: 'Optimization terminated successfully.'
jac: array([ 1.81575805e-01, 5.40387481e-01, 8.18073750e-05, 1.03137662e+00, -1.60038471e-05, 0.00000000e+00])
nit: 4
得到的最優組合權重向量為:
In [10]:
opts['x'].round(3)
Out[10]:
array([-0. , 0. , 0.164, -0. , 0.836])
sharpe最大的組合3個統計數據分別為:
In [11]:
#預期收益率、預期波動率、最優夏普指數
statistics(opts['x']).round(3)
Out[11]:
array([ 0.508, 0.437, 1.162])
7.投資組合優化2——方差最小
接下來,我們通過方差最小來選出最優投資組合。
In [12]:
#但是我們定義一個函數對 方差進行最小化
def min_variance(weights):
return statistics(weights)[1]
optv = sco.minimize(min_variance, noa*[1./noa,],method = 'SLSQP', bounds = bnds, constraints = cons)
optv
Out[12]:
status: 0
success: True
njev: 7
nfev: 50
fun: 0.38542969450547221
x: array([ 1.14787640e-01, 3.28089742e-17, 2.09584008e-01, 3.53487044e-01, 3.22141307e-01])
message: 'Optimization terminated successfully.'
jac: array([ 0.3851725 , 0.43591119, 0.3861807 , 0.3849672 , 0.38553924, 0. ])
nit: 7
方差最小的最優組合權重向量及組合的統計數據分別為:
In [13]:
optv['x'].round(3)
Out[13]:
array([ 0.115, 0. , 0.21 , 0.353, 0.322])
In [14]:
#得到的預期收益率、波動率和夏普指數
statistics(optv['x']).round(3)
Out[14]:
array([ 0.226, 0.385, 0.587])
8.組合的有效前沿
有效前沿有既定的目標收益率下方差最小的投資組合構成。
在最優化時採用兩個約束,1.給定目標收益率,2.投資組合權重和為1。
In [15]:
def min_variance(weights):
return statistics(weights)[1]
#在不同目標收益率水平(target_returns)循環時,最小化的一個約束條件會變化。
target_returns = np.linspace(0.0,0.5,50)
target_variance = []
for tar in target_returns:
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,],method = 'SLSQP', bounds = bnds, constraints = cons)
target_variance.append(res['fun'])
target_variance = np.array(target_variance)
下面是最優化結果的展示。
叉號:構成的曲線是有效前沿(目標收益率下最優的投資組合)
紅星:sharpe最大的投資組合
黃星:方差最小的投資組合
In [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')
#紅星:標記最高sharpe組合
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(True)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label = 'Sharpe ratio')
『叄』 python實現資產配置(1)----Markowitz 投資組合模型
現假設有A, B, C, D, E五隻股票的收益率數據((第二日收盤價-第一日收盤價)/第一日收盤價)), 如果投資人的目標是達到20%的年收益率,那麼該如何進行資產配置,才能使得投資的風險最低?
更一般的問題,假設現有x 1 ,x 2 ,...,x n , n支風險資產,且收益率已知,如果投資人的預期收益為goalRet,那麼該如何進行資產配置,才能使得投資的風險最低?
1952年,芝加哥大學的Markowitz提出現代資產組合理論(Modern Portfolio Theory,簡稱MPT),為現代西方證券投資理論奠定了基礎。其基本思想是,證券投資的風險在於證券投資收益的不確定性。如果將收益率視為一個數學上的隨機變數的話,證券的期望收益是該隨機變數的數學期望(均值),而風險可以用該隨機變數的方差來表示。
對於投資組合而言,如何分配各種證券上的投資比例,從而使風險最小而收益最大?
答案是將投資比例設定為變數,通過數學規劃,對每一固定收益率求最小方差,對每一個固定的方差求最大收益率,這個多元方程的解可以決定一條曲線,這條曲線上的每一個點都對應著最優投資組合,即在給定風險水平下,收益率最大,這條曲線稱作「有效前沿」 (Efficient Frontier)。
對投資者而言,不存在比有效前沿更優的投資組合,只需要根據自己的風險偏好在有效前沿上尋找最優策略。
簡化後的公式為:
其中 p 為投資人的投資目標,即投資人期待的投資組合的期望值. 目標函數說明投資人資產分配的原則是在達成投資目標 p 的前提下,要將資產組合的風險最小化,這個公式就是Markowitz在1952年發表的'Portfolio Selection'一文的精髓,該文奠定了現代投資組合理論的基礎,也為Markowitz贏得了1990年的諾貝爾經濟學獎. 公式(1)中的決策變數為w i , i = 1,...,N, 整個數學形式是二次規劃(Quadratic Programming)問題,在允許賣空的情況下(即w i 可以為負,只有等式約束)時,可以用拉格朗日(Lagrange)方法求解。
有效前緣曲線如下圖:
我們考慮如下的二次規劃問題
運用拉格朗日方法求解,可以得到
再看公式(1),則將目標函數由 min W T W 調整為 min 1/2(W T W), 兩問題等價,寫出的求解矩陣為:
工具包: CVXOPT python凸優化包
函數原型: CVXOPT.solvers.qp(P,q,G,h,A,b)
求解時,將對應的P,q,G,h,A,b寫出,帶入求解函數即可.值得注意的是輸入的矩陣必須使用CVXOPT 中的matrix函數轉化,輸出的結果要使用 print(CVXOPT.solvers.qp(P,q,G,h,A,b)['x']) 函數才能輸出。
這里選取五支股票2014-01-01到2015-01-01的收益率數據進行分析.
選取的五支股票分別為: 白雲機場, 華夏銀行, 浙能電力, 福建高速, 生益科技
先大體了解一下五支股票的收益率情況:
看來,20%的預期收益是達不到了。
接下來,我們來看五支股票的相關系數矩陣:
可以看出,白雲機場和福建高速的相關性較高,因為二者同屬於交通版塊。在資產配置時,不利於降低非系統性風險。
接下來編寫一個MeanVariance類,對於傳入的收益率數據,可以進行給定預期收益的最佳持倉配比求解以及有效前緣曲線的繪制。
繪制的有效前緣曲線為:
將數據分為訓練集和測試集,並將隨機模擬的資產配比求得的累計收益與測試集的數據進行對比,得到:
可以看出,在前半段大部分時間用Markowitz模型計算出的收益率要高於隨機模擬的組合,然而在後半段卻不如隨機模擬的數據,可能是訓練的數據不夠或者沒有動態調倉造成的,在後面寫策略的時候,我會加入動態調倉的部分。
股票分析部分:
Markowitz 投資組合模型求解
蔡立專:量化投資——以python為工具. 電子工業出版社
『肆』 用Python中的蒙特卡洛模擬兩支股票組成的投資組合的價格趨勢分析
蒙特卡洛模擬是一種模擬把真實系統中的概率過程用計算機程序來模擬的方法。對於投資組合的價格趨勢分析,可以使用Python中的蒙特卡洛模擬。首先,回顧投資組合的價格趨勢。投資組合中的股票價格的趨勢是受多種因素影響的,可分為經濟、政治和技術因素,其中經濟因素最重要。因此,蒙特卡洛模擬可以模擬這些因素對投資組合價格趨勢的影響,並通過計算機繪制投資組合價格趨勢的曲線。
Python中的蒙特卡洛模擬首先需要計算投資組合中各股票價格的每一期的收益率,其次,計算出投資組合的收益率;隨後,計算預測投資組合的期權價格,並將所有的期權價格疊加起來,從而繪制投資組合的價格曲線。最後,在投資組合的價格曲線的基礎上,可以分析投資組合在不同時期的價格走勢,並進行投資組合結構的調整,從而獲得最優投資組合。