Lirsen Myrtaj
Upload ef.py (#6)
408579e
raw
history blame
3.68 kB
import pandas as pd
import numpy as np
from datetime import datetime as dt
from pypfopt.efficient_frontier import EfficientFrontier
import streamlit as st
import plotly.graph_objects as go
import plotly.express as px
def ef_viz(stock_df,choices):
st.write("EF Visualization KOI EDITS")
symbols, weights, investment = choices.values()
tickers = symbols
#tickers.append('sp500')
st.write(tickers)
#st.write(stock_df)
# Yearly returns for individual companies
#https://stackoverflow.com/questions/69284773/unable-to-resample-the-pandas-with-date-column-typeerror-only-valid-with-dateti
stock_dff = stock_df.copy()
stock_dff['Date'] = pd.to_datetime(stock_dff['Date'])
# ind_er_df = stock_dff.set_index('Date')
#st.write(stock_dff.columns)
ind_er_df = stock_dff.resample('Y', on = 'Date').last().pct_change().mean()
ind_er = ind_er_df[tickers]
#st.write(ind_er)
ann_sd = stock_df[tickers].pct_change().apply(lambda x: np.log(1+x)).std().apply(lambda x: x*np.sqrt(250))
assets = pd.concat([ind_er, ann_sd], axis=1) # Creating a table for visualising returns and volatility of assets
assets.columns = ['Returns', 'Volatility']
assets
st.write(assets)
ln_pct_change = stock_df[tickers].pct_change().apply(lambda x: np.log(1+x))[1:]
#Cov Matrix
cov_matrix =ln_pct_change.cov()
p_ret = [] # Define an empty array for portfolio returns
p_vol = [] # Define an empty array for portfolio volatility
p_weights = [] # Define an empty array for asset weights
num_assets = len(tickers)
num_portfolios = 10000
for portfolio in range(num_portfolios):
weights = np.random.random(num_assets)
weights = weights/np.sum(weights)
p_weights.append(weights)
returns = np.dot(weights, ind_er) # Returns are the product of individual expected returns of asset and its
# weights
p_ret.append(returns)
var = cov_matrix.mul(weights, axis=0).mul(weights, axis=1).sum().sum()# Portfolio Variance
sd = np.sqrt(var) # Daily standard deviation
ann_sd = sd*np.sqrt(250) # Annual standard deviation = volatility
p_vol.append(ann_sd)
data = {'Returns':p_ret, 'Volatility':p_vol}
for counter, symbol in enumerate(stock_df[tickers].columns.tolist()):
#print(counter, symbol)
data[symbol] = [w[counter] for w in p_weights]
port_ef_df = pd.DataFrame(data)
st.write(port_ef_df[tickers].T)
rf = 0.041
min_vol_port = port_ef_df.iloc[port_ef_df['Volatility'].idxmin()]
optimal_risky_port = port_ef_df.iloc[((port_ef_df['Returns']-rf)/port_ef_df['Volatility']).idxmax()]
## Create Figure
# fig = go.Figure()
# fig.add_trace(go.Scatter(x=port_ef_df['Volatility'], y=port_ef_df['Returns'], \
# color=port_ef_df['Volatility'], mode='markers', name='markers'))
fig = px.scatter(port_ef_df, 'Volatility', 'Returns', size='Returns', size_max=20, color='Volatility', \
custom_data=tickers)
fig.update_traces(hovertemplate="<br>".join([
"%{tickers[0]}:%{custom_data[0]}",
"%{tickers[1]}:%{custom_data[1]}",
"%{tickers[2]}:%{custom_data[2]}",
"%{tickers[3]}:%{custom_data[3]}"
])
)
#https://stackoverflow.com/questions/59057881/python-plotly-how-to-customize-hover-template-on-with-what-information-to-show
st.plotly_chart(fig, use_container_width=True)
#st.write(stock_df)