Lirsen Myrtaj
Update app.py (#56)
9cfb4b8
raw
history blame
13.1 kB
import streamlit as st
from datetime import date, timedelta
#from rest_api.fetch_data import (get_symbol_data)
import pandas as pd
from PIL import Image
import time
from plots import (
beta,
basic_portfolio,
# display_portfolio_return,
display_heat_map,
#circle_packing,
ER,
buble_interactive
)
### Koi
from ef import(
ef_viz
)
def risk_str(num):
if num >=5 and num <15:
return 'Low Risk Aversion'
elif num >= 15 and num <25:
return 'Medium Risk Aversion'
elif num >= 25 and num <=35:
return 'High Risk Aversion'
#### Koi
from sharp_ratio import(
cumulative_return,
sharp_ratio_func
)
from arima import (
# get_model_accuracy,
arima_chart
)
def load_heading():
"""The function that displays the heading.
Provides instructions to the user
"""
with st.container():
st.title('Dataminers')
header = st.subheader('This App performs historical portfolio analysis and future analysis ')
st.subheader('Please read the instructions carefully and enjoy!')
# st.text('This is some text.')
def get_choices():
"""Prompts the dialog to get the All Choices.
Returns:
An object of choices and an object of combined dataframes.
"""
choices = {}
#tab1, tab2, tab3, tab4, tab5 = st.tabs(["Tickers", "Quantity", "Benchmark","Risk Free Return","Risk Aversion"])
tickers = st.sidebar.text_input('Enter stock tickers.', 'GOOG,AA,AVGO,AMD')
# Set the weights
weights_str = st.sidebar.text_input('Enter the investment quantities', '50,30,25,25')
benchmark = st.sidebar.selectbox(
'Select your ideal benchmark of return',
('SP500', 'AOK', 'IXIC'))
if benchmark == 'IXIC':
st.sidebar.warning("You have selected a volatile benchmark.")
elif benchmark == 'SP500':
st.sidebar.success('You have selected a balanced benchmark')
elif benchmark == 'AOK':
st.sidebar.success('You have selected a conservative benchmark')
### koi
rf = st.sidebar.number_input('Enter current rate of risk free return', min_value=0.001, max_value=1.00, value=0.041)
#A_coef_map =
A_coef = st.sidebar.slider('Enter The Coefficient of Risk Aversion', min_value=5, max_value=35, value=30, step=5)
if A_coef > 20:
st.sidebar.success("You have selected a "+ risk_str(A_coef) +" investing style")
investing_style = 'Conservative'
elif A_coef >10 and A_coef <= 20:
st.sidebar.success("You have selected a "+risk_str(A_coef) +" investing style")
investing_style = 'Balanced'
elif A_coef <= 10:
st.sidebar.warning("You have selected a "+ risk_str(A_coef) +" investing style")
investing_style = 'Risky'
# Every form must have a submit button.
submitted = st.sidebar.button("Calculate")
symbols = []
reset = False
# Reusable Error Button DRY!
#def reset_app(error):
# st.sidebar.write(f"{error}!")
# st.sidebar.write(f"Check The Syntax")
# reset = st.sidebar.button("RESET APP")
if submitted:
#with st.spinner('Running the calculations...'):
# time.sleep(8)
# st.success('Done!')
# convert strings to lists
tickers_list = tickers.split(",")
weights_list = weights_str.split(",")
#crypto_symbols_list = crypto_symbols.split(",")
# Create the Symbols List
symbols.extend(tickers_list)
#symbols.extend(crypto_symbols_list)
# Convert Weights To Decimals
weights = []
for item in weights_list:
weights.append(float(item))
if reset:
# # Clears all singleton caches:
#tickers = st.sidebar.selectbox('Enter 11 stock symbols.', ('GOOG','D','AAP','BLK'))
# crypto_symbols = st.sidebar.text_input('Enter 2 crypto symbols only as below', 'BTC-USD,ETH-USD')
#weights_str = st.sidebar.text_input('Enter The Investment Weights', '0.3,0.3 ,0.3')
st.experimental_singleton.clear()
else:
# Submit an object with choices
choices = {
'symbols': symbols,
'weights': weights,
'benchmark': benchmark,
'investing_style': investing_style,
'risk-free-rate': rf,
'A-coef': A_coef
}
# Load combined_df
data = pd.read_csv('data_and_sp500.csv')
combined_df = data[tickers_list]
raw_data=pd.read_csv('us-shareprices-daily.csv', sep=';')
# return object of objects
return {
'choices': choices,
'combined_df': combined_df,
'data': data,
'raw_data':raw_data
}
def run():
"""The main function for running the script."""
load_heading()
choices = get_choices()
if choices:
st.success('''** Selected Tickers **''')
buble_interactive(choices['data'],choices['choices'])
st.header('Tickers Beta')
"""
The Capital Asset Pricing Model (CAPM) utilizes a formula to enable the application to calculate
risk, return, and variability of return with respect to a benchmark. The application uses this
benchmark, currently S&P 500 annual rate of return, to calculate the return of a stock using
Figure 2 in Appendix A. Elements such as beta can be calculated using the formula in Appendix
A Figure 1. The beta variable will serve as a variable to be used for calculating the variability of
the stock with respect to the benchmark. This variability factor will prove useful for a variety of
calculations such as understanding market risk and return. If the beta is equal to 1.0, the stock
price is correlated with the market. When beta is smaller than 1.0, the stock is less volatile than
the market. If beta is greater than 1.0, the stock is more volatile than the market.
The CAPM model was run for 9 stocks, using 10-year daily historical data for initial test analysis.
With this initial analysis, beta was calculated to determine the stock’s risk by measuring the
price changes to the benchmark. By using CAPM model, annual expected return and portfolio
return is calculated. The model results can be found in Appendix A.
"""
beta(choices['data'], choices['choices'])
ER(choices['data'], choices['choices'])
##### EDIT HERE ##### koi
st.header('CAPM Model and the Efficient Frontier')
"""
CAPM model measures systematic risks, however many of it's functions have unrealistic assumptions and rely heavily on a linear interpretation
of the risks vs. returns relationship. It is better to use CAPM model in conjunction with the Efficient Frontier to better
graphically depict volatility (a measure of investment risk) for the defined rate of return. \n
Below we map the linear Utility function from the CAPM economic model along with the Efficient Frontier
Each circle depicted above is a variation of the portfolio with the same input asset, only different weights.
Portfolios with higher volatilities have a yellower shade of hue, while portfolios with a higher return have a larger radius. \n
As you input different porfolio assets, take note of how diversification can improve a portfolio's risk versus reward profile.
"""
ef_viz(choices['data'],choices['choices'])
"""
There are in fact two components of the Efficient Frontier: the Efficient Frontier curve itself and the Minimum Variance Frontier.
The lower curve, which is also the Minimum Variance Frontier will contain assets in the portfolio
that has the lowest volatility. If our portfolio contains "safer" assets such as Governmental Bonds, the further to the right
of the lower curve we will see a portfolio that contains only these "safe" assets, the portfolios on
this curve, in theory, will have diminishing returns.\n
The upper curve, which is also the Efficient Frontier, contains portfolios that have marginally increasing returns as the risks
increases. In theory, we want to pick a portfolio on this curve, as these portfolios contain more balanced weights of assets
with acceptable trade-offs between risks and returns. \n
If an investor is more comfortable with investment risks, they can pick a portfolio on the right side of the Efficient Frontier.
Whereas, a conservative investor might want to pick a portfolio from the left side of the Efficient Frontier. \n
Take notes of the assets' Betas and how that changes the shape of the curve as well. \n
How does the shape of the curve change when
the assets are of similar Beta vs when they are all different?\n
Note the behavior of the curve when the portfolio contains only assets with Betas higher than 1 vs. when Betas are lower than 1.\n
"""
##### ##### Koi
# Creates the title for streamlit
st.subheader('Portfolio Historical Normalized Cumulative Returns')
"""
Cumulative Returns:\n
The cumulative return of an asset is calculated by subtracting the original price paid from the current profit or loss. This answers the question,
what is the return on my initial investment?\n
The graph below shows the historical normalized cumulative returns for each of the chosen assets for the entire time period of the available data.
The default line chart shows tickers AA, AMD, AVGO, and GOOG and we can see that all have a positive cumulative return over the period of the available data.
Any of these assets purchased on the starting day and sold on the ending day for the period would have earned a return on their investment.\n
This chart can also be used to analyze the correlation of the returns of the chosen assets over the displayed period.
Any segments of the line charts that show cumulative returns with similarly or oppositely angled segments can be considered to have some level of
correlation during those periods.
"""
basic_portfolio(choices['combined_df'])
"""
Negative Correlations (1): \n
Occur for assets whose cumulative returns move in opposite directions. When one goes up the other goes down and vice versa.
These negatively correlated assets would offer some level of diversification protection to each other.
Perfectly negatively correlated stocks are sort of the goal, but unlikely to be common.
In most cases finding some level of negatively correlated stocks, should offer some level of diversification protection to your portfolio.
The amount of protection depends upon the calculated metric. Our tool includes some CAPM analysis, which attempts to relate the risk and return
and the correlation of assets to determine the expected portfolio returns versus the combined, hopefully reduced, risk.\n
Positive Correlations (2):\n
Occur for assets whose cumulative returns move in concert. When one goes up the other also goes up and vice versa.
These positively correlated assets would not offer much or any diversification protection to each other.\n
"""
im = Image.open('1vs2.png')
col1, col2, col3 = st.columns([1,6,1])
with col1:
st.write("")
with col2:
st.image(im, caption='Trends of Assets Correlations',use_column_width='auto')
with col3:
st.write("")
# Creates the title for streamlit
st.subheader('Heatmap Showing Correlation Of Assets')
"""
Heatmap: \n
The Heat map shows the overall correlation of each asset to the other assets. Notice that the middle diagonal row is filled in with all 1’s.
That is because they are all perfectly correlated with themselves. A value of 1 equates to perfect correlation, -1 equates to perfect negative correlation,
and 0 equates to no correlation with values in between being relative to their distance from the extremes. A correlation value of .5 would mean
the asset moves half as much in the same direction as the correlated asset. A values of -0.5 would mean it moves half as much in the opposite direction
as the correlated asset. \n
The Heat map shows the correlation coefficient or value for each asset over the entire period to each other asset.
It also depicts the color of the intersection as darker for less correlation and lighter for more correlation, which could be either positive or negative.
The legend on the right indicates the absolute level of correlation for each color, again positive or negative associated to each color.\n
"""
display_heat_map(choices['data'],choices['choices'])
#display_portfolio_return(choices['combined_df'], choices['choices'])
cumulative_return(choices['combined_df'], choices['choices'])
sharp_ratio_func(choices['raw_data'], choices['choices'])
'''
ARIMA:\n
'''
arima_chart(choices['choices']['symbols'])
if __name__ == "__main__":
run()