import requests import json from requests.api import delete, options import streamlit as st import time import tweepy import requests from io import BytesIO import base64 import matplotlib.pyplot as plt import numpy as np from plotly.subplots import make_subplots from config import * from dateutil.relativedelta import relativedelta from patterns import patterns # import talibsddsfs from datetime import datetime, timedelta, tzinfo from alpaca_trade_api.rest import REST from streamlit_tags import st_tags_sidebar # from streamlit_autorefresh import st_autorefresh # import plotly.express as px from coinbaskets import * import plotly.graph_objects as go from mapping import * import pandas as pd import threading from bs4 import BeautifulSoup from ETFs import * from dateutil import tz import os # try: # from streamlit.ReportThread import add_report_ctx # except Exception: # # Streamlit >= 0.65.0 # from streamlit.report_thread import add_report_ctx # # from streamlit.scriptrunner import add_script_run_ctx from streamlit.scriptrunner import add_script_run_ctx as add_report_ctx def get_stocktwits_data(req,code,label): r = requests.get(req) trending_syms = pd.DataFrame(r.json()["stocks"]).T trending_syms.index.name = "stock_id" trending_syms.index = trending_syms.index.astype("int") trending_score = pd.DataFrame(r.json()["table"][code]) trending_score.set_index("stock_id",inplace = True) most_trending_syms = pd.merge(trending_syms,trending_score,on= "stock_id") most_trending_syms.sort_values("val",ascending = False, inplace = True) most_trending_syms.set_index("symbol",inplace = True) most_trending_syms.columns = ["Name","Price","%Change",label] return most_trending_syms def get_cnbc_data(symbol): ticker = symbol.replace(" ","") if ticker == "NASDAQ": ticker = "NDX" elif ticker == "NIFTY50": ticker = ".NSEI" # Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping # df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={ticker}").json()["barData"]["priceBars"]) df_1D = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1D.json?symbol={ticker}").json()["barData"]["priceBars"]) # df["datetime"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms') # df["close"] = df["close"].astype(float) df_1D["close"] = df_1D["close"].astype(float) # df.set_index("datetime",inplace = True) # dma200 = df["close"].rolling(200).mean() close = (df_1D["close"].iloc[-1]) return close def vix_gradient(vix): """ Mapping is done as follows rsi<=20 --> -100, rsi>=80, 100, and then linear variation """ if vix<20: return 100 elif vix<30: return (-20*vix+500) else: return -100 def roro_comp_get(series,i,state, inverse = False): current = series.iloc[-i] current_idx = series.index[-i] w_1_ago = current_idx - relativedelta(days=7) w_2_ago = current_idx - relativedelta(days=14) m_1_ago = current_idx - relativedelta(months=1) if state == 0: w_1_ret = (current - series.loc[w_1_ago:].iloc[0])*100/series.loc[w_1_ago:].iloc[0] w_2_ret = (current - series.loc[w_2_ago:].iloc[0])*100/series.loc[w_2_ago:].iloc[0] m_1_ret = (current - series.loc[m_1_ago:].iloc[0])*100/series.loc[m_1_ago:].iloc[0] else: w_1_ret = (current - series.iloc[-1-i])*100/series.iloc[-1-i] w_2_ret = (current - series.iloc[-2-i])*100/series.iloc[-2-i] m_1_ret = (current - series.iloc[-4-i])*100/series.iloc[-4-i] sign_of = 1 if inverse == True: sign_of = -1 val = 100*(3*(2*(sign_of*w_1_ret>0) - 1) + 2*(2*(sign_of*w_2_ret>0) - 1) + 2*(sign_of*m_1_ret>0) - 1)/6 return val def get_roro(tf = "1Y"): df_spx = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=.SPX").json()["barData"]["priceBars"]) df_spx["datetime"] = pd.to_datetime(df_spx['tradeTimeinMills'],unit='ms').dt.date df_spx.set_index("datetime",inplace = True) df_spx["close"] = df_spx["close"].astype(float) df_vix = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=.VIX").json()["barData"]["priceBars"]) df_vix["close"] = df_vix["close"].astype(float) df_AUDJPY = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=AUDJPY=").json()["barData"]["priceBars"]) df_AUDJPY["datetime"] = pd.to_datetime(df_AUDJPY['tradeTimeinMills'],unit='ms').dt.date df_AUDJPY.set_index("datetime",inplace = True) df_AUDJPY["close"] = df_AUDJPY["close"].astype(float) df_gold = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=@GC.1").json()["barData"]["priceBars"]) df_gold["datetime"] = pd.to_datetime(df_gold['tradeTimeinMills'],unit='ms').dt.date df_gold.set_index("datetime",inplace = True) df_gold["close"] = df_gold["close"].astype(float) df_silver = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=@SI.1").json()["barData"]["priceBars"]) df_silver["datetime"] = pd.to_datetime(df_silver['tradeTimeinMills'],unit='ms').dt.date df_silver.set_index("datetime",inplace = True) df_silver["close"] = df_silver["close"].astype(float) gold_silver_ratio = df_gold["close"]/df_silver["close"] df_bnd = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=BND").json()["barData"]["priceBars"]) df_bnd["datetime"] = pd.to_datetime(df_bnd['tradeTimeinMills'],unit='ms').dt.date df_bnd.set_index("datetime",inplace = True) df_bnd["close"] = df_bnd["close"].astype(float) df_sphb = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SPHB").json()["barData"]["priceBars"]) df_sphb["datetime"] = pd.to_datetime(df_sphb['tradeTimeinMills'],unit='ms').dt.date df_sphb.set_index("datetime",inplace = True) df_sphb["close"] = df_sphb["close"].astype(float) df_splv = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SPLV").json()["barData"]["priceBars"]) df_splv["datetime"] = pd.to_datetime(df_splv['tradeTimeinMills'],unit='ms').dt.date df_splv.set_index("datetime",inplace = True) df_splv["close"] = df_splv["close"].astype(float) sphb_splv_ratio = df_sphb["close"]/df_splv["close"] df_HYG = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=HYG").json()["barData"]["priceBars"]) df_HYG["datetime"] = pd.to_datetime(df_HYG['tradeTimeinMills'],unit='ms').dt.date df_HYG.set_index("datetime",inplace = True) df_HYG["close"] = df_HYG["close"].astype(float) df_fnda = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=FNDA").json()["barData"]["priceBars"]) df_fnda["datetime"] = pd.to_datetime(df_fnda['tradeTimeinMills'],unit='ms').dt.date df_fnda.set_index("datetime",inplace = True) df_fnda["close"] = df_fnda["close"].astype(float) df_schx = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SCHX").json()["barData"]["priceBars"]) df_schx["datetime"] = pd.to_datetime(df_schx['tradeTimeinMills'],unit='ms').dt.date df_schx.set_index("datetime",inplace = True) df_schx["close"] = df_schx["close"].astype(float) fnda_schx_ratio = df_fnda["close"]/df_schx["close"] df_btc_usd = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=BTC.CB=").json()["barData"]["priceBars"]) df_btc_usd["datetime"] = pd.to_datetime(df_btc_usd['tradeTimeinMills'],unit='ms').dt.date df_btc_usd.set_index("datetime",inplace = True) df_btc_usd["close"] = df_btc_usd["close"].astype(float) periods = 300 roro = [] if tf == "5Y": state = 1 else: state = 0 for i in range(periods,0,-1): temp = dict( date = (pd.to_datetime(df_spx.index).date)[-i], spx = roro_comp_get(df_spx["close"],i,state), audjpy = roro_comp_get(df_AUDJPY["close"],i,state), gold_silver = roro_comp_get(gold_silver_ratio,i,state,inverse = True), bnd = roro_comp_get(df_bnd["close"],i,state,inverse = True), sphb_splv = roro_comp_get(sphb_splv_ratio,i,state), hyg = roro_comp_get(df_HYG["close"],i,state), fnda_schx = roro_comp_get(fnda_schx_ratio,i,state), vix = vix_gradient(df_vix["close"].iloc[-i]), btc_usd = roro_comp_get(df_btc_usd["close"],i,state) ) roro.append(temp) return roro # Setting the page layout as wide st.set_page_config(layout="wide") def get_data_yields(symbol,lookback_period): global response_yields df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{lookback_period}.json?symbol={symbol}").json()["barData"]["priceBars"]) df["datetime"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms') df.set_index("datetime",inplace = True) response_yields[symbol] = df["close"].astype(float) def get_recommendation(symbol,rsi_val,drop_frm_ath,dist_from_5_yr_low): global momentum_recommendations,cheap_recommendations df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={symbol}").json()["barData"]["priceBars"]) df_all = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/ALL.json?symbol={symbol}").json()["barData"]["priceBars"]) df_all["high"] = df_all["high"].astype(float) df_all["low"] = df_all["low"].astype(float) df["tradeTimeinMills"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms') df_all["tradeTimeinMills"] = pd.to_datetime(df_all['tradeTimeinMills'],unit='ms') df["close"] = df["close"].astype(float) df["open"] = df["open"].astype(float) df.set_index("tradeTimeinMills",inplace = True) df_all.set_index("tradeTimeinMills",inplace = True) current_close = df["close"].iloc[-1] df["50DMA"] = df["close"].rolling(50).mean() df["100DMA"] = df["close"].rolling(100).mean() df["Vol_mon_avg"] = 5*df["volume"].rolling(252).mean() df["RSI"] = talib.RSI(df["close"]) cond1 = current_close>df["50DMA"].iloc[-1] cond2 = current_close>df["100DMA"].iloc[-1] cond3 = df["volume"].rolling(5).sum().iloc[-1]>1.5*df["Vol_mon_avg"].iloc[-1] mom_score = int(cond1)+int(cond2)+int(cond3) ath = df_all["high"].max() distance_from_ath = round((ath-current_close)*100/ath,2) yr_2_ago_dt = datetime.now() - relativedelta(years=2) yr_2_low = df_all["low"].loc[yr_2_ago_dt:].min() distance_frm_2yr_low = round((current_close - yr_2_low)*100/current_close,2) rsi = round(df["RSI"].iloc[-1],2) cond_1 = rsi=drop_frm_ath cond_3 = distance_frm_2yr_low<=dist_from_5_yr_low cheap_score = int(cond_1)+int(cond_2)+int(cond_3) if (cond1 or cond2) or cond3: momentum_recommendations[symbol] = {"LTP":current_close,"50DMA":df["50DMA"].iloc[-1],"100DMA":df["100DMA"].iloc[-1],"Vol>1.5avg":cond3,"score":mom_score,"sparkline": sparkline(data=df["close"])} if cond_1 or cond_2 or cond_3: cheap_recommendations[symbol] = {"LTP":current_close,"RSI":rsi,f'drop frm ATH':distance_from_ath,f"% away 2 yr low":distance_frm_2yr_low,"score":cheap_score,"sparkline": sparkline(data=df["close"])} def sparkline(data, figsize=(4,0.25),**kwags): data = list(data) fig,ax = plt.subplots(1,1,figsize=figsize,**kwags) ax.plot(data) for k,v in ax.spines.items(): v.set_visible(False) ax.set_xticks([]) ax.set_yticks([]) plt.plot(len(data)-1, data[len(data)-1], 'r.') ax.fill_between(range(len(data)), data, len(data)*[min(data)], alpha=0.1) img = BytesIO() plt.savefig(img, transparent=True, bbox_inches='tight') img.seek(0) # plt.show() plt.close() # return base64.b64encode(img.read()).decode("utf-8") return ''.format(base64.b64encode(img.read())) def highlight_rec_momentum(s): arr = [] arr.append('background-color: white') if s["50DMA"]1.5avg"]: arr.append('background-color: #90EE90') else: arr.append('background-color: #FF7F7F') arr.append('background-color: white') arr.append('background-color: white') return arr def font_color(s): return ["color: black"]*len(s) def highlight_rec_cheap(s,rsi_val,drop_frm_ath,dist_from_5_yr_low): arr = [] arr.append('background-color: white') if s["RSI"]drop_frm_ath: arr.append('background-color: #90EE90') else: arr.append('background-color: #FF7F7F') if s[f"% away 2 yr low"]data["lowerKC"], data["upperband"]0: # If there's something in watchlist then for cryptos fetch the LTP from FTX api # Getting LTP is currently for Crypto only due to free data unavailability for stocks/ETFs df_watchlist.set_index("Symbol",inplace = True) df_watchlist["LTP"] = 0 def get_data_symbol(symbol_name_for_quote): global df_watchlist try: if symbol_name_for_quote in ["HYG","LQD","SPX","NASDAQ","NIFTY50","VIX","US 2Y","US 5Y", "US 10Y","US 30Y"]: data_symbol = get_cnbc_data(symbol_name_for_quote) else: data_symbol = json.loads(requests.get(f"https://ftx.com/api/markets/{symbol_name_for_quote}").text)["result"]["price"] df_watchlist.loc[symbol_name_for_quote,"LTP"] = data_symbol except: pass threads_list = [] for i in range(len(df_watchlist)): symbol_name_for_quote = df_watchlist.index[i] x = threading.Thread(target = get_data_symbol,args = (symbol_name_for_quote,)) x.start() add_report_ctx(x) threads_list.append(x) for thread in threads_list: thread.join() df_watchlist["pct_away"] = np.round(100*np.abs(df_watchlist["Trigger"] - df_watchlist["LTP"])/df_watchlist["LTP"]) # Show the watchlist st.dataframe(df_watchlist) elif option == "RORO Components": lkbck_perd = st.sidebar.selectbox("Lookback Period",["1Y","5Y"]) st.sidebar.write("1Y will fetch daily data, 5Y --> weekly") st.sidebar.write("Number of lookback periods is set as 300") roro_run_btn = st.sidebar.button("Run") if roro_run_btn: roro_comp_df = pd.DataFrame(get_roro(lkbck_perd)) roro_comp_df.set_index("date",inplace = True) roro_comp_df["roro"] = roro_comp_df.sum(axis = 1)/(len(roro_comp_df.columns)) fig = make_subplots(rows=len(roro_comp_df.columns), shared_xaxes=True,vertical_spacing=0.01,subplot_titles=(roro_comp_df.columns)) counter = 1 for key in roro_comp_df.columns: if key!= "roro": fig.add_scatter(x = roro_comp_df.index, y = roro_comp_df[key].values,mode = "lines",row = counter, col = 1, name = key) else: fig.add_scatter(y = roro_comp_df["roro"].values,x = roro_comp_df.index,mode = "lines",fill='tozeroy',row = counter,col =1,name = key) counter+=1 fig['layout'].update(height=2500, width=600, title='Subplots of components') st.plotly_chart(fig,use_container_width = True) elif option == "Recommendations": select_asset = st.sidebar.selectbox("Asset Class",["ETF"]) rsi_val = st.sidebar.number_input("RSI Thresh",value = 50) drop_frm_ath = st.sidebar.number_input("Drop From ATH(%) Thresh",value = 50) dist_from_5_yr_low = st.sidebar.number_input(f"%away from 2 yr Low Thresh",value = 20) rec_run_btn = st.sidebar.button("Run") st.sidebar.write("**Momentum Rising Screening Conditions**") st.sidebar.write("LTP>50DMA") st.sidebar.write("LTP>100DMA") st.sidebar.write("5D Vol>1.5*(5D Vol. yearly_avg") st.sidebar.write("**Cheap Stocks Screening Conditions**") st.sidebar.write("RSI < RSI Thresh") st.sidebar.write("Drop from ATH(%) > Drop from ATH(%) Thresh") st.sidebar.write(f"% away from 2 yr Low < %away from 2 yr Low Thresh") if rec_run_btn: momentum_recommendations = {} cheap_recommendations = {} rec_threads = [] if select_asset == "ETF": options_for_assets = all_etfs for asset in options_for_assets: x = threading.Thread(target=get_recommendation,args = (asset,rsi_val,drop_frm_ath,dist_from_5_yr_low,)) x.start() rec_threads.append(x) # get_recommendation(asset) for rec in rec_threads: rec.join() # st.write(momentum_recommendations) momentum_recommendations = pd.DataFrame(momentum_recommendations).T momentum_recommendations.sort_values("score",ascending=False,inplace = True) cheap_recommendations = pd.DataFrame(cheap_recommendations).T cheap_recommendations.sort_values("score",ascending=False,inplace = True) st.header("Momentum Rising") st.dataframe(momentum_recommendations.style.apply(highlight_rec_momentum,axis = 1).apply(font_color)) st.header("Cheap Stocks") st.dataframe(cheap_recommendations.style.apply(highlight_rec_cheap,args = (rsi_val,drop_frm_ath,dist_from_5_yr_low),axis = 1).apply(font_color)) elif option == "MACRO": select_timeframe = st.sidebar.selectbox("Which Timeframe (finviz only)?",["Daily","Weekly","Monthly"]) # select_lookback_period = st.sidebar.selectbox("LookbackPeriod for yields(yrs)",[1,2,3,4,5]) select_lookback_period = st.sidebar.selectbox("LookbackPeriod for yields",["1D","1M","3M","6M","1Y","5Y"]) timeframe_map = {"Daily":"d1","Weekly":"w1","Monthly":"mo"} tf = timeframe_map[select_timeframe] run_btn = st.sidebar.button("Run") if run_btn: col1, col2, col3 = st.columns([1,1,1]) with col1: st.image(f"https://finviz.com/fut_image.ashx?es_{tf}_s.png") with col2: st.image(f"https://finviz.com/fut_image.ashx?vx_{tf}_s.png") with col3: st.image(f"https://finviz.com/fut_image.ashx?nq_{tf}_s.png") response_yields = {} thread_yields = [] for symbol in ["US1Y","US2Y","US5Y","US10Y","US30Y"]: thread = threading.Thread(target = get_data_yields, args = (symbol,select_lookback_period,)) thread.start() thread_yields.append(thread) for x in thread_yields: x.join() df_yields = pd.concat(response_yields,axis = 1) df_yields["2y/10y"] = df_yields["US10Y"]-df_yields["US2Y"] df_yields["10y/30y"] = df_yields["US30Y"]-df_yields["US10Y"] df_yields["2y/5y"] = df_yields["US5Y"]-df_yields["US2Y"] df_yields["1y/2y"] = df_yields["US2Y"]-df_yields["US1Y"] st.line_chart(df_yields[["US1Y","US2Y","US5Y","US10Y","US30Y"]]) col1, col2 = st.columns([1,1]) with col1: st.line_chart(df_yields["1y/2y"]) st.line_chart(df_yields["2y/5y"]) with col2: st.line_chart(df_yields["2y/10y"]) st.line_chart(df_yields["10y/30y"]) # today = datetime.now().strftime("%Y-%m-%d") # past = (datetime.now() - timedelta(days=365*select_lookback_period)).strftime("%Y-%m-%d") # # https://fred.stlouisfed.org/graph/?id=DGS10,DGS5,DGS30,DGS3MO,DGS1,DGS2, # url = f"""https://fred.stlouisfed.org/graph/fredgraph.png?dwnld=0&hires=1&type=image/png& # bgcolor=%23e1e9f0&chart_type=line&drp=0&fo=open%20sans&graph_bgcolor=%23ffffff&height=450& # mode=fred&recession_bars=on&txtcolor=%23444444&ts=12&tts=12&width=1168&nt=0&thu=0&trc=0& # show_legend=yes&show_axis_titles=yes&show_tooltip=yes&id=DGS10,DGS5,DGS30,DGS3MO,DGS1,DGS2& # scale=left,left,left,left,left,left&cosd={past},{past},{past},{past},{past},{past}& # coed={today},{today},{today},{today},{today},{today}& # line_color=%234572a7,%23aa4643,%2389a54e,%2380699b,%233d96ae,%23db843d& # link_values=false,false,false,false,false,false&line_style=solid,solid,solid,solid,solid,solid& # mark_type=none,none,none,none,none,none&mw=3,3,3,3,3,3&lw=2,2,2,2,2,2& # ost=-99999,-99999,-99999,-99999,-99999,-99999&oet=99999,99999,99999,99999,99999,99999& # mma=0,0,0,0,0,0&fml=a,a,a,a,a,a&fq=Daily,Daily,Daily,Daily,Daily,Daily& # fam=avg,avg,avg,avg,avg,avg&fgst=lin,lin,lin,lin,lin,lin& # fgsnd=2020-02-01,2020-02-01,2020-02-01,2020-02-01,2020-02-01,2020-02-01&line_index=1,2,3,4,5,6& # transformation=lin,lin,lin,lin,lin,lin& # vintage_date={today},{today},{today},{today},{today},{today}& # revision_date={today},{today},{today},{today},{today},{today}& # nd=1962-01-02,1962-01-02,1977-02-15,1981-09-01,1962-01-02,1976-06-01 # """ # url = url.replace("\n","") # st.image(url,width = 800) elif option == "twitter": # If twitter is selected today = datetime.today() # Get the local timezone, this is important because then it works on a different timezone to_zone = tz.tzlocal() # Multibox for selecting multiple users who = st.sidebar.multiselect("Choose person",tuple(TWITTER_USERNAMES)) twitter_run_btn = st.sidebar.button("Run") if twitter_run_btn: # if twitter run button is clicked then all those people selected are called if "SELECT ALL" in who: users_list = TWITTER_USERNAMES[1:] else: users_list = who for username in users_list: # For a given username fetch the tweets, its username, image user = api.get_user(screen_name = username) tweets = api.user_timeline(screen_name = username, count = 100, tweet_mode = "extended") st.subheader(username) st.image(user.profile_image_url) for tweet in tweets: # In all his tweets, bring those to local timezone tweet_date = ((tweet.created_at).astimezone(to_zone)).replace(tzinfo = None) #Now, we don't want tweets older than 3 days delta = (today - tweet_date).days if delta>3: continue # For the following user names certain modification is done to get the tweets if username in ["@chartmojo","@MacroCharts"]: if tweet.in_reply_to_screen_name== None: st.subheader(tweet._json["created_at"]) st.write(tweet.full_text) try: for j in tweet.extended_entities["media"]: st.image(j["media_url_https"], width=600) except: pass else: if tweet.in_reply_to_screen_name== None and len(tweet.entities["symbols"])>0: symbols = [] for i in range(len(tweet.entities["symbols"])): symbols.append(tweet.entities["symbols"][i]["text"]) st.subheader(" ".join(symbols)) st.subheader(tweet._json["created_at"]) st.subheader(tweet.full_text) try: for j in tweet.extended_entities["media"]: st.image(j["media_url_https"], width = 600) except: pass for symbol in symbols: st.image(f"https://finviz.com/chart.ashx?t={symbol}&ta=1", width=600) # elif option == "US Sectors": # st.sidebar.write("Source - TradingView") # select_sector = st.sidebar.selectbox("Select Sector", options = us_sectors) # select_btn = st.sidebar.button("Run") # url = "https://in.tradingview.com/markets/stocks-usa/sectorandindustry-sector/" # r = requests.get(url) # soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib # req = soup.find_all('tr',attrs = {'class':'tv-data-table__row tv-data-table__stroke tv-screener-table__result-row'}) # sectors = [] # pct_change = [] # for i in req: # arr = [] # for sector in i.find_all("td"): # arr.append(sector.text) # arr[0] = arr[0].split("\n")[3].split("\t")[0] # sectors.append(arr[0]) # pct_change.append(float(arr[3][:-1])) # fig = go.Figure([go.Bar(x=sectors, y=pct_change, # marker = dict(color = ['rgba(63, 195, 128, 1)' if value>0 else 'rgba(219, 10, 91, 1)' for value in pct_change], # line = dict(color='rgb(0,0,0)',width=1.5)))]) # st.plotly_chart(fig,use_container_width=True) # if select_btn: # val = "-".join(select_sector.lower().split(" ")) # url = f"https://in.tradingview.com/markets/stocks-usa/sectorandindustry-sector/{val}/" # r = requests.get(url) # soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib # req = soup.find_all('tr',attrs = {'class':'tv-data-table__row tv-data-table__stroke tv-screener-table__result-row'}) # ticker = [] # pct_change_ticker = [] # company = [] # for i in req: # arr = [] # for sector in i.find_all("td"): # arr.append(sector.text) # arr[0] = arr[0].split("\n")[4] # # result.append(dict(ticker = arr[0],pct_change = float(arr[2][:-1]),vol = arr[5],mkt_cap = arr[6])) # # ticker.append(arr[0]) # company.append(us_stocks_mapping[arr[0]]) # pct_change_ticker.append(float(arr[2][:-1])) # layout = go.Layout( # xaxis = go.XAxis( # title = "Stocks", # showticklabels = False # ) # ) # fig = go.Figure([go.Bar(x=company, y=pct_change_ticker, # marker = dict(color = ['rgba(63, 195, 128, 1)' if value>0 else 'rgba(219, 10, 91, 1)' for value in pct_change_ticker], # line = dict(color='rgb(0,0,0)',width=1.5)))],layout = layout) # st.write(len(company)) # st.plotly_chart(fig,use_container_width=True) # st_autorefresh(interval=120000, limit=10000, key="US sectors refresh") elif option == "Commodities": select_timeframe = st.sidebar.selectbox("Which Timeframe?",["Daily","Weekly","Monthly"]) timeframe_map = {"Daily":"d1","Weekly":"w1","Monthly":"mo"} tf = timeframe_map[select_timeframe] col0,col1,col2 = st.columns([1,1,1]) count = 0 for key in commodity_mapping: # https://finviz.com/futures_charts.ashx?t=YM&p=d1 # Get the mapping for commodities, which is there in config.py keyword_comm = commodity_mapping[key] num = count%3 if num ==0: with col0: st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png") elif num == 1: with col1: st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png") else: with col2: st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png") count = count+1 elif option == "CryptoIndex": # If cryptoIndex tab is selected # Select which crypto index, then timeframe and accordingly fetch the data type_index = st.sidebar.selectbox("Which?",["Major","Minor","Shit"]) select_index_timeframe = st.sidebar.selectbox("Timeframe",["15s","1m","5m","15m","1h","4h","1d"]) if select_index_timeframe[-1] == "s": timeframe = int(select_index_timeframe[:-1]) elif select_index_timeframe[-1] == "m": timeframe = int(select_index_timeframe[:-1]) * 60 elif select_index_timeframe[-1] == "h": timeframe = int(select_index_timeframe[:-1])*60*60 elif select_index_timeframe[-1] == "d": timeframe = int(select_index_timeframe[:-1])* 60*60*24 if type_index == "Major": # Our crypto index is of 0.5BTC + 0.5 ETH st.write("0.5BTC + 0.5ETH") # Fetch data and create crypto index in same proportion data_btc = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/BTC/USDT/candles?resolution={timeframe}").text)["result"]) data_eth = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/ETH/USDT/candles?resolution={timeframe}").text)["result"]) data_btc.set_index("startTime",inplace = True) data_eth.set_index("startTime",inplace = True) # Note crypto index are normalized data = (data_btc["close"]*0.5/data_btc["close"][0] + data_eth["close"]*0.5/data_eth["close"][0])*100 fig = go.Figure() fig.add_trace(go.Scatter(x=data.index, y=data.values, mode='lines', name=type_index)) fig.update_xaxes( rangeslider_visible=True, nticks = 20, spikemode = "toaxis", rangeselector=dict( buttons=list([ dict(count=1, label="1mon", step="month", stepmode="backward"), dict(count=6, label="6mon", step="month", stepmode="backward"), dict(count=1, label="YTD", step="year", stepmode="todate"), dict(count=1, label="1y", step="year", stepmode="backward"), dict(step="all") ]) ) ) fig.update_layout( xaxis_tickformat = '%Y-%m-%d', height = 600, width = 900, hovermode = "x" ) st.plotly_chart(fig) elif option == "Report": df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"]) df = df[df["quoteCurrency"].isin(["USD","USDT"])] symbols = df.name.values to_analyze_symbol = st.sidebar.multiselect("Which symbol",symbols) analysis_date = st.sidebar.selectbox("Which date for Analysis",["Current","Yesterday"]) if analysis_date == "Yesterday": locn = -2 elif analysis_date == "Current": locn = -1 fetch_data_btn = st.sidebar.button("Fetch Data") if fetch_data_btn: threads = [] for symbol in symbols: t = threading.Thread(target = get_crypto_data_daily, args = (symbol,)) t.start() add_report_ctx(t) threads.append(t) for x in threads: x.join() res = {} for req_symbol in to_analyze_symbol: req_symbol_file = req_symbol.replace("/","_") df_req = pd.read_csv(f"crypto_data/{req_symbol_file}.csv",index_col = 0, parse_dates = True) ans = {} for period in [20,50,100,200]: df_req[f"MA{period}"] = talib.SMA(df_req["close"],period) ans[f"% from MA{period}"] = round((df_req["close"].iloc[locn] - df_req[f"MA{period}"].iloc[locn])*100/df_req[f"MA{period}"].iloc[locn],2) df_req["RSI14"] = talib.RSI(df_req["close"]) ans["RSI"] = round(df_req["RSI14"].iloc[locn],2) ans["LTP"] = df_req["close"].iloc[-1] res[req_symbol] = ans result = pd.DataFrame(res).T st.dataframe(result) elif option == "Breakout": # If breakout tab is selected # Get the crypto symbols #Create buttons and boxes for selecting timeframe, BB number, KC multiplier df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"]) df = df[df["quoteCurrency"].isin(["USD","USDT"])] symbols = df.name.values select_consol_tf = st.sidebar.selectbox("Timeframe",["15s","1m","5m","15m","1h","4h","1d"]) if select_consol_tf[-1] == "s": timeframe = int(select_consol_tf[:-1]) elif select_consol_tf[-1] == "m": timeframe = int(select_consol_tf[:-1]) * 60 elif select_consol_tf[-1] == "h": timeframe = int(select_consol_tf[:-1])*60*60 elif select_consol_tf[-1] == "d": timeframe = int(select_consol_tf[:-1])* 60*60*24 select_BB_mul = st.sidebar.text_input("Bollinger Band multiplier",value = "2") select_KC_mul = st.sidebar.text_input("KC multiplier", value = "1.5") select_num_days = st.sidebar.text_input("Consolidating before how many periods?",3) num_days = int(select_num_days) bb_mul = float(select_BB_mul) kc_mul = float(select_KC_mul) consol_run_btn = st.sidebar.button("Run") if consol_run_btn: # If user clicks on run button # Again running in threads. threads = [] for symbol in symbols: t = threading.Thread(target = in_squeeze, args = (symbol,bb_mul, kc_mul, num_days, True,60*60*24)) add_report_ctx(t) t.start() threads.append(t) for x in threads: x.join() st.sidebar.write("Task Complete") elif option == "ETFs": # If ETFs are selected # Button to select ETF selectETF = st.sidebar.selectbox("Select ETF class",etf.keys()) today = datetime.now() - timedelta(days =80) st.subheader(selectETF) # Note Country ETFs are dealt differently as they have country names as well if selectETF!= "Country": # If ETF is not Country then its very easy just from ETF variable we can fetch it etf_names = etf[selectETF].keys() else: # Select Markets, Country selectMarket = st.sidebar.selectbox("Which Market?",etf[selectETF].keys()) country_list = list(etf[selectETF][selectMarket].keys()) etf_list = list(etf[selectETF][selectMarket].values()) etf_names = [] country_names = [] # In a for loop fetch all the ETFs for selected entries for i in range(len(etf_list)): if type(etf_list[i])==str: etf_names.append(etf_list[i]) country_names.append(country_list[i]) else: for sub_etf_name in etf_list[i]: etf_names.append(sub_etf_name) country_names.append(country_list[i]) select_timeframe = st.sidebar.selectbox("Which Timeframe?",["Daily","Weekly","Monthly"]) timeframe_map = {"Daily":"d","Weekly":"w","Monthly":"m"} etf_run_btn = st.sidebar.button("Run") if etf_run_btn: tf = timeframe_map[select_timeframe] # If After giving all the entries, run button is clicked get the charts for all the ETFs count = 0 res_etf_ret = [] thread_det = [] vol_etf_info = {} expense_ratios = {} st.info("Loading..... Please Have Patience") for n in etf_names: thread = threading.Thread(target = get_etf_rets, args = (n,)) thread.start() thread_det.append(thread) for x in thread_det: x.join() st.success("Finished Loading") etf_rets_df = pd.DataFrame(res_etf_ret) etf_rets_df.set_index("symbol",inplace=True) col1,col2,col3,col4,col5 = st.columns([1,1,1,1,1]) with col1: # st.write("") st.markdown("
Daily Returns
", unsafe_allow_html=True) st.dataframe(etf_rets_df["day_ret"].sort_values(ascending=False)) with col2: st.markdown("
1 Week Returns
", unsafe_allow_html=True) st.dataframe(etf_rets_df["w1_ret"].sort_values(ascending=False)) with col3: st.markdown("
2 Week Returns
", unsafe_allow_html=True) st.dataframe(etf_rets_df["w2_ret"].sort_values(ascending=False)) with col4: st.markdown("
1 Month Returns
", unsafe_allow_html=True) st.dataframe(etf_rets_df["m1_ret"].sort_values(ascending=False)) with col5: st.markdown("
1 Year Returns
", unsafe_allow_html=True) st.dataframe(etf_rets_df["year_ret"].sort_values(ascending=False)) st.dataframe(etf_rets_df) cols1,cols2 = st.columns([1,1]) if selectETF!= "Country": for etf_name in etf_names: num = count%2 if num == 0: with cols1: try: st.write(f"{etf[selectETF][etf_name]}, IV = {vol_etf_info[etf_name]}, ER = {expense_ratios[etf_name]}") except: pass if tf == "d": st.image(f"https://finviz.com/chart.ashx?t={etf_name}&ta=1&p={tf}") else: st.image(f"https://finviz.com/chart.ashx?t={etf_name}&p={tf}") else: with cols2: try: st.write(f"{etf[selectETF][etf_name]}, IV = {vol_etf_info[etf_name]}, ER = {expense_ratios[etf_name]}") except: pass if tf == "d": st.image(f"https://finviz.com/chart.ashx?t={etf_name}&ta=1&p={tf}") else: st.image(f"https://finviz.com/chart.ashx?t={etf_name}&p={tf}") count = count + 1 else: for i in range(len(etf_names)): try: st.write(f"{country_names[i]}, IV = {vol_etf_info[etf_names[i]]}, ER = {expense_ratios[etf_names[i]]}") except: pass if tf == "d": st.image(f"https://finviz.com/chart.ashx?t={etf_names[i]}&ta=1&p={tf}") else: st.image(f"https://finviz.com/chart.ashx?t={etf_names[i]}&p={tf}") elif option == "coinBaskets": # If coinBaskets is selected # Note, Mudrex was our reference here baskets = st.sidebar.multiselect(label = "Baskets",options=names, default =names[0]) run_basket = st.sidebar.button("Run") select_crypto_timeframe = st.sidebar.selectbox("Crypto Timeframe", options = ["1d","1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","3d","1w","1M"]) check_symbol = st.sidebar.text_input("Symbol check") interval = select_crypto_timeframe # Once all the inputs are given, and if any of the basket is chosen if check_symbol != "": for bkt in names: # For each basket selected, get its components, fetch its price from Binance api #Then plot all components in a single chart #Here, you are giving in the symbol name and program is finding whether that symbol is there # in any of the basket or not if check_symbol in eval(bkt)["components"]: fig_check = go.Figure() st.write(bkt.upper()) cols = st.columns(len(eval(bkt)["components"])) for i in eval(bkt)["components"]: ticker = f'{i.upper()}USDT' req_params = dict(symbol = ticker, interval = interval) url = "https://api.binance.com/api/v3/klines" data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text)) data = data.iloc[:,0:5] data.columns = ['datetime', 'open','high','low', 'close'] data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime] data["close"] = data["close"].astype(float) df = (data["close"].pct_change() + 1).cumprod() fig_check.add_trace(go.Scatter(x=df.index, y=df.values, mode='lines', name=i)) fig_check.update_xaxes( rangeslider_visible=True, nticks = 20, spikemode = "toaxis", rangeselector=dict( buttons=list([ dict(count=1, label="1mon", step="month", stepmode="backward"), dict(count=6, label="6mon", step="month", stepmode="backward"), dict(count=1, label="YTD", step="year", stepmode="todate"), dict(count=1, label="1y", step="year", stepmode="backward"), dict(step="all") ]) ) ) fig_check.update_layout( xaxis_tickformat = '%Y-%m-%d', height = 600, width = 900, hovermode = "x" ) fig_check.update_traces( hovertemplate="
".join([ "Price: %{y}" ])) st.plotly_chart(fig_check) if run_basket: for basket in baskets: # Here, you are choosing the baskets and program is plotting the baskets st.write(basket.upper()) st.table(eval(basket)) # Create traces fig = go.Figure() for i in eval(basket)["components"]: ticker = f'{i.upper()}USDT' interval = select_crypto_timeframe req_params = dict(symbol = ticker, interval = interval) url = "https://api.binance.com/api/v3/klines" data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text)) data = data.iloc[:,0:5] data.columns = ['datetime', 'open','high','low', 'close'] data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime] data["close"] = data["close"].astype(float) df = (data["close"].pct_change() + 1).cumprod() fig.add_trace(go.Scatter(x=df.index, y=df.values, mode='lines', name=i)) fig.update_xaxes( rangeslider_visible=True, nticks = 20, spikemode = "toaxis", rangeselector=dict( buttons=list([ dict(count=1, label="1mon", step="month", stepmode="backward"), dict(count=6, label="6mon", step="month", stepmode="backward"), dict(count=1, label="YTD", step="year", stepmode="todate"), dict(count=1, label="1y", step="year", stepmode="backward"), dict(step="all") ]) ) ) fig.update_layout( xaxis_tickformat = '%Y-%m-%d', height = 600, width = 900, hovermode = "x" ) fig.update_traces( hovertemplate="
".join([ "Price: %{y}" ])) st.plotly_chart(fig) elif option == "Chart": # Charting platform # Get user inputs symbols = st_tags_sidebar(label = "Choose the tickers", text = 'Press enter to add more', maxtags = 100) select_stock_timeframe = st.sidebar.selectbox("Stock Timeframe",options=["1Min", "5Min", "15Min", "day"]) select_crypto_timeframe = st.sidebar.selectbox("Crypto Timeframe", options = ["1d","1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","3d","1w","1M"]) select_periods = st.sidebar.text_input("Number of Days(Stock)",value = "30") today = datetime.now() - timedelta(int(select_periods)) if len(symbols)>0: # If symbols are selected for symbol in symbols: # Run over all symbol in for loop and if they are crypto, treat them differently #And if they are others, treat them differently if f'{symbol.upper()}' in crypto_symbols: # If crypto, get the data from Binance api ticker = f'{symbol.upper()}USDT' interval = select_crypto_timeframe req_params = dict(symbol = ticker, interval = interval) url = "https://api.binance.com/api/v3/klines" st.subheader(ticker) data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text)) data = data.iloc[:,0:5] data.columns = ['datetime', 'open','high','low', 'close'] data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime] data.drop("datetime",axis = 1, inplace = True) else: # If stocks then get it from trade_api # Remember!!!--> trade_api was initiated in the session_state in the starting of code data = st.session_state.trade_api.get_barset(symbol.upper(), select_stock_timeframe, start =today.strftime("%Y-%m-%d")).df data = data[symbol.upper()] st.subheader(symbol.upper()) fig = plot_candlestick(data) st.plotly_chart(fig, use_container_width=False) elif option == "stocktwits": # If stocktwits is selected # This is almost similar to Larry's video, so you can reference that as well # Display Trending stocks based on watchlist count st.header("Most Trending Symbols") most_trending_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/ts", code = "ts", label = "Trending Score") st.dataframe(most_trending_syms) st.header("Most messages in last 24 hrs") most_active_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/m_day", code = "m_day", label = "#messages") st.dataframe(most_active_syms) st.header("Top New Watchers added in last 24 hrs") most_active_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/wl_ct_day", code = "wl_ct_day", label = "Count") st.dataframe(most_active_syms) # For a given symbol, use request module to hit the stocktwits api and get the required info symbol = st.sidebar.text_input("Symbol", value = "AAPL", max_chars = 5) r = requests.get(f"https://api.stocktwits.com/api/2/streams/symbol/{symbol}.json") data = r.json() for message in data["messages"]: st.image(message["user"]["avatar_url"]) st.write(message['user']["username"]) st.write(message["created_at"]) st.write(message["body"]) st.sidebar.write("Update time for -->") st.sidebar.write("Top Watchlist Counts : 5mins") st.sidebar.write("Most Messages : 1hr") elif option == "Technical Scanner": # If technical scanner is selected # Then choose the pattern, timeframe, etc pattern = st.sidebar.selectbox("Which Pattern?", tuple(patterns.values())) keywords = st_tags_sidebar(label = "Choose the tickers", text = 'Press enter to add more', maxtags = 100) select_timeframe = st.sidebar.selectbox("Timeframe",options=["1Min", "5Min", "15Min", "day"]) run_btn = st.sidebar.button("Run") # Get the mapping for patterns from pattern.py file pattern_code = get_key(patterns, pattern) pattern_function = getattr(talib,pattern_code) if run_btn: # If clicked on run button # Then for each symbol, check the output keyword = [x.upper() for x in keywords] data = st.session_state.trade_api.get_barset(keyword, select_timeframe, limit = 100).df for symbol in keyword: try: # st.write(data) result = pattern_function(data[symbol]["open"],data[symbol]["high"],data[symbol]["low"],data[symbol]["close"]) last = result.tail(1).values[0] # For some of the indicators value <0 is Bearish and value>0 is Bullish # But for others there would be a different logic, you shall handle it differently if last>0: st.write(f"Bullish {symbol}") elif last<0: st.write(f"Bearish {symbol}") except: pass