'Plotting Markowitz Efficient Frontier with Python
I'm trying to Plott the Markowitz Efficient Frontier with Python but I'm not getting the desired bullet shape that is usually found and I don't know what I might have done wrong, any help is much appreciated !
(I'm using Average Equal daily Weighted Returns as input data)
the link from which I'm trying to plott the Markowitz Efficient Frontier: https://towardsdatascience.com/python-markowitz-optimization-b5e1623060f5
import pandas as pd
import numpy as np
df = pd.read_excel (r'C:\Users\brade\Desktop\Python\49_Industry_Portfolios_Daily.xlsx', skiprows=9, nrows= 25187, index_col=0, parse_dates=True)
df.info()
print (df)
np.random.seed(42)
num_ports = 6000
all_weights = np.zeros((num_ports, len(df.columns)))
ret_arr = np.zeros(num_ports)
vol_arr = np.zeros(num_ports)
sharpe_arr = np.zeros(num_ports)
for x in range(num_ports):
# Weights
weights = np.array(np.random.random(49))
weights = weights/np.sum(weights)
# Save weights
all_weights[x,:] = weights
# Expected return
ret_arr[x] = np.sum((df.mean() * weights * 252))
# Expected volatility
vol_arr[x] = np.sqrt(np.dot(weights.T, np.dot(df.cov()*252, weights)))
# Sharpe Ratio
sharpe_arr[x] = ret_arr[x]/vol_arr[x]
#Maximum SHarpe Ratio
print('Max sharpe ratio in the array: {}'.format(sharpe_arr.max()))
print("Its location in the array: {}".format(sharpe_arr.argmax()))
#Max sharpe ratio in the array: -8.525157669319496
#Its location in the array: 5185
#get the allocation in this max
print(all_weights[5185,:])
max_sr_ret = ret_arr[sharpe_arr.argmax()]
max_sr_vol = vol_arr[sharpe_arr.argmax()]
#Max sharpe ratio in the array: -8.525157669319496
#Its location in the array: 5185
#[0.01117167 0.03558722 0.00194414 0.03362501 0.01413863 0.03196054
# 0.02553783 0.0291854 0.01097694 0.00207069 0.0011559 0.00010691
# 0.0016922 0.03941764 0.03785089 0.01865089 0.0390962 0.01874136
# 0.01186381 0.00486033 0.02981664 0.03378699 0.03989109 0.00922282
# 0.03618472 0.0004863 0.0125648 0.03059016 0.01388772 0.01990928
# 0.01206905 0.01063152 0.01711765 0.01018931 0.01223478 0.00130421
# 0.02504012 0.03362276 0.02425936 0.02570623 0.03723166 0.02867486
# 0.01846097 0.03365429 0.02681322 0.03384932 0.00382821 0.02903587
# 0.0203019 ]
from matplotlib import pyplot as plt
plt.figure(figsize=(12,8))
plt.scatter(vol_arr, ret_arr, c=sharpe_arr, cmap='viridis')
plt.colorbar(label='Sharpe Ratio')
plt.xlabel('Volatility')
plt.ylabel('Return')
plt.scatter(max_sr_vol, max_sr_ret,c='red', s=50) # red dot
plt.show()
########################################################################
def get_ret_vol_sr(weights):
weights = np.array(weights)
ret = np.sum(df.mean() * weights) * 252
vol = np.sqrt(np.dot(weights.T, np.dot(df.cov()*252, weights)))
sr = ret/vol
return np.array([ret, vol, sr])
def neg_sharpe(weights):
# the number 2 is the sharpe ratio index from the get_ret_vol_sr
return get_ret_vol_sr(weights)[2] * -1
def check_sum(weights):
#return 0 if sum of the weights is 1
return np.sum(weights)-1
cons = ({'type':'eq','fun':check_sum})
bounds = ((0,1), (0,1), (0,1), (0,1))
init_guess = [0.25,0.25,0.25,0.25]
opt_results = minimize(neg_sharpe, init_guess, method='SLSQP' ,bounds=bounds, constraints=cons)
print(opt_results)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
