投資組合管理
有效邊界看起來不太好
嗨,我正在嘗試繪製一個有效的邊界。下面是我用的。回報參數由投資組合的 9 列回報組成。我選擇了 10,000 個投資組合,這就是我的有效邊界的樣子。這不是我們熟悉的通常的邊界形狀。
數據集是 48_Industry_Portfolios_daily.csv,來自 ( http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html )。前 9 列被選中
有人可以向我解釋這個問題嗎?
def portfolio_annualised_performance(weights, mean_returns, cov_matrix): returns = np.sum(mean_returns*weights ) *252 #print ('weights shape',weights.shape) #print (' Returns ',returns) std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))) * np.sqrt(252) #print ('Std ',std) return std, returns def random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate): results = np.zeros((3,num_portfolios)) weights_record = [] for i in range(num_portfolios): weights = np.random.random(48) weights /= np.sum(weights) weights_record.append(weights) portfolio_std_dev, portfolio_return = portfolio_annualised_performance(weights, mean_returns, cov_matrix) results[0,i] = portfolio_std_dev results[1,i] = portfolio_return results[2,i] = (portfolio_return - risk_free_rate) / portfolio_std_dev return results, weights_record def monteCarlo_Simulation(returns): #returns=returns.drop("Date") returns=returns/100 stocks=list(returns) stocks1=list(returns) stocks1.insert(0,"ret") stocks1.insert(1,"stdev") stocks1.insert(2,"sharpe") print (stocks) #calculate mean daily return and covariance of daily returns mean_daily_returns = returns.mean() #print (mean_daily_returns) cov_matrix = returns.cov() #set number of runs of random portfolio weights num_portfolios = 10000 #set up array to hold results #We have increased the size of the array to hold the weight values for each stock results = np.zeros((4+len(stocks)-1,num_portfolios)) for i in range(num_portfolios): #select random weights for portfolio holdings weights = np.array(np.random.random(len(stocks))) #rebalance weights to sum to 1 weights /= np.sum(weights) #calculate portfolio return and volatility portfolio_return = np.sum(mean_daily_returns * weights) * 252 portfolio_std_dev = np.sqrt(np.dot(weights.T,np.dot(cov_matrix, weights))) * np.sqrt(252) #store results in results array results[0,i] = portfolio_return results[1,i] = portfolio_std_dev #store Sharpe Ratio (return / volatility) - risk free rate element excluded for simplicity results[2,i] = results[0,i] / results[1,i] #iterate through the weight vector and add data to results array for j in range(len(weights)): results[j+3,i] = weights[j] print (results.T.shape) #convert results array to Pandas DataFrame results_frame = pd.DataFrame(results.T,columns=stocks1) #locate position of portfolio with highest Sharpe Ratio max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()] #locate positon of portfolio with minimum standard deviation min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()] #create scatter plot coloured by Sharpe Ratio plt.figure(figsize=(10,10)) plt.scatter(results_frame.stdev,results_frame.ret,c=results_frame.sharpe,cmap='RdYlBu') plt.xlabel('Volatility') plt.ylabel('Returns') plt.colorbar() #plot red star to highlight position of portfolio with highest Sharpe Ratio plt.scatter(max_sharpe_port[1],max_sharpe_port[0],marker=(2,1,0),color='r',s=1000) #plot green star to highlight position of minimum variance portfolio plt.scatter(min_vol_port[1],min_vol_port[0],marker=(2,1,0),color='g',s=1000) print(max_sharpe_port)
更新的答案
我還被要求使用不同的正則化比較投資組合變異數,並使用驗證方法來找到最佳參數。我們可以使用python來做到這一點嗎?
據我了解您的問題,您對為什麼沒有清楚地描繪邊界的預期拋物線形狀感到困惑。
如果您想更清楚地看到形狀,可以執行以下兩項操作之一:
- 增加隨機投資組合的數量。隨著這個數字趨於無窮大,您最終將繪製所有可能的投資組合組合,您的有效邊界將非常明顯。
- 利用有效前沿上的所有投資組合都可以由兩個有效投資組合(例如最大銳化和最小變異數投資組合)的組合建構的事實。您只需建構一個權重等於的投資組合數組((return,std.dev)-pairs)即可 $ weights=w*\pi_{max}+(1-w)*\pi_{min} $ 對於一個區間 $ w $ 的。
而不是製作 10,000 個隨機投資組合來找到切線和 min.var。投資組合,您也可以使用方程式解決它們
$$ \mathbf{\pi}_{\max SR} = \frac{1}{\mathbf{1’\Sigma^{-1}\mu}} \mathbf{\Sigma^{-1}\mu} $$
$$ \mathbf{\pi_{\min Var}} = \frac{1}{ \mathbf{1’ \Sigma^{-1}1}} \mathbf{ \Sigma^{-1}1} $$
在哪裡 $ \mathbf{\Sigma^{-1}} $ 是變異數-共變異數矩陣的倒數, $ \mathbf{\mu} $ 是您的預期回報向量,並且 $ \mathbf{1} $ 是一個與你的長度相同的 1 向量 $ \mathbf{\mu} $ .