|
import streamlit as st |
|
from datetime import date, timedelta |
|
|
|
import pandas as pd |
|
from plots import ( |
|
beta, |
|
basic_portfolio, |
|
|
|
display_heat_map, |
|
|
|
ER, |
|
buble_interactive |
|
) |
|
|
|
|
|
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 Rish Aversion' |
|
|
|
|
|
from sharp_ratio import( |
|
cumulative_return, |
|
preprocess, |
|
sharp_ratio_func |
|
) |
|
|
|
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 Rish Aversion' |
|
|
|
|
|
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!') |
|
|
|
|
|
|
|
def get_choices(): |
|
"""Prompts the dialog to get the All Choices. |
|
Returns: |
|
An object of choices and an object of combined dataframes. |
|
""" |
|
choices = {} |
|
|
|
|
|
tickers = st.sidebar.text_input('Enter stock tickers.', 'GOOG,A,AVOG,AMD') |
|
|
|
|
|
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') |
|
|
|
|
|
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 = 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' |
|
|
|
|
|
submitted = st.sidebar.button("Calculate") |
|
|
|
symbols = [] |
|
reset = False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if submitted: |
|
|
|
|
|
|
|
|
|
tickers_list = tickers.split(",") |
|
weights_list = weights_str.split(",") |
|
|
|
|
|
symbols.extend(tickers_list) |
|
|
|
|
|
weights = [] |
|
for item in weights_list: |
|
weights.append(float(item)) |
|
|
|
if reset: |
|
|
|
|
|
|
|
|
|
|
|
st.experimental_singleton.clear() |
|
|
|
|
|
else: |
|
|
|
choices = { |
|
|
|
'symbols': symbols, |
|
'weights': weights, |
|
'benchmark': benchmark, |
|
'investing_style': investing_style, |
|
'risk-free-rate': rf, |
|
'A-coef': A_coef |
|
|
|
} |
|
|
|
data = pd.read_csv('data_and_sp500.csv') |
|
combined_df = data[tickers_list] |
|
raw_data=pd.read_csv('us-shareprices-daily.csv', sep=';') |
|
|
|
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']) |
|
|
|
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 |
|
|
|
""" |
|
|
|
basic_portfolio(choices['combined_df']) |
|
display_heat_map(choices['data'],choices['choices']) |
|
|
|
preprocess(choices['raw_data'], choices['choices']) |
|
cumulative_return(choices['raw_data'], choices['choices']) |
|
sharp_ratio_func(choices['raw_data'], choices['choices']) |
|
|
|
|
|
if __name__ == "__main__": |
|
run() |
|
|
|
|