Spaces:
Sleeping
Sleeping
from scraped_data import get_alpha_vantage_data, get_finnhub_data | |
import datetime | |
import pandas as pd | |
import streamlit as st | |
import yfinance as yf | |
from datetime import timedelta | |
def get_industry(ticker): | |
comp_info = get_finnhub_data(f'/stock/profile2?symbol={ticker}') | |
return comp_info | |
def get_company_metrics(ticker): | |
res_basic_fins = get_finnhub_data(f'/stock/metric?symbol={ticker}&metric=all') | |
metric_data = res_basic_fins['metric'] if 'metric' in res_basic_fins else 'N/A' | |
annual_series_data = res_basic_fins['series']['annual'] if ('series' in res_basic_fins and 'annual' in res_basic_fins['series']) else 'N/A' | |
quarterly_series_data = res_basic_fins['series']['quarterly'] if ('series' in res_basic_fins and 'quarterly' in res_basic_fins['series']) else 'N/A' | |
return metric_data, annual_series_data, quarterly_series_data | |
def calc_beta(ticker): | |
tick = yf.Ticker(f'{ticker}') | |
sp_hist = yf.Ticker('^GSPC').history(period="5y")['Close'] | |
ticker_hist = tick.history(period="5y")['Close'] | |
sp500 = sp_hist.reset_index().rename(columns={'Close':'sp500_Close'}) | |
sp500['sp500_variance'] = sp500['sp500_Close'].var() | |
merged_df = sp500.merge(ticker_hist, how='outer', on='Date') | |
beta = merged_df.cov(numeric_only=True).loc['sp500_Close']['Close'] / sp500['sp500_variance'].max() | |
max_date = merged_df['Date'].max() | |
d = {'Beta': beta, 'Symbol': ticker} | |
df_beta = pd.DataFrame(d, index = [0]) | |
return df_beta.set_index('Symbol') | |
def get_equity_gains(ticker, period): | |
sp = yf.Ticker(f"{ticker}") | |
sp_hist = sp.history(period=f'{period}d')[['Close','Dividends']] | |
sp500 = sp_hist.reset_index() | |
todays_close = sp500.sort_values('Date', ascending=False).iloc[0] | |
sp500_new_index = sp500.set_index('Date') | |
val = {} | |
if todays_close[0] - timedelta(days=period) in sp500_new_index.index: | |
delta = todays_close['Close'] - sp500_new_index.loc[todays_close[0] - timedelta(days=period)]['Close'] | |
val[f'5Y_change'] = (delta / sp500_new_index.loc[todays_close[0] - timedelta(days=period)]['Close']) | |
else: | |
delta = todays_close['Close'] - sp500_new_index.loc[todays_close[0] - timedelta(days=period-4)]['Close'] | |
val[f'5Y_change'] = (delta / sp500_new_index.loc[todays_close[0] - timedelta(days=period-4)]['Close']) | |
# add in dividend | |
recent_div = sp500.sort_values('Date', ascending=False) | |
first_non_zero_dividend_row = recent_div[recent_div['Dividends'] > 0.0] | |
if len(first_non_zero_dividend_row) == 0: | |
return val['5Y_change'], 0, recent_div['Close'].iloc[0] | |
else: | |
return val['5Y_change'], first_non_zero_dividend_row.iloc[0]['Dividends'], recent_div['Close'].iloc[0] | |
def get_90_day_tbill(): | |
q = 'function=TREASURY_YIELD&' | |
t_bill_data = get_alpha_vantage_data(q) | |
df_t_bills = pd.DataFrame(t_bill_data['data']).rename(columns={'date':'Date', 'value':'90_day_t_bill'}) | |
return float(df_t_bills.iloc[0]['90_day_t_bill'])/100.00 | |
def get_list_of_tickers(): | |
comp_info = get_finnhub_data('/stock/symbol?exchange=US') | |
list_of_tickers = [] | |
for i in range(len(comp_info)-1): | |
for key in comp_info[i].keys(): | |
if key == 'symbol': | |
list_of_tickers.append(comp_info[i]['symbol']) | |
return list_of_tickers | |
# ---------------------------------------------------------------------------------------------- # | |
symbols = [] | |
list_of_tickers = get_list_of_tickers() | |
with st.form(key="selecting columns"): | |
symbols = st.multiselect(label='Enter Tickers Here. Cannot check metrics for Funds.', options=list_of_tickers, placeholder='MSFT, AAPL, ...') | |
strategy_selection = st.radio("Select Strategy", ('Value', 'Growth'), horizontal=True) | |
submit_button = st.form_submit_button(label='Compute Metrics') | |
if submit_button and symbols and strategy_selection == 'Value': | |
beta_dfs = [] | |
gains_data = {} | |
hash_map = {} | |
for ticker in symbols: | |
st.spinner(text=f"Loading {ticker} Data...") | |
# make all the API calls and capture return json | |
basic_info = get_industry(ticker) | |
metric_data, annual_series_data, quarterly_series_data = get_company_metrics(ticker) | |
# reformat all JSON returns to be flattened dictionaries | |
roe_dict = {'roe': annual_series_data['roe'][0]['v'] if annual_series_data != 'N/A' else 'N/A'} | |
totalDebtToTotalCapital_y_dict = {'totalDebtToTotalCapital_y' : annual_series_data['totalDebtToTotalCapital'][0]['v'] if annual_series_data != 'N/A' else 'N/A'} | |
totalDebtToEquity_y_dict = {'totalDebtToEquity_y' : annual_series_data['totalDebtToEquity'][0]['v'] if annual_series_data != 'N/A' else 'N/A'} | |
eps_dict = {'eps' : annual_series_data['eps'][0]['v'] if annual_series_data != 'N/A' else 'N/A'} | |
totalDebtToTotalCapital_q_dict = {'totalDebtToTotalCapital_q' : quarterly_series_data['totalDebtToTotalCapital'][0]['v'] if quarterly_series_data != 'N/A' else 'N/A'} | |
totalDebtToEquity_q_dict = {'totalDebtToEquity_q' : quarterly_series_data['totalDebtToEquity'][0]['v'] if quarterly_series_data != 'N/A' else 'N/A'} | |
# merge all dictionary keys per ticker | |
combined_info = basic_info.copy() # Make a copy of the basic info | |
combined_info = combined_info | metric_data | roe_dict | totalDebtToTotalCapital_y_dict | totalDebtToEquity_q_dict |totalDebtToEquity_y_dict | eps_dict | totalDebtToTotalCapital_q_dict | |
hash_map[ticker] = combined_info | |
# beta calculations | |
df_b = calc_beta(ticker) | |
beta_dfs.append(df_b) | |
# equity gains | |
_, div, close_price = get_equity_gains(ticker=ticker, period=1810) | |
gains_data[ticker] = [div, close_price] | |
# Now, create a DataFrame from the hash_map | |
df_1 = pd.DataFrame.from_dict(hash_map, orient='index')[['finnhubIndustry','eps','roe','dividendGrowthRate5Y','epsGrowth5Y','payoutRatioAnnual','payoutRatioTTM','roeTTM','totalDebtToEquity_y','totalDebtToEquity_q', 'totalDebtToTotalCapital_y','totalDebtToTotalCapital_q']] | |
# Create beta df | |
beta_df = pd.concat(beta_dfs) | |
df_2 = pd.DataFrame.from_dict(gains_data, orient='index', columns=['Recent Dividend','Price']) | |
df_apis = df_1.join(beta_df) | |
df_final = df_apis.join(df_2) | |
# calculate additional columns | |
df_final['5Y_SP500_growth'], _, _ = get_equity_gains(ticker= '^GSPC', period=1810) | |
df_final['90_day_tbill'] = 4.06 | |
df_final['P/E Ratio'] = df_final['Price'] / df_final['eps'] | |
df_final['dividendGrowthRate5Y'] = df_final['dividendGrowthRate5Y']/100 | |
df_final['CAPM'] = df_final['90_day_tbill']/100 + df_final['Beta']*(df_final['5Y_SP500_growth'] - df_final['90_day_tbill']/100) | |
df_final['DDM'] = (df_final['Recent Dividend'] * (1+df_final['dividendGrowthRate5Y'])) / (df_final['CAPM'] - df_final['dividendGrowthRate5Y']) | |
df_final = df_final[['finnhubIndustry','Price','eps','roe','P/E Ratio','epsGrowth5Y','payoutRatioAnnual','payoutRatioTTM','roeTTM','totalDebtToEquity_y','totalDebtToEquity_q', 'totalDebtToTotalCapital_y','totalDebtToTotalCapital_q','Beta','Recent Dividend','90_day_tbill','5Y_SP500_growth','dividendGrowthRate5Y','CAPM','DDM']] | |
df_final.rename({'finnhubIndustry':'Industry', 'eps':'EPS', 'roe':'ROE'}, inplace=True, axis=1) | |
st.write(df_final) | |
if submit_button and symbols and strategy_selection == 'Growth': | |
st.write("Not built yet...") |