Portfolio optimization

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’)

Congrats on finishing the project! :partying_face:

Can you possibly share the project as a GitHub linked Jupyter Notebook (I’m assuming that you used Jupyter or Colab)? ie: create a GitHub repository for the project with the .ipynb file. One cannot really see the output of the code cells as it is here.

Thanks so much for your suggestion. I don’t know how to edit my post so I just leave the Jupyter Notebook link here, feel free to leave your comments for improvement.
http://localhost:8888/notebooks/Efficient%20Frontier%20-%20Thuy%20Nguyen.ipynb

No worries. I think after a certain time period one cannot edit their post.
That file is on your local machine and no one else can see it.

What you can do is put the .ipynb file online, on GitHub. You can create repositories and host/share your work there. Eventually, you can have several projects there to use as part of your portfolio if you are applying for data jobs.

  • First, you’ll need to create an account/profile.
  • From there, create a repository (make it public), add a brief readme file (describing the project) and then,
  • upload your .ipynb file to the repo. That way, anyone can see your project. If you have any questions, let me know. :slight_smile:

https://docs.github.com/en/github

That helps a lot, many thanks for your kindness. Below is the github link, and I hope it works this time :smiley:

Yep, it works! :partying_face:

Looks like you know what you’re doing. (I haven’t done this project)

Perhaps utilize markdown boxes to give a one line explanation before the code so one can better follow your thought processes as you go through the data(?) I don’t understand how risk is measured for the plot. (but, that’s on me b/c financial data confuses me. lol).