优化问题:给定 Beta Bounds Maximize sharpe

数据挖掘 优化
2022-02-15 15:05:57

我想最大化投资组合的夏普比率,同时保持 Beta 在界限内。请问有人可以提供计算吗?

***************Starting Metrics**********************
symbols          : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
Beta             : [ 0.09  1.2   2.1  -1.3   1.1   0.3   0.9   1.2 ]
Sharpe           : [-1.7  5.4 -0.3  0.8  0.4  2.7  0.9  1.9]
optimized weights: [x0, x1, x2, x3, x4, x5, x6, x7]

***************Unadjusted Portfolio**********************
AvgBeta unadjusted  : 0.69875
AvgSharpe unadjusted: 1.2625000000000002

***************Ajusted Portfolio**********************
Beta bounds: -.3 < x <.3
Maximize sharpe: X
1个回答

好吧,你没有提供很多信息,所以我将在这里做一些假设,但我认为这非常接近你想要的。请记住,Beta = (Covar/Var),因此您需要使用下面给出的内容进行计算,然后您将拥有所需的一切。

import pandas as pd  
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.optimize as sco
import datetime as dt
import math
from datetime import datetime, timedelta
from pandas_datareader import data as wb
from sklearn.cluster import KMeans
np.random.seed(777)


start = '2019-02-28'
end = '2020-02-28'
# N = 90
# start = datetime.now() - timedelta(days=N)
# end = dt.datetime.today()



tickers = ['MMM',
'ABT',
'ABBV',
'ABMD',
'ACN',
'ATVI',
'ADBE',
'AMD',
'AAP',
'AES',
'AMG',
'XEL',
'XRX',
'XLNX',
'XYL',
'YUM',
'ZBH',
'ZION',
'ZTS'] 

thelen = len(tickers)

price_data = []
for ticker in tickers:
    prices = wb.DataReader(ticker, start = start, end = end, data_source='yahoo')[['Adj Close']]
    price_data.append(prices.assign(ticker=ticker)[['ticker', 'Adj Close']])

df = pd.concat(price_data)
df.dtypes
df.head()
df.shape

pd.set_option('display.max_columns', 500)

df = df.reset_index()
df = df.set_index('Date')
table = df.pivot(columns='ticker')
# By specifying col[1] in below list comprehension
# You can select the stock names under multi-level column
table.columns = [col[1] for col in table.columns]
table.head()



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


def portfolio_annualised_performance(weights, mean_returns, cov_matrix):
    returns = np.sum(mean_returns*weights ) *252
    std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))) * np.sqrt(252)
    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(thelen)
        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


returns = table.pct_change()
mean_returns = returns.mean()
cov_matrix = returns.cov()
num_portfolios = 10000
risk_free_rate = 0.0178


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


def display_simulated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate):
    results, weights = random_portfolios(num_portfolios,mean_returns, cov_matrix, risk_free_rate)

    max_sharpe_idx = np.argmax(results[2])
    sdp, rp = results[0,max_sharpe_idx], results[1,max_sharpe_idx]
    max_sharpe_allocation = pd.DataFrame(weights[max_sharpe_idx],index=table.columns,columns=['allocation'])
    max_sharpe_allocation.allocation = [round(i*100,2)for i in max_sharpe_allocation.allocation]
    max_sharpe_allocation = max_sharpe_allocation.T

    min_vol_idx = np.argmin(results[0])
    sdp_min, rp_min = results[0,min_vol_idx], results[1,min_vol_idx]
    min_vol_allocation = pd.DataFrame(weights[min_vol_idx],index=table.columns,columns=['allocation'])
    min_vol_allocation.allocation = [round(i*100,2)for i in min_vol_allocation.allocation]
    min_vol_allocation = min_vol_allocation.T

    print("-")
    print("Maximum Sharpe Ratio Portfolio Allocation\n")
    print("Annualised Return:", round(rp,2))
    print("Annualised Volatility:", round(sdp,2))
    print("\n")
    print(max_sharpe_allocation)
    print("-")
    print("Minimum Volatility Portfolio Allocation\n")
    print("Annualised Return:", round(rp_min,2))
    print("Annualised Volatility:", round(sdp_min,2))
    print("\n")
    print(min_vol_allocation)

    plt.figure(figsize=(10, 7))
    plt.scatter(results[0,:],results[1,:],c=results[2,:],cmap='YlGnBu', marker='o', s=10, alpha=0.3)
    plt.colorbar()
    plt.scatter(sdp,rp,marker='*',color='r',s=500, label='Maximum Sharpe ratio')
    plt.scatter(sdp_min,rp_min,marker='*',color='g',s=500, label='Minimum volatility')
    plt.title('Simulated Portfolio Optimization based on Efficient Frontier')
    plt.xlabel('annualised volatility')
    plt.ylabel('annualised returns')
    plt.legend(labelspacing=0.8)


display_simulated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate)

结果:

Maximum Sharpe Ratio Portfolio Allocation

Annualised Return: 0.2
Annualised Volatility: 0.16


             AAP  ABBV  ABMD   ABT   ACN  ADBE   AES    AMD   AMG   ATVI  \
allocation  3.29  5.51  0.59  4.29  2.89  9.09  8.42  11.22  3.01  10.03   

             MMM    XEL  XLNX  XRX   XYL   YUM   ZBH  ZION   ZTS  
allocation  0.12  11.39  2.95  6.7  2.89  5.91  3.02  0.79  7.88  
-
Minimum Volatility Portfolio Allocation

Annualised Return: 0.05
Annualised Volatility: 0.13


             AAP  ABBV  ABMD   ABT   ACN  ADBE   AES   AMD   AMG  ATVI   MMM  \
allocation  6.35  8.14  2.55  4.32  8.71  2.18  5.62  1.99  2.08  4.86  6.89   

             XEL  XLNX  XRX  XYL   YUM   ZBH  ZION   ZTS  
allocation  10.1  1.93  1.9  5.5  7.92  5.57  6.01  7.39  

在此处输入图像描述