Data Science Asked by trapadulli on September 27, 2021
I would like to maximize a portfolio’s Sharpe Ratio while keeping Beta in bounds.
Could anyone supply a calculation please?
***************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
Well, you didn't give a whole lot of information, so I'm going to make some assumptions here, but I think this is pretty darn close to what you want. Keep in mind, Beta = (Covar/Var), so you need to calculate that with what's given below, and then you will have everything you need.
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 Allocationn")
print("Annualised Return:", round(rp,2))
print("Annualised Volatility:", round(sdp,2))
print("n")
print(max_sharpe_allocation)
print("-")
print("Minimum Volatility Portfolio Allocationn")
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)
Result:
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
Answered by ASH on September 27, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP