如何使用CAPM在Python中找到最佳投资组合的预期回报?

2024-06-27 09:40:02 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,我是Python的新手,真的很难对付这个。。我已经能够构建一个最优投资组合和最小方差投资组合,使用雅虎的股票购买5只股票。我还能够使用CAPM模型获得5只股票的预期回报

def show_optimal_portfolio(optimum, returns, preturns, pvariances):
    plt.figure(figsize=(10,6))
    plt.scatter(pvolatility,preturns,c=preturns/pvolatility,marker='o')
    plt.grid(True)
    plt.xlabel('Expected Volatility')
    plt.ylabel('Expected Return')
    plt.colorbar(label='Sharpe Ratio')
    plt.plot(statistics(optimum['x'],returns)[1],statistics(optimum['x'],returns)[0],
         'bs',markersize=10.0)
    plt.show()
show_optimal_portfolio(optimum, returns, preturns, pvolatility)    


def min_func_sharpe(weights,returns): # [2] means that we want to maximize according to the Sharpe-ratio
return  -statistics(weights,returns)[2]

#  constraints remain the same in optimising based on variance
constraints = ({'type':'eq','fun': lambda x: np.sum(x)-1}) #the sum of weights is 1

bounds=tuple((0,1)表示范围内的x(len(股票))#当100%的钱都是现金时,权重最多可以是1:1 投资于单一股票

optimum_sr=optimization.minimize(fun=min_func_sharpe,x0=weights,args=returns,method='SLSQP',bounds = bounds,constraints=constraints)  
print("Optimal weights (Sharpe Ratio based):", optimum_sr['x'].round(3))
print("Expected return, volatility and Sharpe ratio (Sharpe Ratio based):", 
statistics(optimum_sr['x'].round(3),returns))



def show_optimal_portfolio(optimum, optimum_sr, returns, preturns, pvolatility):
    plt.figure(figsize=(10,6)) # defining figure size
    plt.scatter(pvolatility,preturns,c=preturns/pvolatility,marker='o') # creating scatter plot
    plt.grid(True)
    plt.xlabel('Expected Volatility') # labelling x axis
    plt.ylabel('Expected Return') # labelling y axis 
    plt.colorbar(label='Sharpe Ratio') # colorbar that depends on the range of sharpe ratio values
    plt.plot(statistics(optimum['x'],returns)[1],statistics(optimum['x'],returns)[0],
         'gs',markersize=10.0) # plotting a green square to show the optimum value depending on minimum variance
    plt.plot(statistics(optimum_sr['x'],returns)[1],statistics(optimum_sr['x'],returns)[0],
         'b*',markersize=20.0) # plotting a blue star to show the optimum value depending on sharpe ratio
    plt.show()
show_optimal_portfolio(optimum, optimum_sr, returns, preturns, pvolatility)



def min_func_variance_target(weights, returns):return   statistics(weights, returns)[1] **2

约束=({'type':'eq','fun':lambda x:np.sum(x)-1},{'type':'eq','fun':lambda x:portfolio_return-target_return_p})#权重之和为1 界限=范围内x的元组((0,1)(len(股票))#当100%的资金投资于一只股票时,权重最多为1:1

optimum_trg=optimization.minimize(fun=min_func_variance_target,x0=weights,args=returns,method='SLSQP' ,bound =bounds,constraints=constraints) 

print("Optimal weights:", optimum_trg['x'].round(3))
print("Expected return, volatility and Sharpe ratio:", statistics(optimum_trg['x'].round(3),returns))

def show_optimal_portfolio_trg(optimum_trg, returns, preturns, pvariances):
    plt.figure(figsize=(10,6))
    plt.scatter(pvolatility,preturns,c=preturns/pvolatility,marker='o')
    plt.grid(True)
    plt.xlabel('Expected Volatility')
    plt.ylabel('Expected Return')
    plt.colorbar(label='Sharpe Ratio')
    plt.plot(statistics(optimum_trg['x'],returns)[1],statistics(optimum_trg['x'],returns)[0],
         'gs',markersize=10.0)
    plt.show()
show_optimal_portfolio_trg(optimum_trg, returns, preturns, pvolatility)

##########################

risk_free_rate = 0.00

start=dt.datetime(2011,1,1) 
end=dt.datetime(2020,12,31) #.today()

tickers = ['SBUX','MSFT','REGN', 'PYPL', 'F','Market']
names = ['Starbucks', 'Microsoft','Regen', 'Paypal','Ford', 'Market']
#get the data from Yahoo Finance
data = web.DataReader(tickers,data_source='yahoo',start=start,end=end)['Adj Close']

data = np.log(data/data.shift(1))
data.columns = names


data = data.dropna()

#covariance matrix: the diagonal items are the variances - off diagonals are the covariances
#the matrix is symmetric: cov[0,1] = cov[1,0] 
varcov = data.cov()
varcov = np.array(varcov)

#calculating beta according to the formula
beta_starbucks = varcov[0,5]/varcov[5,5]#= cov(x,m)/var(m)
beta_microsoft = varcov[1,5]/varcov[5,5]#B_m=cov(msft, market)/var(market)
beta_regen = varcov[2,5]/varcov[5,5]
beta_paypal = varcov[3,5]/varcov[5,5]
beta_ford = varcov[4,5]/varcov[5,5]
print("Beta from formula:", beta_starbucks)
print("Beta from formula:", beta_microsoft)



#using linear regression to fit a line to the data [stock_returns, market_returns] - slope is the beta
beta_starbucks,alpha_starbucks = np.polyfit(data['Market'], data['Starbucks'], deg=1)
print("Beta from regression:", beta_starbucks)
print("Alpha from regression:", alpha_starbucks)

#plot
plt.figure(figsize=(10,6))
plt.scatter(data['Market'], data['Starbucks'], label="Data points")
plt.plot(data['Market'], alpha_starbucks + beta_starbucks*data['Market'], color='green', label="CAPM Line")
plt.title('Capital Asset Pricing Model', fontsize=18)
plt.xlabel('Market return $r_m$', fontsize=18)
plt.ylabel('Stock return(Starbucks) $r_i$', fontsize=18)
plt.text(0.05, 0.05, r'$r_i = \alpha + \beta r_m$', color='red', fontsize=18)
plt.legend()
plt.grid(True, axis='both')
plt.show()

#calculate the expected return according to the CAPM formula
expected_return = risk_free_rate + beta_starbucks*(data['Market'].mean()*365-risk_free_rate)
print("Expected return:", expected_return)

然而,我不知道如何使用CAPM将预期回报与最佳投资组合联系起来???


Tags: thedatareturnshowpltbetareturnsexpected