In [1]:
import numpy as np
import pandas as pd
from pandas_datareader import data as wb
import matplotlib.pyplot as plt
%matplotlib inline
In [2]:
assets = ["VALE", "PETR4", "ITUB4", "BBDC4", "ABEV3", "BBAS3", "ITSA4", "BVMF3", "KROT3", "CIEL3", "UGPA3", "BBSE3"]
bvmf_data = pd.DataFrame()
for t in assets:
bvmf_data[t] = wb.DataReader(t, data_source='google', start='2015-1-1')['Close']
In [3]:
bvmf_data.head()
Out[3]:
In [4]:
log_returns = np.log(bvmf_data / bvmf_data.shift(1)) # Normalizing returns by using log
In [5]:
def rand_weights(n):
''' Produces n random weights that sum to 1 '''
weights = np.random.rand(n)
weights /= np.sum(weights)
return weights
# Create a random portfolio distribution weigths, that sums 100%
print(rand_weights(len(assets)))
In [6]:
pfolio_returns = []
pfolio_volatilities = []
max_sharpe = 0
max_weights = np.random.rand(len(assets))
for x in range (50000):
weights = rand_weights(len(assets))
retorno = np.sum(weights * log_returns.mean()) * 250
volatilidade = np.sqrt(np.dot(weights.T,np.dot(log_returns.cov() * 250, weights)))
if (retorno/volatilidade) > max_sharpe:
max_sharpe = (retorno/volatilidade)
max_weights = weights
pfolio_returns.append(np.sum(weights * log_returns.mean()) * 250)
pfolio_volatilities.append(np.sqrt(np.dot(weights.T,np.dot(log_returns.cov() * 250, weights))))
pfolio_returns = np.array(pfolio_returns)
pfolio_volatilities = np.array(pfolio_volatilities)
pfolio_returns, pfolio_volatilities
sharpe_arr = pfolio_returns / pfolio_volatilities
sharpe_ind_max = sharpe_arr.argmax()
max_sr_ret = pfolio_returns[sharpe_ind_max]
max_sr_vol = pfolio_volatilities[sharpe_ind_max]
In [7]:
portfolios = pd.DataFrame({'Return': pfolio_returns, 'Volatility': pfolio_volatilities})
In [8]:
portfolios.plot(x='Volatility', y='Return', kind='scatter', figsize=(10, 6));
plt.xlabel('Expected Volatility')
plt.ylabel('Expected Return')
Out[8]:
In [9]:
plt.figure(figsize=(12,8))
plt.scatter(pfolio_volatilities,pfolio_returns,c=sharpe_arr,cmap='plasma')
plt.colorbar(label='Sharpe Ratio')
plt.xlabel('Volatility')
plt.ylabel('Return')
plt.scatter(max_sr_vol,max_sr_ret,c='red',s=100,edgecolors='black')
Out[9]:
In [10]:
print('Retorno máximo (max Sharpe):', max_sr_ret)
print('Volatilidade (max Sharpe):', max_sr_vol)
print('Composição do Portfolio')
for x,y in zip(assets, max_weights):
print(x,y)
In [ ]: