How to do it...

Execute the following steps to find the Efficient Frontier using Monte Carlo simulations.

  1. Import the libraries:
import yfinance as yf
import numpy as np
import pandas as pd

  1. Set up the parameters:
N_PORTFOLIOS = 10 ** 5
N_DAYS = 252
RISKY_ASSETS = ['FB', 'TSLA', 'TWTR', 'MSFT']
RISKY_ASSETS.sort()
START_DATE = '2018-01-01'
END_DATE = '2018-12-31'

n_assets = len(RISKY_ASSETS)
  1. Download the stock prices from Yahoo Finance:
prices_df = yf.download(RISKY_ASSETS, start=START_DATE, 
end=END_DATE, adjusted=True)
  1. Calculate annualized average returns and the corresponding standard deviation:
returns_df = prices_df['Adj Close'].pct_change().dropna()
avg_returns = returns_df.mean() * N_DAYS
cov_mat = returns_df.cov() * N_DAYS
  1. Simulate random portfolio weights:
np.random.seed(42)
weights = np.random.random(size=(N_PORTFOLIOS, n_assets))
weights /= np.sum(weights, axis=1)[:, np.newaxis]
  1. Calculate the portfolio metrics:
portf_rtns = np.dot(weights, avg_returns)

portf_vol = []
for i in range(0, len(weights)):
portf_vol.append(np.sqrt(np.dot(weights[i].T,
np.dot(cov_mat, weights[i]))))
portf_vol = np.array(portf_vol)

portf_sharpe_ratio = portf_rtns / portf_vol
  1. Create a DataFrame containing all the data:
portf_results_df = pd.DataFrame({'returns': portf_rtns,
'volatility': portf_vol,
'sharpe_ratio':
portf_sharpe_ratio})
  1. Locate the points creating the Efficient Frontier:
N_POINTS = 100
portf_vol_ef = []
indices_to_skip = []

portf_rtns_ef = np.linspace(portf_results_df.returns.min(),
portf_results_df.returns.max(),
N_POINTS)
portf_rtns_ef = np.round(portf_rtns_ef, 2)
portf_rtns = np.round(portf_rtns, 2)

for point_index in range(N_POINTS):
if portf_rtns_ef[point_index] not in portf_rtns:
indices_to_skip.append(point_index)
continue
matched_ind = np.where(portf_rtns ==
portf_rtns_ef[point_index])
portf_vol_ef.append(np.min(portf_vol[matched_ind]))


portf_rtns_ef = np.delete(portf_rtns_ef, indices_to_skip)
  1. Plot the Efficient Frontier:
MARKS = ['o', 'X', 'd', '*']

fig, ax = plt.subplots()
portf_results_df.plot(kind='scatter', x='volatility',
y='returns', c='sharpe_ratio',
cmap='RdYlGn', edgecolors='black',
ax=ax)
ax.set(xlabel='Volatility',
ylabel='Expected Returns',
title='Efficient Frontier')
ax.plot(portf_vol_ef, portf_rtns_ef, 'b--')
for asset_index in range(n_assets):
ax.scatter(x=np.sqrt(cov_mat.iloc[asset_index, asset_index]),
y=avg_returns[asset_index],
marker=MARKS[asset_index],
s=150,
color='black',
label=RISKY_ASSETS[asset_index])
ax.legend()

Executing the preceding code generates the plot with all the randomly created portfolios, four points indicating the individual assets, and the Efficient Frontier:

In the preceding plot, we see the typical, bullet-like shape of the Efficient Frontier.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.47.59