I’ve just finished the course “Analyze Financial Data with Python”. I’m still struggling with importing data from APIs and editing a data frame (dropping columns/rows). Anyway it’s just so great to finish a simple project like this. I’ll try to improve my skills continuously. Would love to hear any comments/suggestion/recommendations or you can even share your projects for reference.

#
-*- coding: utf-8 -*-

“”"

Created on Thu Jul 22 15:00:17 2021

@author: ASUS

“”"

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

from datetime import datetime

import time

import yfinance as yf

from scipy.optimize import minimize

import cvxopt as opt

from cvxopt import blas, solvers

def return_portfolios(expected_returns, cov_matrix):

port_returns =

port_volatility =

stock_weights =

```
selected = (expected_returns.axes)[0]
num_assets = len(selected)
num_portfolios = 10000
for single_portfolio in range(num_portfolios):
weights = np.random.random(num_assets)
weights /= np.sum(weights)
returns = np.dot(weights, expected_returns)
volatility = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
port_returns.append(returns)
port_volatility.append(volatility)
stock_weights.append(weights)
portfolio = {'Returns': port_returns,
'Volatility': port_volatility}
for counter,symbol in enumerate(selected):
portfolio[symbol +' Weight'] = [Weight[counter] for Weight in stock_weights]
df = pd.DataFrame(portfolio)
column_order = ['Returns', 'Volatility'] + [stock+' Weight' for stock in selected]
df = df[column_order]
return df
```

def optimal_portfolio(returns):

n = returns.shape[1]

returns = np.transpose(returns.to_numpy())

```
N = 100
mus = [10**(5.0 * t/N - 1.0) for t in range(N)]
# Convert to cvxopt matrices
S = opt.matrix(np.cov(returns))
pbar = opt.matrix(np.mean(returns, axis=1))
# Create constraint matrices
G = -opt.matrix(np.eye(n)) # negative n x n identity matrix
h = opt.matrix(0.0, (n ,1))
A = opt.matrix(1.0, (1, n))
b = opt.matrix(1.0)
# Calculate efficient frontier weights using quadratic programming
portfolios = [solvers.qp(mu*S, -pbar, G, h, A, b)['x']
for mu in mus]
## CALCULATE RISKS AND RETURNS FOR FRONTIER
returns = [blas.dot(pbar, x) for x in portfolios]
risks = [np.sqrt(blas.dot(x, S*x)) for x in portfolios]
## CALCULATE THE 2ND DEGREE POLYNOMIAL OF THE FRONTIER CURVE
m1 = np.polyfit(returns, risks, 2)
x1 = np.sqrt(m1[2] / m1[0])
# CALCULATE THE OPTIMAL PORTFOLIO
wt = solvers.qp(opt.matrix(x1 * S), -pbar, G, h, A, b)['x']
return np.asarray(wt), returns, risks
```

tickers = yf.Tickers([‘GOOG’, ‘JPM’, ‘UL’, ‘JNJ’])

start = datetime(2016,1,1)

end = datetime(2021,1,1)

#weekly_prices = tickers.history(period = ‘5Y’, interval = ‘1wk’)

weekly_prices = pd.read_csv(‘weekly_prices.csv’)

print(weekly_prices.head())

selected = list(weekly_prices.columns[1:])

weekly_returns = weekly_prices[selected].pct_change()

print(weekly_returns.head())

mean_returns = weekly_returns.mean()

cov_matrix = weekly_returns.cov()

port_return = return_portfolios(mean_returns, cov_matrix)

print(port_return.head())

weights, returns, risks = optimal_portfolio(weekly_returns[1:])

plt.scatter(port_return.Volatility, port_return.Returns)

plt.plot(risks,returns,‘y-o’)

ax = plt.subplot()

ax.set_xlabel(‘Risk’)

ax.set_ylabel(‘Expected Return’)

plt.title(‘Risks vs Returns of Random portfolios’)